def destroy(self): if self.textfields: for tf in self.textfields: tf.setEnabled(False) self.textfields = None Roi.removeRoiListener(self) self.imp = None
def setRoisarray(self, rois, img) : self.__roisArray=[] self.__roisArray+=rois self.__image=img self.__firstslice=img.getSlice() self.__ranges={} self.__test="ok" Roi.setColor(Color.BLUE)
def __init__(self, rois, img): #constructor initialize a private rois array self.__roisArray=[] self.__roisArray+=rois self.__image=img self.__firstslice=img.getSlice() self.__ranges={} self.__test="ok" Roi.setColor(Color.BLUE) self.__setMaxValues()
def windowClosing(self, event): answer = JOptionPane.showConfirmDialog( event.getSource(), "Are you sure you want to close?", "Confirm closing", JOptionPane.YES_NO_OPTION) if JOptionPane.NO_OPTION == answer: event.consume() # Prevent closing else: Roi.removeRoiListener(self.roilistener) event.getSource().dispose() # close the JFrame
def __init__(self): #super(GridLayout(0,1)) # 1 column, as many rows as necessary super(RoiGroupTable, self).__init__(GridLayout( 0, 1)) # 1 column, as many rows as necessary #super() #self.setLayout(GridLayout(0,1)) ### Table Panel ### # Prepare table data headers = ["Group number", "Name"] listNames = Roi.getGroupNames().split(",") # groupNames is a list then dataRows = [[item[0] + 1, item[1]] for item in enumerate(listNames) ] # +1 since the group actually start at 1 #print dataRows # Make the table pane table = JTable(dataRows, headers) #table.setPreferredScrollableViewportSize( Dimension(500, 70) ) #table.setFillsViewportHeight(true) # Create the scroll pane and add the table to it. tablePane = JScrollPane(table) #tablePane = ScrollPane() #tablePane.add(table) # Add the scrollpane to the main panel. self.add(tablePane)
def parse_roistr_to_roi(self): """interpret string saved in parameters JSON as IJ ROI""" from ij.gui import PolygonRoi, Roi rect_format_str = "java.awt.Rectangle\[x=(?P<x>\d+)\,y=(?P<y>\d+)\,width=(?P<w>\d+)\,height=(?P<h>\d+)\]" m1 = re.match(rect_format_str, self.spatial_crop) if bool(m1): return Roi(int(m1.groupdict()['x']), int(m1.groupdict()['y']), int(m1.groupdict()['w']), int(m1.groupdict()['h'])) else: # if original ROI wasn't a rectangle... if isinstance(self.spatial_crop, str): str_list = self.spatial_crop[2:-2].split('), (') poly_format_str = '(?P<x>\d+)\, (?P<y>\d+)' xs = [] ys = [] for s in str_list: m2 = re.match(poly_format_str, s) if bool(m2): xs.append(float(m2.groupdict()['x'])) ys.append(float(m2.groupdict()['y'])) else: xs = [x for (x, y) in self.spatial_crop] ys = [y for (x, y) in self.spatial_crop] if len(xs) > 0: return PolygonRoi(xs, ys, Roi.POLYGON) else: return None
def generateOverlayRoi(self, imp): """For a given ImagePlus, generate the overlay ROI""" pixSizeLowM = self.getLowMagPixelSize(imp); # zoom occurs around the center of the image, but positions are defined wrt the # top left - so need to transfom to central origin coords (with x, y in normal directions) ox = self.scanImageDimensionsXY[0]/2.0; oy = self.scanImageDimensionsXY[1]/2.0; pixSizeHighM = pixSizeLowM * self.highMagM/self.lowMagM; xprime = self.roiX - ox - 0.5; yprime = oy - self.roiY + 0.5; w3x = math.ceil((self.lowMagM/self.highMagM) * self.roiW); h3x = math.ceil((self.lowMagM/self.highMagM) * self.roiH); xprime3x = (self.lowMagM/self.highMagM) * xprime + self.panUmXY[0]/pixSizeLowM; yprime3x = (self.lowMagM/self.highMagM) * yprime - self.panUmXY[1]/pixSizeLowM; x3x = math.ceil(ox + xprime3x - self.lowMagRoiOffsetXY[0] + 1); y3x = math.ceil(oy - yprime3x - self.lowMagRoiOffsetXY[1] + 1); print("X corner: " + str(x3x)); print("Y corner: " + str(y3x)); print("Width = " + str(w3x)); print("Height = " + str(h3x)); return Roi(x3x, y3x, w3x, h3x);
def scaleTypeROI(roi): if isinstance(roi,PointRoi): p=roi.getFloatPolygon() x,y=list(p.xpoints),list(p.ypoints) xNew,yNew=map(lambda c:c*scale[0],x),map(lambda c:c*scale[1],y) roiNew=PointRoi(xNew,yNew) elif isinstance(roi,ShapeRoi): roiSels=roi.getRois() roiNews=map(scaleTypeROI,roiSels) roiNew=0 for roi in roiNews: if roiNew==0: roiNew=ShapeRoi(roi) else: roiNew=roiNew.or(ShapeRoi(roi)) else: tp=roi.getType() if tp!=0: p=roi.getPolygon() x,y=list(p.xpoints),list(p.ypoints) posNew=map(lambda pos:(pos[0]*scale[0],pos[1]*scale[1]),zip(x,y)) xNew,yNew=zip(*posNew) roiNew=PolygonRoi(xNew,yNew,tp) else: x,y,w,h=roi.getXBase(),roi.getYBase(),roi.getFloatWidth(),roi.getFloatHeight() xNew,yNew,wNew,hNew=x*scale[0],y*scale[1],w*scale[0],h*scale[1] roiNew=Roi(xNew,yNew,wNew,hNew) return(roiNew)
def shift_roi(imp, roi, dr): """ shifts a roi in x,y by dr.x and dr.y if the shift would cause the roi to be outside the imp, it only shifts as much as possible maintaining the width and height of the input roi """ if roi == None: return roi else: r = roi.getBounds() # init x,y coordinates of new shifted roi sx = 0 sy = 0 # x shift if (r.x + dr.x) < 0: sx = 0 elif (r.x + dr.x + r.width) > imp.width: sx = int(imp.width-r.width) else: sx = r.x + int(dr.x) # y shift if (r.y + dr.y) < 0: sy = 0 elif (r.y + dr.y + r.height) > imp.height: sy = int(imp.height-r.height) else: sy = r.y + int(dr.y) # return shifted roi shifted_roi = Roi(sx, sy, r.width, r.height) return shifted_roi
def update(self, inc): """ Set the rectangular ROI defined by the textfields values onto the active image. """ value = self.parse() if value: self.textfields[self.index].setText(str(value + inc)) imp = IJ.getImage() if imp: imp.setRoi(Roi(*[int(tf.getText()) for tf in self.textfields]))
def vor_cell(nuc_bin_imp, cell): """creates the voronoi for one cell, cell is assumed to have nucs""" rm = RoiManager.getRoiManager() rm.reset() d = Duplicator() nuc_bin_copy = d.run(nuc_bin_imp) IJ.run(nuc_bin_copy, "Make Binary", "") nuc_bin_copy.setRoi(cell.roi) IJ.run(nuc_bin_copy, "Clear Outside", "") IJ.run(nuc_bin_copy, "Voronoi", "") nuc_bin_copy.setRoi(None) ip = nuc_bin_copy.getProcessor() ip.setMinAndMax(0, 1) IJ.run(nuc_bin_copy, "Apply LUT", "") IJ.run(nuc_bin_copy, "Invert", "") nuc_bin_copy.setRoi(cell.roi) IJ.run(nuc_bin_copy, "Analyze Particles...", "add") vor_rois = rm.getRoisAsArray() nuc_inds = [x for x in range(len(cell.nucs))] for vor_roi in vor_rois: temp = None for i, nuc_ind in enumerate(nuc_inds): nuc_roi = cell.nucs[nuc_ind].roi nuc_cent = roi_cent(nuc_roi, integer=True) if vor_roi.contains(*nuc_cent): cell.nucs[nuc_ind].vor_roi = vor_roi ## I don't think I need to do this, I could just use i outside of loop but it feels so insecure or something temp = i break else: IJ.log('cell: {}, issue with voronoi nuc match up'.format( cell.name)) rm.reset() for i, nuc in enumerate(cell.nucs): x = int(nuc.roi.getXBase()) y = int(nuc.roi.getYBase()) IJ.log('{}. ({},{})'.format(i, x, y)) add_roi(Roi(x, y, 10, 10), str(i)) IJ.log(str(nuc_inds)) add_roi(vor_roi, "vor_roi") ## raise RuntimeError('cell: {}, issue with voronoi nuc match up'.format(cell.name)) if temp is not None: del nuc_inds[temp] force_close(nuc_bin_copy)
def showTable(self): """ Add the main panel to a GenericDialog and show it """ gd = GenericDialog("Roi-group table") gd.addPanel(self) # Add current table instance to panel gd.addMessage("""If you use this plugin, please cite: Laurent Thomas. (2020, November 18). LauLauThom/RoiGroupTable: ImageJ/Fiji RoiGroup Table (Version 1.0) Zenodo. http://doi.org/10.5281/zenodo.4279049""") gd.addHelp(r"https://github.com/LauLauThom/RoiGroupTable") gd.showDialog() if gd.wasOKed(): # Update ImageJ Roi group names mapping stringGroup = self.tableModel.getGroupString() Roi.setGroupNames(stringGroup)
def CropInputImage(ip, width, height): temp = int(ip.width / width) newwidth = temp * width temp = int(ip.height / height) newheight = temp * height roi = Roi(0, 0, newwidth, newheight) ip.setRoi(roi) ip = ip.crop() return ip.crop()
def SplitImage(ip, width, height): stack = ImageStack(width, height) for x in range(0, ip.width, width): for y in range(0, ip.height, height): roi = Roi(x, y, width, height) ip.setRoi(roi) ip2 = ip.crop() stack.addSlice(None, ip2) return stack
def findAllEndPointInSkeleton(impMT): points = getPointsFromSekelton(impMT) endPoints = [] for point in points: rect = Roi(point.x-1, point.y-1, 3, 3) impMT.setRoi(rect) stats = impMT.getStatistics () impMT.killRoi() if (stats.mean > 56 and stats.mean<57): endPoints.append(point) return endPoints
def GenerateGallery(imp, CoordinateList): """ Generates a gallery from a list of coordinates: input values are: a coordinate list (x,y as list of tupels) an image from which the gallery is generated (imp), Image must (for now) be a 8 or 16 bit composite a ROI size for the gallery (roisize)""" if CoordinateList != []: CellNumber = len(CoordinateList) channelnumber = imp.getNChannels() slicenumber = imp.getNSlices() bitdepth = imp.getBitDepth() imp2 = IJ.createHyperStack("Gallery", roisize, roisize, channelnumber, slicenumber, CellNumber, bitdepth) if bitdepth != 24: imp2.copyLuts(imp) timer = 0 for cells in CoordinateList: timer = timer + 1 roi2 = Roi(cells[0] - (roisize / 2), cells[1] - roisize / 2, roisize, roisize) imp.setC(1) imp.setRoi(roi2) imp.copy() imp2.setT(timer) imp2.setC(1) imp2.paste() if channelnumber > 1: imp.setC(2) imp.copy() imp2.setC(2) imp2.paste() if channelnumber > 2: imp.setC(3) imp.copy() imp2.setC(3) imp2.paste() imp2.show() if Label_Gallery: timer2 = 0 for cells in CoordinateList: timer2 = timer2 + 1 imp2.setT(timer2) imp2.setC(1) ip = imp2.getProcessor() Labelfont = Font("Arial", Font.PLAIN, 12) ip.setFont(Labelfont) ip.setColor(65000) ROINumber = str(cells[2]) ip.drawString(ROINumber[:4], 5, 14) imp.updateAndDraw() return imp2
def save_roi_set(imp=IJ.getImage()): img_dir, name = get_file_info() roi_dir = make_roi_dir(img_dir, name) roi_path = make_roi_path(roi_dir, name) Roi.setColor(Color.blue) rm = RoiManager().getInstance() rm.deselect() rm.runCommand("Save", roi_path) ol = imp.getOverlay() if ol is None: ol = Overlay() for roi in rm.getRoisAsArray(): ol.add(roi) imp.setOverlay(ol) rm.runCommand("delete") ol.setStrokeColor(Color.blue) Roi.setColor(Color.yellow)
def overlay_corners(corners, L): ov = Overlay() for [x, y] in corners: rect = Roi(x, y, L, L) rect.setStrokeColor(Color.RED) rect.setLineWidth(40) ov.add(rect) return ov
def local_angles(points, scope=1): angles = [] orthogonals = [] for i,p in enumerate(points): #localpoly = Polygon() #or j in range(0, i-scope): # localpoly.addPoint(int(points[j].x), int(points[j].y)) #localpoly.addPoint(int(p.x), int(p.y)) #for j in range(i, min(i+scope,len(points))): # localpoly.addPoint(int(points[j].x), int(points[j].y)) #polygon = PolygonRoi(localpoly, PolygonRoi.POLYLINE) #angle = polygon.getAngle() p1 = points[max(0,i-scope)] p2 = points[min(len(points)-1, i+scope)] shiftx = 0.5*(p1.x+p2.x) shifty = 0.5*(p1.y+p2.y) ortho1 = Point(int(-(p1.y-shifty)+shiftx), int(p1.x-shiftx+shifty),0) ortho2 = Point(int(-(p2.y-shifty)+shiftx), int(p2.x-shiftx+shifty),0) orthogonals.append([ortho1, ortho2]) dummyroi = Roi(p1.x, p1.y, p2.x, p2.y) angle = dummyroi.getAngle(p1.x, p1.y, p2.x, p2.y) angles.append(angle) return angles, orthogonals
def save_rois(imp, corners_cleaned, L, OUTDIR): # parse title tit = imp.getTitle() core = '_'.join(tit.split('_')[0:-1]) ending = tit.split('_')[-1] # save rois roi_ID = 1 for [x, y] in corners_cleaned: rect = Roi(x, y, L, L) imp.setRoi(rect) imp2 = imp.crop() # save IJ.saveAsTiff( imp2, path.join(OUTDIR, core + "_ROI-" + str(roi_ID) + "_" + ending)) roi_ID += 1
def __init__(self): if IJ.getFullVersion() < "1.53b": message = "ImageJ with at least version 1.53b required. Update with Help > Update ImageJ..." IJ.error(message) raise Exception(message) super(TableModel, self).__init__() self.headers = ["Group", "Name"] groupNames = Roi.getGroupNames() # groupNames can be None ! groupNames = groupNames.split(",") if groupNames else [ "ExampleName-doubleClick to edit" ] # groupNames is a list self.nRows = len(groupNames) self.columns = [[], []] # 2 columns self.columns[0] = range(1, len(groupNames) + 1) self.columns[1] = groupNames
def findEndPointsInSkeleton(impMT): points = getPointsFromSekelton(impMT) nr = 0 endPoint1 = (-1,-1) endPoint2 = (-1,-1) for point in points: rect = Roi(point.x-1, point.y-1, 3, 3) impMT.setRoi(rect) stats = impMT.getStatistics() impMT.killRoi() if (stats.mean > 56 and stats.mean<57): if (nr==0): endPoint1 = point else: endPoint2 = point nr = nr + 1 return nr, endPoint1, endPoint2
def generate_kymograph(data_to_plot, colormap_string, title_string, trim=True): """Display one-channel kymograph with point furthest from the edges along the middle of the kymograph """ kym_height = 2 * max([len(data) for data in data_to_plot]) + 1 ip = FloatProcessor(len(data_to_plot), kym_height) # normalise such that point furthest from the anchors is in the middle of the kymograph maxy = 0 miny = kym_height for idx, data in enumerate(data_to_plot): dist = [ mb.vector_length(data[0][0], p) * mb.vector_length(data[-1][0], p) for p in [d[0] for d in data] ] distal_idx = dist.index(max(dist)) pix = ip.getPixels() for kidx, didx in zip( range(((kym_height - 1) / 2 + 1), ((kym_height - 1) / 2 + 1) + len(data) - distal_idx), range(distal_idx, len(data))): pix[kidx * len(data_to_plot) + idx] = data[didx][1] for kidx, didx in zip( range(((kym_height - 1) / 2 + 1) - distal_idx, ((kym_height - 1) / 2 + 1)), range(0, distal_idx)): pix[kidx * len(data_to_plot) + idx] = data[didx][1] maxy = ((kym_height - 1) / 2 + 1) + len(data) - distal_idx if ( ((kym_height - 1) / 2 + 1) + len(data) - distal_idx) > maxy else maxy miny = ((kym_height - 1) / 2 + 1) - distal_idx if (( (kym_height - 1) / 2 + 1) - distal_idx) < miny else miny imp = ImagePlus(title_string, ip) IJ.run(imp, colormap_string, "") if trim: maxtomiddle = maxy - (kym_height - 1) / 2 + 1 mintomiddle = (kym_height - 1) / 2 + 1 - miny if maxtomiddle > mintomiddle: miny = (kym_height - 1) / 2 + 1 - maxtomiddle else: maxy = (kym_height - 1) / 2 + 1 + mintomiddle if (maxy - miny) / 2 == round((maxy - miny) / 2): maxy = maxy - 1 imp.setRoi(Roi(0, miny, imp.getWidth(), (maxy - miny))) imp = imp.crop() imp.show() return imp
def openSubImage( self, x, y, auto=False ): """ This method is called by both openPrevious and openNext to display an image that is cropped from the sourceImage based on the grid coordinates Arguments: - auto : bool, if True the image is autoscaled """ # Set the ROI on the source image #roi = Roi(int(self.x), int(self.y), int(self.width), int(self.width)) roi = Roi( int(x), int(y), int(self.width), int(self.width) ) self.sourceImage.setRoi(roi) # Get a processor corresponding to a cropped version of the image processor = self.sourceImage.getProcessor().crop() self.sourceImage.killRoi() # Make a new image of image and run contrast on it openImage = ImagePlus(" ", processor) return openImage
#print "\n-- Hits after NMS --\n" #for hit in Hits_AfterNMS : print hit # NB : Hits coordinates have not been corrected for cropping here ! Done in the next for loop # Loop over final hits to generate ROI for hit in Hits_AfterNMS: #print hit if Bool_SearchRoi: # Add offset of search ROI hit['BBox'] = (hit['BBox'][0] + dX, hit['BBox'][1] + dY, hit['BBox'][2], hit['BBox'][3]) # Create detected ROI roi = Roi(*hit['BBox']) roi.setName(hit['TemplateName']) roi.setPosition(i) # set ROI Z-position #roi.setProperty("class", hit["TemplateName"]) image.setSlice(i) image.setRoi(roi) if add_roi: rm.add( None, roi, i ) # Trick to be able to set Z-position when less images than the number of ROI. Here i is an digit index before the Roi Name # Show All ROI + Associate ROI to slices rm.runCommand("Associate", "true") rm.runCommand("Show All with labels")
fontName = 'Arial' upperFontSize = 18 lowerFontSize = 10 image = IJ.createImage("MacOSX background picture", "rgb", w, h, 1) # background Toolbar.setForegroundColor(Color(0x5886ea)) Toolbar.setBackgroundColor(Color(0x3464c9)) IJ.run(image, "Radial Gradient", "") # rounded rectangle # correct for MacOSX bug: do the rounded rectangle in another image image2 = image image = IJ.createImage("MacOSX background picture", "rgb", w, h, 1) image.setRoi(Roi(xOffset, yOffset, w - 2 * xOffset, h - 2 * yOffset)) IJ.run(image, "Make rectangular selection rounded", "radius=" + str(radius)) Toolbar.setForegroundColor(Color(0x435a96)) Toolbar.setBackgroundColor(Color(0x294482)) IJ.run(image, "Radial Gradient", "") ip = image.getProcessor() ip.setColor(0x0071bc) ip.setLineWidth(2) image.getRoi().drawPixels(ip) Roi.setPasteMode(Blitter.COPY_TRANSPARENT) #grow = image.getRoi().getClass().getSuperclass().getDeclaredMethod('growConstrained', [Integer.TYPE, Integer.TYPE]) #grow.setAccessible(True) #grow.invoke(image.getRoi(), [1, 1]) image.copy(True) image = image2 image.paste()
def runOneFile(fullFilePath): global gNumChannels global gAlignBatchVersion if not os.path.isfile(fullFilePath): bPrintLog( '\nERROR: runOneFile() did not find file: ' + fullFilePath + '\n', 0) return 0 bPrintLog( time.strftime("%H:%M:%S") + ' starting runOneFile(): ' + fullFilePath, 1) enclosingPath = os.path.dirname(fullFilePath) head, tail = os.path.split(enclosingPath) enclosingPath += '/' #make output folders destFolder = enclosingPath + tail + '_channels/' if not os.path.isdir(destFolder): os.makedirs(destFolder) destMaxFolder = destFolder + 'max/' if not os.path.isdir(destMaxFolder): os.makedirs(destMaxFolder) if gDoAlign: destAlignmentFolder = destFolder + 'alignment/' if not os.path.isdir(destAlignmentFolder): os.makedirs(destAlignmentFolder) if gSave8bit: eightBitFolder = destFolder + 'channels8/' if not os.path.isdir(eightBitFolder): os.makedirs(eightBitFolder) eightBitMaxFolder = eightBitFolder + 'max/' if not os.path.isdir(eightBitMaxFolder): os.makedirs(eightBitMaxFolder) # open image imp = Opener().openImage(fullFilePath) # get parameters of image (width, height, nChannels, nSlices, nFrames) = imp.getDimensions() bitDepth = imp.getBitDepth() infoStr = imp.getProperty("Info") #get all .tif tags if not infoStr: infoStr = '' infoStr += 'bAlignBatch_Version=' + str(gAlignBatchVersion) + '\n' infoStr += 'bAlignBatch_Time=' + time.strftime( "%Y%m%d") + '_' + time.strftime("%H%M%S") + '\n' msgStr = 'w:' + str(width) + ' h:' + str(height) + ' slices:' + str(nSlices) \ + ' channels:' + str(nChannels) + ' frames:' + str(nFrames) + ' bitDepth:' + str(bitDepth) bPrintLog(msgStr, 1) path, filename = os.path.split(fullFilePath) shortName, fileExtension = os.path.splitext(filename) # # look for num channels in ScanImage infoStr if gGetNumChanFromScanImage: for line in infoStr.split('\n'): #scanimage.SI4.channelsSave = [1;2] scanimage4 = find(line, 'scanimage.SI4.channelsSave =') == 0 #state.acq.numberOfChannelsSave=2 scanimage3 = find(line, 'state.acq.numberOfChannelsSave=') == 0 if scanimage3: #print 'line:', line equalIdx = find(line, '=') line2 = line[equalIdx + 1:] if gGetNumChanFromScanImage: gNumChannels = int(line2) bPrintLog( 'over-riding gNumChannels with: ' + str(gNumChannels), 2) if scanimage4: #print ' we have a scanimage 4 file ... now i need to exptract the number of channel' #print 'line:', line equalIdx = find(line, '=') line2 = line[equalIdx + 1:] for delim in ';[]': line2 = line2.replace(delim, ' ') if gGetNumChanFromScanImage: gNumChannels = len(line2.split()) bPrintLog( 'over-riding gNumChannels with: ' + str(gNumChannels), 2) # show imp.show() # split channels if necc. and grab the original window names if gNumChannels == 1: origImpWinStr = imp.getTitle() #use this when only one channel origImpWin = WindowManager.getWindow( origImpWinStr) #returns java.awt.Window if gNumChannels == 2: winTitle = imp.getTitle() bPrintLog('Deinterleaving 2 channels...', 1) IJ.run('Deinterleave', 'how=2 keep') #makes ' #1' and ' #2', with ' #2' frontmost origCh1WinStr = winTitle + ' #1' origCh2WinStr = winTitle + ' #2' origCh1Imp = WindowManager.getImage(origCh1WinStr) origCh2Imp = WindowManager.getImage(origCh2WinStr) origCh1File = destFolder + shortName + '_ch1.tif' origCh2File = destFolder + shortName + '_ch2.tif' # work on a copy, mostly for alignment with cropping copy = Duplicator().run(imp) #copy.copyAttributes(imp) #don't copy attributes, it copies the name (which we do not want) copy.show() # # crop (on copy) if gDoCrop: bPrintLog('making cropping rectangle (left,top,width,height) ', 1) bPrintLog( str(gCropLeft) + ' ' + str(gCropTop) + ' ' + str(gCropWidth) + ' ' + str(gCropHeight), 2) roi = Roi(gCropLeft, gCropTop, gCropWidth, gCropHeight) #left,top,width,height copy.setRoi(roi) time.sleep( 0.5 ) # otherwise, crop SOMETIMES failes. WHAT THE F**K FIJI DEVELOPERS, REALLY, WHAT THE F**K #bPrintLog('cropping', 1) IJ.run('Crop') infoStr += 'bCropping=' + str(gCropLeft) + ',' + str( gCropTop) + ',' + str(gCropWidth) + ',' + str(gCropHeight) + '\n' # # remove calibration ( on original) if gRemoveCalibration: cal = imp.getCalibration() calCoeff = cal.getCoefficients() if calCoeff: msgStr = 'Calibration is y=a+bx' + ' a=' + str( calCoeff[0]) + ' b=' + str(calCoeff[1]) bPrintLog(msgStr, 1) #remove calibration bPrintLog('\tRemoving Calibration', 2) imp.setCalibration(None) #without these, 8-bit conversion goes to all 0 !!! what the f**k !!! #bPrintLog('calling imp.resetStack() and imp.resetDisplayRange()', 2) imp.resetStack() imp.resetDisplayRange() #get and print out min/max origMin = StackStatistics(imp).min origMax = StackStatistics(imp).max msgStr = '\torig min=' + str(origMin) + ' max=' + str(origMax) bPrintLog(msgStr, 2) # 20150723, 'shift everybody over by linear calibration intercept calCoeff[0] - (magic number) if 1: # [1] was this #msgStr = 'Subtracting original min '+str(origMin) + ' from stack.' #bPrintLog(msgStr, 2) #subArgVal = 'value=%s stack' % (origMin,) #IJ.run('Subtract...', subArgVal) # [2] now this #msgStr = 'Adding calCoeff[0] '+str(calCoeff[0]) + ' from stack.' #bPrintLog(msgStr, 2) #addArgVal = 'value=%s stack' % (int(calCoeff[0]),) #IJ.run('Add...', addArgVal) # [3] subtract a magic number 2^15-2^7 = 32768 - 128 magicNumber = gLinearShift #2^15 - 128 msgStr = 'Subtracting a magic number (linear shift) ' + str( magicNumber) + ' from stack.' bPrintLog(msgStr, 2) infoStr += 'bLinearShift=' + str(gLinearShift) + '\n' subArgVal = 'value=%s stack' % (gLinearShift, ) IJ.run(imp, 'Subtract...', subArgVal) # 20150701, set any pixel <0 to 0 if 0: ip = imp.getProcessor() # returns a reference pixels = ip.getPixels() # returns a reference msgStr = '\tSet all pixels <0 to 0. This was added 20150701 ...' bPrintLog(msgStr, 2) pixels = map(lambda x: 0 if x < 0 else x, pixels) bPrintLog('\t\t... done', 2) #get and print out min/max newMin = StackStatistics(imp).min newMax = StackStatistics(imp).max msgStr = '\tnew min=' + str(newMin) + ' max=' + str(newMax) bPrintLog(msgStr, 2) #append calibration to info string infoStr += 'bCalibCoeff_a = ' + str(calCoeff[0]) + '\n' infoStr += 'bCalibCoeff_b = ' + str(calCoeff[1]) + '\n' infoStr += 'bNewMin = ' + str(newMin) + '\n' infoStr += 'bNewMax = ' + str(newMax) + '\n' # # set up if gNumChannels == 1: impWinStr = copy.getTitle() #use this when only one channel impWin = WindowManager.getWindow(impWinStr) #returns java.awt.Window if gNumChannels == 2: winTitle = copy.getTitle() bPrintLog('Deinterleaving 2 channels...', 1) IJ.run('Deinterleave', 'how=2 keep') #makes ' #1' and ' #2', with ' #2' frontmost ch1WinStr = winTitle + ' #1' ch2WinStr = winTitle + ' #2' ch1Imp = WindowManager.getImage(ch1WinStr) ch2Imp = WindowManager.getImage(ch2WinStr) ch1File = destFolder + shortName + '_ch1.tif' ch2File = destFolder + shortName + '_ch2.tif' # # alignment if gDoAlign and gNumChannels == 1 and copy.getNSlices() > 1: infoStr += 'AlignOnChannel=1' + '\n' #snap to middle slice if gAlignOnMiddleSlice: middleSlice = int( math.floor(copy.getNSlices() / 2)) #int() is necc., python is f*****g picky else: middleSlice = gAlignOnThisSlice copy.setSlice(middleSlice) transformationFile = destAlignmentFolder + shortName + '.txt' bPrintLog('MultiStackReg aligning:' + impWinStr, 1) stackRegParams = 'stack_1=[%s] action_1=Align file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body] save' % ( impWin, transformationFile) IJ.run('MultiStackReg', stackRegParams) infoStr += 'AlignOnSlice=' + str(middleSlice) + '\n' #20150723, we just aligned on a cropped copy, apply alignment to original imp origImpTitle = imp.getTitle() stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' % ( origImpTitle, transformationFile) IJ.run('MultiStackReg', stackRegParams) if gDoAlign and gNumChannels == 2 and ch1Imp.getNSlices( ) > 1 and ch2Imp.getNSlices() > 1: #apply to gAlignThisChannel alignThisWindow = '' applyAlignmentToThisWindow = '' if gAlignThisChannel == 1: infoStr += 'AlignOnChannel=1' + '\n' transformationFile = destAlignmentFolder + shortName + '_ch1.txt' alignThisWindow = ch1WinStr applyAlignmentToThisWindow = ch2WinStr else: infoStr += 'AlignOnChannel=2' + '\n' transformationFile = destAlignmentFolder + shortName + '_ch2.txt' alignThisWindow = ch2WinStr applyAlignmentToThisWindow = ch1WinStr alignThisImp = WindowManager.getImage(alignThisWindow) #snap to middle slice if gAlignOnMiddleSlice: middleSlice = int( math.floor(alignThisImp.getNSlices() / 2)) #int() is necc., python is f*****g picky else: middleSlice = gAlignOnThisSlice alignThisImp.setSlice(middleSlice) infoStr += 'bAlignOnSlice=' + str(middleSlice) + '\n' bPrintLog('MultiStackReg aligning:' + alignThisWindow, 1) stackRegParams = 'stack_1=[%s] action_1=Align file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body] save' % ( alignThisWindow, transformationFile) IJ.run('MultiStackReg', stackRegParams) # 20150723, we just aligned on a copy, apply alignment to both channels of original # ch1 bPrintLog('MultiStackReg applying alignment to:' + origCh1WinStr, 1) stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' % ( origCh1WinStr, transformationFile) IJ.run('MultiStackReg', stackRegParams) # ch2 bPrintLog('MultiStackReg applying alignment to:' + origCh2WinStr, 1) stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' % ( origCh2WinStr, transformationFile) IJ.run('MultiStackReg', stackRegParams) #apply alignment to other window #bPrintLog('MultiStackReg applying alignment to:' + applyAlignmentToThisWindow, 1) #applyAlignThisImp = WindowManager.getImage(applyAlignmentToThisWindow) #stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' %(applyAlignmentToThisWindow,transformationFile) #IJ.run('MultiStackReg', stackRegParams) elif gDoAlign: bPrintLog('Skipping alignment, there may be only one slice?', 3) # # save if gNumChannels == 1: imp.setProperty("Info", infoStr) impFile = destFolder + shortName + '.tif' #bPrintLog('Saving:' + impFile, 1) bSaveStack(imp, impFile) #max project bSaveZProject(imp, destMaxFolder, shortName) if gNumChannels == 2: #ch1 origCh1Imp.setProperty("Info", infoStr) #bPrintLog('Saving:' + ch1File, 1) bSaveStack(origCh1Imp, ch1File) #max project bSaveZProject(origCh1Imp, destMaxFolder, shortName + '_ch1') #ch2 origCh2Imp.setProperty("Info", infoStr) #bPrintLog('Saving:' + ch2File, 1) bSaveStack(origCh2Imp, ch2File) #max project bSaveZProject(origCh2Imp, destMaxFolder, shortName + '_ch2') # # post convert to 8-bit and save if gSave8bit: if bitDepth == 16: if gNumChannels == 1: bPrintLog('Converting to 8-bit:' + impWinStr, 1) IJ.selectWindow(impWinStr) #IJ.run('resetMinAndMax()') IJ.run("8-bit") impFile = eightBitFolder + shortName + '.tif' bPrintLog('Saving 8-bit:' + impFile, 2) bSaveStack(imp, impFile) #max project bSaveZProject(imp, eightBitMaxFolder, shortName) if gNumChannels == 2: # bPrintLog('Converting to 8-bit:' + origCh1WinStr, 1) IJ.selectWindow(origCh1WinStr) IJ.run("8-bit") impFile = eightBitFolder + shortName + '_ch1.tif' bPrintLog('Saving 8-bit:' + impFile, 2) bSaveStack(origCh1Imp, impFile) #max project bSaveZProject(origCh1Imp, eightBitMaxFolder, shortName + '_ch1') # bPrintLog('Converting to 8-bit:' + origCh2WinStr, 1) IJ.selectWindow(origCh2WinStr) #IJ.run('resetMinAndMax()') IJ.run("8-bit") impFile = eightBitFolder + shortName + '_ch2.tif' bPrintLog('Saving 8-bit:' + impFile, 2) bSaveStack(origCh2Imp, impFile) #max project bSaveZProject(origCh2Imp, eightBitMaxFolder, shortName + '_ch2') # # close original window imp.changes = 0 imp.close() #copy copy.changes = 0 copy.close() # # close ch1/ch2 if gNumChannels == 2: #original origCh1Imp.changes = 0 origCh1Imp.close() origCh2Imp.changes = 0 origCh2Imp.close() #copy ch1Imp.changes = 0 ch1Imp.close() ch2Imp.changes = 0 ch2Imp.close() bPrintLog( time.strftime("%H:%M:%S") + ' finished runOneFile(): ' + fullFilePath, 1)
RM = RoiManager() rm = RM.getInstance() # Show All ROI + Associate ROI to slices rm.runCommand("Associate", "true") rm.runCommand("Show All with labels") # Loop over final hits to generate ROI, result table... for hit in Hits_AfterNMS: if Bool_SearchRoi: # Add offset of searchRoi hit['BBox'] = (hit['BBox'][0] + dX, hit['BBox'][1] + dY, hit['BBox'][2], hit['BBox'][3]) if show_roi: roi = Roi(*hit['BBox']) roi.setName(hit['TemplateName']) rm.addRoi(roi) if show_table: Xcorner, Ycorner = hit['BBox'][0], hit['BBox'][1] Xcenter, Ycenter = CornerToCenter(Xcorner, Ycorner, hit['BBox'][2], hit['BBox'][3]) Dico = { "Image": ImageName, 'Template': hit['TemplateName'], 'Xcorner': Xcorner, 'Ycorner': Ycorner, 'Xcenter': Xcenter, 'Ycenter': Ycenter, 'Score': hit['Score']
IJ.run(image, "Radial Gradient", "") # rounded rectangle # correct for MacOSX bug: do the rounded rectangle in another image image2 = image image = IJ.createImage("MacOSX background picture", "rgb", w, h, 1) image.setRoi(Roi(xOffset, yOffset, w - 2 * xOffset, h - 2 * yOffset)) IJ.run(image, "Make rectangular selection rounded", "radius=" + str(radius)) Toolbar.setForegroundColor(Color(0x435a96)) Toolbar.setBackgroundColor(Color(0x294482)) IJ.run(image, "Radial Gradient", "") ip = image.getProcessor() ip.setColor(0x0071bc) ip.setLineWidth(2) image.getRoi().drawPixels(ip) Roi.setPasteMode(Blitter.COPY_TRANSPARENT) #grow = image.getRoi().getClass().getSuperclass().getDeclaredMethod('growConstrained', [Integer.TYPE, Integer.TYPE]) #grow.setAccessible(True) #grow.invoke(image.getRoi(), [1, 1]) image.copy(True) image = image2 image.paste() image.killRoi() ip = image.getProcessor() # arrow ip.setColor(0x123558) arrowLength = int(arrowThickness * 2.5) arrowWidth = arrowThickness * 2 x1 = (w - arrowLength) / 2 x2 = x1 + arrowLength
# noise로 칠해진 이미지 생성 width = 1024 height = 1024 pixels = zeros('f', width * height) for i in xrange(len(pixels)): pixels[i] = random() fp = FloatProcessor(width, height, pixels, None) imp = ImagePlus("Random", fp) imp.show() # 직사각형 관심영역(ROI: Region of Interest)를 2로 채우기 fp = FloatProcessor(width, height, pixels, None) roi = Roi(400, 200, 400, 300) # Roi(int x, int y, int width, int height) fp.setRoi(roi) fp.setValue(2.0) fp.fill() imp2 = ImagePlus("Rectangle", fp) imp2.show() # Polygon ROI를 -3으로 채우기 fp = FloatProcessor(width, height, pixels, None) xs = [ 234, 174, 162, 102, 120, 123, 153, 177, 171, 60, 0, 18, 63, 132, 84, 129, 69, 174, 150, 183, 207, 198, 303, 231, 258, 234, 276, 327, 378, 312, 228, 225, 246, 282, 261, 252 ] ys = [
def makeCropUI(imp, images, tgtDir, panel=None, cropContinuationFn=None): """ imp: the ImagePlus to work on. images: the list of ImgLib2 images, one per frame, not original but already isotropic. (These are views that use a nearest neighbor interpolation using the calibration to scale to isotropy.) tgtDir: the target directory where e.g. CSV files will be stored, for ROI, features, pointmatches. panel: optional, a JPanel controlled by a GridBagLayout. cropContinuationFn: optional, a function to execute after cropping, which is given as arguments the original images, minC, maxC (both define a ROI), and the cropped images. """ independent = None == panel if not panel: panel = JPanel() panel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)) gb = GridBagLayout() gc = GBC() else: gb = panel.getLayout() # Constraints of the last component gc = gb.getConstraints(panel.getComponent(panel.getComponentCount() - 1)) # Horizontal line to separate prior UI components from crop UI gc.gridx = 0 gc.gridy += 1 gc.gridwidth = 4 gc.anchor = GBC.WEST gc.fill = GBC.HORIZONTAL sep = JSeparator() sep.setMinimumSize(Dimension(200, 10)) gb.setConstraints(sep, gc) panel.add(sep) # ROI UI header title = JLabel("ROI controls:") gc.gridy +=1 gc.anchor = GBC.WEST gc.gridwidth = 4 gb.setConstraints(title, gc) panel.add(title) # Column labels for the min and max coordinates gc.gridy += 1 gc.gridwidth = 1 for i, title in enumerate(["", "X", "Y", "Z"]): gc.gridx = i gc.anchor = GBC.CENTER label = JLabel(title) gb.setConstraints(label, gc) panel.add(label) textfields = [] rms = [] # Load stored ROI if any roi_path = path = os.path.join(tgtDir, "crop-roi.csv") if os.path.exists(roi_path): with open(roi_path, 'r') as csvfile: reader = csv.reader(csvfile, delimiter=',', quotechar="\"") reader.next() # header minC = map(int, reader.next()[1:]) maxC = map(int, reader.next()[1:]) # Place the ROI over the ImagePlus imp.setRoi(Roi(minC[0], minC[1], maxC[0] + 1 - minC[0], maxC[1] + 1 - minC[1])) else: # Use whole image dimensions minC = [0, 0, 0] maxC = [v -1 for v in Intervals.dimensionsAsLongArray(images[0])] # Text fields for the min and max coordinates for rowLabel, coords in izip(["min coords: ", "max coords: "], [minC, maxC]): gc.gridx = 0 gc.gridy += 1 label = JLabel(rowLabel) gb.setConstraints(label, gc) panel.add(label) for i in xrange(3): gc.gridx += 1 tf = JTextField(str(coords[i]), 10) gb.setConstraints(tf, gc) panel.add(tf) textfields.append(tf) listener = RoiMaker(imp, textfields, len(textfields) -1) rms.append(listener) tf.addKeyListener(listener) tf.addMouseWheelListener(listener) # Listen to changes in the ROI of imp rfl = RoiFieldListener(imp, textfields) Roi.addRoiListener(rfl) # ... and enable cleanup ImagePlus.addImageListener(FieldDisabler(rfl, rms)) # Functions for cropping images cropped = None cropped_imp = None def storeRoi(minC, maxC): if os.path.exists(roi_path): # Load ROI with open(path, 'r') as csvfile: reader = csv.reader(csvfile, delimiter=',', quotechar="\"") reader.next() # header same = True for a, b in izip(minC + maxC, map(int, reader.next()[1:] + reader.next()[1:])): if a != b: same = False # Invalidate any CSV files for features and pointmatches: different cropping for filename in os.listdir(tgtDir): if filename.endswith("features.csv") or filename.endswith("pointmatches.csv"): os.remove(os.path.join(tgtDir, filename)) break if same: return # Store the ROI as crop-roi.csv with open(roi_path, 'w') as csvfile: w = csv.writer(csvfile, delimiter=',', quotechar="\"", quoting=csv.QUOTE_NONNUMERIC) w.writerow(["coords", "x", "y", "z"]) w.writerow(["min"] + map(int, minC)) w.writerow(["max"] + map(int, maxC)) def crop(event): global cropped, cropped_imp coords = [int(float(tf.getText())) for tf in textfields] minC = [max(0, c) for c in coords[0:3]] maxC = [min(d -1, c) for d, c in izip(Intervals.dimensionsAsLongArray(images[0]), coords[3:6])] storeRoi(minC, maxC) print "ROI min and max coordinates" print minC print maxC cropped = [Views.zeroMin(Views.interval(img, minC, maxC)) for img in images] cropped_imp = showAsStack(cropped, title="cropped") cropped_imp.setDisplayRange(imp.getDisplayRangeMin(), imp.getDisplayRangeMax()) if cropContinuationFn: cropContinuationFn(images, minC, maxC, cropped, cropped_imp) # Buttons to create a ROI and to crop to ROI, # which when activated enables the fine registration buttons crop_button = JButton("Crop to ROI") crop_button.addActionListener(crop) gc.gridx = 0 gc.gridy += 1 gc.gridwidth = 4 gc.anchor = GBC.WEST buttons_panel = JPanel() buttons_panel.add(crop_button) gb.setConstraints(buttons_panel, gc) panel.add(buttons_panel) if independent: frame = JFrame("Crop by ROI") frame.getContentPane().add(panel) frame.pack() frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE) frame.addWindowListener(CloseControl(destroyables=rms + [rfl])) frame.setVisible(True) else: # Re-pack the JFrame parent = panel.getParent() while not isinstance(parent, JFrame) and parent is not None: parent = parent.getParent() if parent: frame = parent frame.pack() found = False for wl in frame.getWindowListeners(): if isinstance(wl, CloseControl): wl.addDestroyables(rms + [rfl]) found = True break if not found: frame.addWindowListener(CloseControl(destroyables=rms + [rfl])) frame.setVisible(True) return panel
#for hit in Hits_AfterNMS : print hit ## Stop time here (we dont benchmark display time) Stop = time.clock() Elapsed = Stop - Start # in seconds ListTime.append(Elapsed) ## Loop over final hits to generate ROI, result table... ### for hit in Hits_AfterNMS: if Bool_SearchRoi: # Add the offset of the search ROI hit['BBox'] = (hit['BBox'][0] + dX, hit['BBox'][1] + dY, hit['BBox'][2], hit['BBox'][3]) if add_roi: roi = Roi(*hit['BBox']) roi.setName(hit['TemplateName']) roi.setPosition(i + 1) # set slice position rm.add( None, roi, i + 1 ) # Trick to be able to set slice when less images than ROI. Here i is an digit index before the Roi Name if show_table: Xcorner, Ycorner = hit['BBox'][0], hit['BBox'][1] Xcenter, Ycenter = CornerToCenter(Xcorner, Ycorner, hit['BBox'][2], hit['BBox'][3]) Dico = { 'Image': ImName, 'Template': hit['TemplateName'], 'Xcorner': Xcorner,
options = NI.FILL_RAMP # Other choices: FILL_BLACK & FILL_WHITE # Now we create the image (An ij.ImagePlus object) image = NI.createImage(title, width, height, n_slices, bit_depth, options) # We'll generate the code require to place a ROI right # in the middle of our image! Here is how: from ij.gui import Roi # We define the ROI properties rec_width = 100 # The width of our rectangular ROI rec_height = 100 # The height of our rectangular ROI # We create the ROI (A ij.gui.Roi object) my_rectangle = Roi( width / 2 - rec_width / 2, # 1st argument: x-positioning height / 2 - rec_width / 2, # 2nd argument: y-positioning rec_width, # 3rd argument: ROI width rec_height # 4th argument: ROI height ) # Now we just need to associate the ROI with our image. Did # we say an image is an ImagePlus? Then, we'll look which # methods in the ImagePlus class allow us to assigns our # ROI with our image. Here is what we found: image.setRoi(my_rectangle) # Found it? Great! Then we'll proudly show everything! image.show()