def insertLayer(self, index, name=None, data=None): ''' insert a new image as layer ...add new / override existing layer ...show dialog when data.shape != self.image.shape ''' if data is not None: try: self.image = np.insert(self.image, index, data, axis=0) except IndexError: index = -1 self.image = np.insert(self.image, index, data, axis=0) except (ValueError, MemoryError): if index == 0 and len(self.image) == 1: #replace, if only has one layer self.image = np.expand_dims(data, axis=0) else: if type(data) == list: data = data[0] s1 = self.image[0].shape s2 = data.shape #LAYER COLOR IS DIFFERENT: c1 = isColor(self.image[0]) c2 = isColor(data) if c1 and not c2: data = toColor(data) s2 = data.shape elif not c1 and c2: self.image = toColor(self.image) s1 = self.image[0].shape if s1 != s2: #NEW LAYER SHAPE DOESNT FIT EXISTING: ###show DIALOG##### d = DifferentShapeDialog(name, s1, s2) d.exec_() r = d.opt if r == d.optNewDisplay: self.moveLayerToNewImage = index return elif r == d.optCut: data = data[0:s1[0],0:s1[1]] if data.shape != s1: d = np.zeros(s1) d[0:s2[0], 0:s2[1]]=data data = d elif r == d.optResize: data = cv2.resize(data, (s1[1],s1[0])) elif r == d.optWarp: data = PerspectiveTransformation(self.image[-1]).fitImg(data) self.image = np.insert(self.image, index, data, axis=0) self.currentIndex = index self.setImage(self.image) return self.image[index]
def addColorLayer(self, layer=None, name='Unnamed', tip='', color=None, alpha=0.5): ''' add a [layer], a np.array (2d or 3d), as colour overlay to the image ''' if layer is None: s = self.image.shape if len(s) == 4: # multi layer color image s = s[1:-1] elif len(s) == 3: if s[-1] == 3: # single layer color image s = s[:-1] else: # multi layer grey image s = s[1:] layer = np.zeros(shape=s) if isColor(layer): layer = toGray(layer) if color is None: # set colour as function of the number of colorItems: color = pg.intColor(len(self.cItems)).rgb() cItem = ColorLayerItem(layer, imageWidget=self, color=color, alpha=alpha ) name = incrementName(list(self.cItems.keys()), name) self.cItems[name] = cItem self.view.addItem(cItem) self.sigOverlayAdded.emit(cItem, name, tip) return cItem
def _chromaticity(self): i = self.display.widget.image assert isColor(i), 'Only works on color images' out = np.empty_like(i) for n, im in enumerate(i): out[n] = rgChromaticity(im) self.handleOutput(out, title='RG chromacity')
def separate(self): i = self.display.widget.image assert isColor(i), 'Only works on color images' out = np.transpose(i, axes=(3, 0, 1, 2)) self.handleOutput(out, title='Color channels separated', names=['red', 'green', 'blue'])
def addColorLayer(self, layer=None, name='Unnamed', tip='', color=None, alpha=0.5): ''' add a [layer], a np.array (2d or 3d), as colour overlay to the image ''' if layer is None: s = self.image.shape if len(s) == 4: # multi layer color image s = s[1:-1] elif len(s) == 3: if s[-1] == 3: # single layer color image s = s[:-1] else: #multi layer grey image s = s[1:] layer = np.zeros(shape=s) if isColor(layer): layer = toGray(layer) if color is None: #set colour as function of the number of colorItems: color = pg.intColor(len(self.cItems)).rgb() cItem = ColorLayerItem(layer, imageWidget=self, color=color, alpha=alpha ) name = incrementName(self.cItems.keys(), name) self.cItems[name] = cItem self.view.addItem(cItem) self.sigOverlayAdded.emit(cItem, name, tip) return cItem
def _monochromaticWavelength(self): i = self.display.widget.image assert isColor(i), 'Only works on color images' out = np.empty(shape=i.shape[:-1]) for n, im in enumerate(i): out[n] = monochromaticWavelength(im) self.handleOutput(out, title='monochromatic wavelength', axes=('x', 'y', 'wavelength [nm]'))
def _process(self): img = self.display.widget.image[-1] if isColor(img): img = toGray(img) avg = SNRaverage(SNR(img)) i = self.pOpt.opts['limits'].index(self.pOpt.value()) limit = self.SNR_LIMITS[i][1] fac = limit / avg return fac
def activate(self): self._items = [] self._fns = [] nr = self.pRNRows.value() s = self.pSpace.value() w = self.display.widget vb = w.view.vb if len(w.image) < 2: self.setChecked(False) raise Exception('needs multiple images for grid view') w.setCurrentIndex(0) w.display.widget.showTimeline(False) hist = w.ui.histogram s0,s1 = w.image.shape[1:3] px,py = s0+s,0 ir = 1 for img in w.image[1:]: if isColor(img): #TODO: I dont know why it returns an error on color ...find out print 'only works on grayscale images at the moment' img = toGray(img) item = ImageItem(img) #link colorbar fn1 = lambda hist, i=item: i.setLookupTable(hist.getLookupTable) fn2 = lambda hist, i=item: i.setLevels(hist.region.getRegion() ) hist.sigLookupTableChanged.connect(fn1) hist.sigLevelsChanged.connect(fn2) s0,s1 = img.shape[:2] item.moveBy(px,py) vb.addItem(item) #update grid position coords: ir += 1 px += s0+s if ir == nr: ir = 0 px = 0 py += s1+s self._items.append(item) self._fns.append((fn1,fn2)) hist.sigLookupTableChanged.emit(hist) hist.sigLevelsChanged.emit(hist) ar = vb.state['autoRange'] vb.state['autoRange'] = [True,True] vb.updateAutoRange() vb.state['autoRange'] = ar
def activate(self): self._items = [] self._fns = [] w = self.display.widget vb = w.view.vb if len(w.image) < 2: self.setChecked(False) raise Exception('needs multiple images for grid view') w.setCurrentIndex(0) w.display.widget.showTimeline(False) hist = w.ui.histogram for img, (px, py) in zip(w.image[1:], self._positions()): if isColor(img): # TODO: I dont know why it returns an error on color ...find # out print('only works on grayscale images at the moment') img = toGray(img) item = ImageItem(img) # link colorbar fn1 = lambda hist, i=item: i.setLookupTable(hist.getLookupTable) fn2 = lambda hist, i=item: i.setLevels(hist.region.getRegion()) hist.sigLookupTableChanged.connect(fn1) hist.sigLevelsChanged.connect(fn2) # s0,s1 = img.shape[:2] item.moveBy(px, py) vb.addItem(item) self._items.append(item) self._fns.append((fn1, fn2)) hist.sigLookupTableChanged.emit(hist) hist.sigLevelsChanged.emit(hist) ar = vb.state['autoRange'] vb.state['autoRange'] = [True, True] vb.updateAutoRange() vb.state['autoRange'] = ar
def activate(self): self._fns = [] w = self.display.widget vb = w.view.vb w.subitems = [] if len(w.image) < 2: self.setChecked(False) raise Exception('needs multiple images for grid view') w.setCurrentIndex(0) w.display.widget.showTimeline(False) hist = w.ui.histogram for img, (px, py) in zip(w.image[1:], self._positions()): if isColor(img): # TODO: I dont know why it returns an error on color ...find # out print('only works on grayscale images at the moment') img = toGray(img) item = ImageItem(img) # link colorbar fn1 = lambda hist, i=item: i.setLookupTable(hist.getLookupTable) fn2 = lambda hist, i=item: i.setLevels(hist.region.getRegion()) hist.sigLookupTableChanged.connect(fn1) hist.sigLevelsChanged.connect(fn2) # s0,s1 = img.shape[:2] item.moveBy(px, py) vb.addItem(item) w.subitems.append(item) self._fns.append((fn1, fn2)) hist.sigLookupTableChanged.emit(hist) hist.sigLevelsChanged.emit(hist) ar = vb.state['autoRange'] vb.state['autoRange'] = [True, True] vb.updateAutoRange() vb.state['autoRange'] = ar
def fn(path, img): r = self.pRange.value() if r == '0-max': r = (0, w.levelMax) elif r == 'min-max': r = (w.levelMin, w.levelMax) else: # 'current' r = w.ui.histogram.getLevels() int_img = toUIntArray(img, # cutNegative=self.pCutNegativeValues.value(), cutHigh=~self.pStretchValues.value(), range=r, dtype={'8 bit': np.uint8, '16 bit': np.uint16}[self.pDType.value()]) if isColor(int_img): int_img = cv2.cvtColor(int_img, cv2.COLOR_RGB2BGR) cv2.imwrite(path, transpose(int_img))
def fn(path, img): r = self.pRange.value() if r == '0-max': r = (0, w.levelMax) elif r == 'min-max': r = (w.levelMin, w.levelMax) else: # 'current' r = w.ui.histogram.getLevels() int_img = toUIntArray( img, # cutNegative=self.pCutNegativeValues.value(), cutHigh=~self.pStretchValues.value(), range=r, dtype={ '8 bit': np.uint8, '16 bit': np.uint16 }[self.pDType.value()]) if isColor(int_img): int_img = cv2.cvtColor(int_img, cv2.COLOR_RGB2BGR) cv2.imwrite(path, int_img)
def insertLayer(self, index, name=None, data=None): ''' insert a new image as layer ...add new / override existing layer ...show dialog when data.shape != self.image.shape ''' if data is not None: try: self.image = np.insert(self.image, index, data, axis=0) except IndexError: index = -1 self.image = np.insert(self.image, index, data, axis=0) except (ValueError, MemoryError): if index == 0 and len(self.image) == 1: # replace, if only has one layer self.image = np.expand_dims(data, axis=0) else: if isinstance(data, list): data = data[0] s1 = self.image[0].shape s2 = data.shape # LAYER COLOR IS DIFFERENT: c1 = isColor(self.image[0]) c2 = isColor(data) if c1 and not c2: data = toColor(data) s2 = data.shape elif not c1 and c2: self.image = toColor(self.image) s1 = self.image[0].shape if s1 != s2: if isRot90(s1, s2): print('Image is rotated 90DEG.') data = rot90(data) else: # NEW LAYER SHAPE DOESNT FIT EXISTING: ###show DIALOG##### d = DifferentShapeDialog(name, s1, s2) d.exec_() r = d.opt if r == d.optNewDisplay: self.moveLayerToNewImage = index return elif r == d.optCut: data = data[0:s1[0], 0:s1[1]] if data.shape != s1: d = np.zeros(s1) d[0:s2[0], 0:s2[1]] = data data = d elif r == d.optResize: data = cv2.resize(data, (s1[1], s1[0])) elif r == d.optWarp: data = PerspectiveImageStitching( self.image[-1]).fitImg(data) self.image = np.insert(self.image, index, data, axis=0) self.currentIndex = index self.setImage(self.image) return self.image[index]
def _check(self): i = self.display.widget.image if i is not None: self.setChecked(isColor(i))
def separate(self): i = self.display.widget.image assert isColor(i), 'Only works on color images' out = np.transpose(i, axes=(3,0,1,2)) self.handleOutput(out, title='Color channels separated', names=['red', 'green', 'blue'])