diff --git a/legacyConvert.py b/legacyConvert.py index 583aad96d687cb5e7f034b468806f0a80fd460ec..0db729744fdb0beed4277c95184e502a1d3e0725 100644 --- a/legacyConvert.py +++ b/legacyConvert.py @@ -37,7 +37,7 @@ def legacyConversion(dset, recreatefullimage=False): print("This may take some time") # local imports as these functions are only needed for the rare occasion of legacy conversion - from .opticalscan import loadAndPasteImage + from .opticalscan import legacyLoadAndPasteImage # try to load png and check for detection contours recreatefullimage = recreatefullimage or not os.path.exists(dset.getLegacyImageName()) @@ -68,7 +68,7 @@ def legacyConversion(dset, recreatefullimage=False): for k in range(len(dset.zpositions)): names.append(os.path.join(dset.getScanPath(), f"image_{i}_{k}.bmp")) p = dset.grid[i] - imgdata, zvalimg = loadAndPasteImage(names, imgdata, zvalimg, width, + imgdata, zvalimg = legacyLoadAndPasteImage(names, imgdata, zvalimg, width, height, rotationvalue, p0, p1, p) dset.zvalimg = zvalimg cv2imwrite_fix(dset.getImageName(), cv2.cvtColor(imgdata, cv2.COLOR_RGB2BGR)) diff --git a/opticalbackground.py b/opticalbackground.py index 86342c5fdbee5a15785a08707b3b8905090658b2..6eee46acc601c2327217d48d7f291682bab317aa 100644 --- a/opticalbackground.py +++ b/opticalbackground.py @@ -93,7 +93,7 @@ class BackGroundManager(QtWidgets.QWidget): QtWidgets.QMessageBox.about(self, 'Warning', 'No Background Image is aquired') return else: - from .opticalscan import loadAndPasteImage + from .opticalscan import legacyLoadAndPasteImage self.dataset = self.parentOSwidget.dataset #acquire images in 3x3 area to preview quality of background subtraction @@ -118,7 +118,7 @@ class BackGroundManager(QtWidgets.QWidget): self.ramanctrl.moveToAbsolutePosition(curPoint[0], curPoint[1]) self.ramanctrl.saveImage(self.dataset.getTmpImageName()) - fullimg, zimg = loadAndPasteImage([self.dataset.getTmpImageName()], fullimg, zimg, width, height, angle, p0, p1, curPoint, background=self.avgImg) + fullimg, zimg = legacyLoadAndPasteImage([self.dataset.getTmpImageName()], fullimg, zimg, width, height, angle, p0, p1, curPoint, background=self.avgImg) self.updateGraphicsView(self.previewArea, fullimg, convertColors=True) diff --git a/opticalscan.py b/opticalscan.py index ae17a88fbdd9898abc9c669e7a4aeaf4ba3d8ab4..7d912aeb55a194fb00550854580429223c27477e 100644 --- a/opticalscan.py +++ b/opticalscan.py @@ -87,7 +87,42 @@ def subtractBackground(image, background): avg = np.mean(background) subtracted = np.clip(np.array(image - background + avg, dtype=np.uint8), 0, 255) return subtracted - + +def legacyLoadAndPasteImage(srcnames, fullimage, fullzval, width, height, + rotationvalue, p0, p1, p, background=None): + colimgs = [] + for name in srcnames: + curImg = cv2imread_fix(name) + if background is not None: + curImg = subtractBackground(curImg, background) + colimgs.append(curImg) + img, zval = imageStacking(colimgs) + + x, y = p + Nx, Ny = int((p1[0] - p0[0] + width) / width * img.shape[1]), int((p0[1] - p1[1] + height) / height * img.shape[ + 0]) + 10 # + 10 because of rotation and hopefully it will be small + c, s = np.cos(np.radians(rotationvalue)), np.sin(np.radians(rotationvalue)) + dx, dy = (x - p0[0]) / width * img.shape[1], (p0[1] - y) / height * img.shape[0] + + M = np.float32([[c, s, dx], [-s, c, dy]]) + if fullimage is not None: + cv2.warpAffine(img, M, (Nx, Ny), fullimage, borderMode=cv2.BORDER_TRANSPARENT) + cv2.warpAffine(zval, M, (Nx, Ny), fullzval, borderMode=cv2.BORDER_TRANSPARENT) + dst = fullimage + zval = fullzval + else: + dst = cv2.warpAffine(img, M, (Nx, Ny)) + zval = cv2.warpAffine(zval, M, (Nx, Ny)) + return dst, zval + +def removeSrcTiles(names, path): + files = os.listdir(path) + for fpath in names: + file = os.path.basename(fpath) + if file in files: + os.remove(fpath) + + def loadAndPasteImage(srcnames, pyramid, fullzval, width, height, rotationvalue, p0, p1, p, background=None): colimgs = [] @@ -318,9 +353,6 @@ class OpticalScan(QtWidgets.QWidget): micModeLayout.addWidget(self.bf_btn) micModeGroup.setLayout(micModeLayout) - self.deleteImgChecker = QtWidgets.QCheckBox('Delete image files after run') - self.deleteImgChecker.setChecked(True) - self.areaOptionsGroup = QtWidgets.QGroupBox('Area Select Options') areaLayout = QtWidgets.QFormLayout() areaLayout.addRow(radioGroup) @@ -335,7 +367,6 @@ class OpticalScan(QtWidgets.QWidget): furtherOptionsGroup = QtWidgets.QGroupBox('Further Options') furtherOptionsLayout = QtWidgets.QFormLayout() furtherOptionsLayout.addRow(self.hdrcheck) - furtherOptionsLayout.addRow(self.deleteImgChecker) furtherOptionsGroup.setLayout(furtherOptionsLayout) btnLayout = QtWidgets.QHBoxLayout() @@ -672,7 +703,7 @@ class OpticalScan(QtWidgets.QWidget): Ngrid = len(self.dataset.grid) names = [] for k in range(len(self.dataset.zpositions)): - names.append(os.path.join(self.dataset.getScanPath(),f"image_{i}_{k}.bmp")) + names.append(os.path.join(self.dataset.getScanPath(), f"image_{i}_{k}.bmp")) width, height, rotationvalue = (self.dataset.imagedim_df if self.view.imparent.ramanSwitch.df_btn.isChecked() else self.dataset.imagedim_bf) p = self.dataset.grid[i] p0, p1 = self.dataset.maxdim[:2], self.dataset.maxdim[2:] @@ -682,8 +713,13 @@ class OpticalScan(QtWidgets.QWidget): else: background_img = None - self.view.imgdata, self.dataset.zvalimg = loadAndPasteImage(names, self.pyramid, self.dataset.zvalimg, width, height, - rotationvalue, p0, p1, p, background=background_img) + self.view.imgdata, self.dataset.zvalimg = loadAndPasteImage( + names, self.pyramid, self.dataset.zvalimg, width, height, + rotationvalue, p0, p1, p, background=background_img + ) + + removeSrcTiles(names, self.dataset.getScanPath()) + self.progressbar.setValue(i+1) if i>3: timerunning = time()-self.starttime @@ -703,13 +739,6 @@ class OpticalScan(QtWidgets.QWidget): self.pyramid.toDataset() - if self.deleteImgChecker.isChecked(): - path = self.dataset.getScanPath() - files = os.listdir(path) - for file in files: - if file.startswith('image_') and (file.endswith('.bmp') or file.endswith('.tiff')): - os.remove(os.path.join(path, file)) - self.ramanctrl.connect() self.view.saveDataSet() self.view.unblockUI() diff --git a/scenePyramid.py b/scenePyramid.py index be6e8f020048273b952bad7f6c8205ae78989424..f5957d08bea8d8f7af723746511f7ef2e4fe0a4d 100644 --- a/scenePyramid.py +++ b/scenePyramid.py @@ -539,72 +539,41 @@ class ScenePyramid: interpolation=cv2.INTER_AREA ) + pos_x_scaled = current_scaling_factor * pos_x + pos_y_scaled = current_scaling_factor * pos_y + # width, height of src tile src_tile_height, src_tile_width = current_src_img.shape[:2] - # position of src tile in view tile - src_tile_pos_x = (current_scaling_factor * pos_x) % view_tile_width - src_tile_pos_y = (current_scaling_factor * pos_y) % view_tile_height - # does src tile exceed view tiles width? add exceeding parts to next (right) view tile - add_to_right = src_tile_pos_x + src_tile_width > view_tile_width - # does src tile exceed view tiles height? add exceeding parts to next (lower) view tile - add_to_below = src_tile_pos_y + src_tile_height > view_tile_height - # does src tile exceed view tiles height and width? add exceeding parts to next (right and lower) view tile - add_to_left_below = add_to_right and add_to_below - - # indices of the tile, the src tiles origin is located in - i = math.floor(current_scaling_factor * pos_x / view_tile_width) - j = math.floor(current_scaling_factor * pos_y / view_tile_height) - - # add to v(i , j) - tile = self.readViewTile(slice_nr, i, j) - size = (tile.shape[1], tile.shape[0]) - ''' - m = np.float32([ - [1, 0, src_tile_pos_x], - [0, 1, src_tile_pos_y] - ]) - ''' - - # adjust translation part of affine transformation matrix - m_rot[0][2] = src_tile_pos_x - m_rot[1][2] = src_tile_pos_y - m = m_rot - cv2.warpAffine(current_src_img, m, size, tile, borderMode=cv2.BORDER_TRANSPARENT) - self.saveViewTile(tile, slice_nr, i, j) - - # add to v(i+1, j) right of (i, j) - if add_to_right: - tile = self.readViewTile(slice_nr, i + 1, j) - size = (tile.shape[1], tile.shape[0]) - m = np.float32([ - [1, 0, src_tile_pos_x - view_tile_width], - [0, 1, src_tile_pos_y] - ]) - cv2.warpAffine(current_src_img, m, size, tile, borderMode=cv2.BORDER_TRANSPARENT) - self.saveViewTile(tile, slice_nr, i + 1, j) - - # add to v(i , j+1) below of (i, j) - if add_to_below: - tile = self.readViewTile(slice_nr, i, j + 1) - size = (tile.shape[1], tile.shape[0]) - m = np.float32([ - [1, 0, src_tile_pos_x], - [0, 1, src_tile_pos_y - view_tile_height] - ]) - cv2.warpAffine(current_src_img, m, size, tile, borderMode=cv2.BORDER_TRANSPARENT) - self.saveViewTile(tile, slice_nr, i, j + 1) - - # add to v(i+1, j+1) right and below of (i, j) - if add_to_left_below: - tile = self.readViewTile(slice_nr, i + 1, j + 1) - size = (tile.shape[1], tile.shape[0]) - m = np.float32([ - [1, 0, src_tile_pos_x - view_tile_width], - [0, 1, src_tile_pos_y - view_tile_height] - ]) - cv2.warpAffine(current_src_img, m, size, tile, borderMode=cv2.BORDER_TRANSPARENT) - self.saveViewTile(tile, slice_nr, i + 1, j + 1) + # position of src tile in first view tile + src_tile_pos_x = pos_x_scaled % view_tile_width + src_tile_pos_y = pos_y_scaled % view_tile_height + + # indices of tile, the src tiles origin is located in + io = math.floor(pos_x_scaled / view_tile_width) + jo = math.floor(pos_y_scaled / view_tile_height) + + # indices of tiles, the src tile is reaching in + ie = math.floor((pos_x_scaled + src_tile_width) / view_tile_width) + je = math.floor((pos_y_scaled + src_tile_height) / view_tile_height) + + # move in x direction + for i in range(io, ie + 1): + cur_src_tile_pos_y = src_tile_pos_y + # move in y direction + for j in range(jo, je + 1): + # add to v(i, j) + tile = self.readViewTile(slice_nr, i, j) + size = (tile.shape[1], tile.shape[0]) + # translation matrix + m = np.float32([ + [1, 0, src_tile_pos_x], + [0, 1, cur_src_tile_pos_y] + ]) + cv2.warpAffine(current_src_img, m, size, tile, borderMode=cv2.BORDER_TRANSPARENT) + self.saveViewTile(tile, slice_nr, i, j) + cur_src_tile_pos_y -= view_tile_height + src_tile_pos_x -= view_tile_width current_scaling_factor *= self.scalingFactor slice_nr += 1 @@ -785,7 +754,7 @@ class ScenePyramid: with k(i,j) = tile at pos (i, j) h, w = base height, base width of tile - we need to extract from subimage from tiles K where (i, j) in: + we need to extract subimage from tiles k(i, j) with i, j in: imin = floor(xmin/w) <= i <= floor(xmax/w) = imax jmin = floor(ymin/h) <= j <= floor(ymax/h) = jmax transform p0, p1 (relative to origin of tile k(imin, jmin)):