def __init__(self, axis, one_axis, two_axis, corr_axis, imgSrc, rootPath, figure=None, load_callback=None): """initialization function which will plot the imagematrix passed in and set the bounds according the bounds specified by extent keywords) axis)the matplotlib axis to plot the image into one_axis) the matplotlib axis to plot the cutout of the fixed point when using the corresponding point functionality two_axis) the matplotlib axis to plot the cutout of the point that should be moved when using the corresponding point functionality corr_axis) the matplotlib axis to plot out the matrix of correlation values found when using the corresponding point functionality imagefile) a string with the path of the file which contains the full resolution image that should be used when calculating the corresponding point funcationality currently the reading of the image is using PIL so the path specified must be an image which is PIL readable imagematrix) a numpy 2d matrix containing a low resolution varsion of the full resolution image, for the purposes of faster plotting/memory management extent) a list [minx,maxx,miny,maxy] of the corners of the image. This will specify the scale of the image, and allow the corresponding point functionality to specify how much the movable point should be shifted in the units given by this extent. If omitted the units will be in pixels and extent will default to [0,width,height,0]. """ #define the attributes of this class self.axis = axis self.one_axis = one_axis self.two_axis = two_axis self.corr_axis = corr_axis #initialize the images for the various subplots as None self.oneImage = None self.twoImage = None self.corrImage = None self.imgSrc = imgSrc self.imgCollection = ImageCollection(rootpath=rootPath, imageSource=imgSrc, axis=self.axis) (x, y) = imgSrc.get_xy() bbox = imgSrc.calc_bbox(x, y) self.imgCollection.set_view_home() self.imgCollection.load_image_collection(load_callback=load_callback) self.maxvalue = 512 self.currentPosLine2D = Line2D([x], [y], marker='o', markersize=7, markeredgewidth=1.5, markeredgecolor='r', zorder=100) self.axis.add_line(self.currentPosLine2D) self.axis.set_title('Mosaic Image') self.fig = figure self.update_pos_cursor()
def run(self): full_executor = ThreadPoolExecutor(max_workers=self.max_workers) # Split available worker threads between training data preparation and post # processing (if possible). if self.max_workers > 1: workers = min(self.max_workers - 1, round(self.max_workers * self.train_workers_ratio)) train_executor = ThreadPoolExecutor(max_workers=workers) post_executor = ThreadPoolExecutor(max_workers=self.max_workers - workers) else: train_executor = full_executor post_executor = full_executor images = ImageCollection(self.images, executor=full_executor) images.prune_corrupt_images() total_images = len(images) if total_images == 0: print('No image files to process.') return elif total_images < self.clusters: print( '{} clusters were requested but only {} images are there. Reducing clusters to {}.' .format(self.clusters, total_images, total_images)) self.clusters = total_images if self.clusters > 1: clusters = images.make_clusters(number=self.clusters) else: clusters = [images] detector = AutoencoderSaliencyDetector(self.patch_size, stride=self.detector_stride, hidden=self.latent_size) jobs = [] for i, cluster in enumerate(clusters): cluster.set_executor(train_executor) print("Cluster {} of {}".format(i + 1, self.clusters)) threshold = self.process_cluster(detector, cluster) jobs.extend([ post_executor.submit(self.postprocess_map, image, threshold) for image in cluster ]) wait(jobs)
def __init__(self,axis,one_axis,two_axis,corr_axis,imgSrc,rootPath): """initialization function which will plot the imagematrix passed in and set the bounds according the bounds specified by extent keywords) axis)the matplotlib axis to plot the image into one_axis) the matplotlib axis to plot the cutout of the fixed point when using the corresponding point functionality two_axis) the matplotlib axis to plot the cutout of the point that should be moved when using the corresponding point functionality corr_axis) the matplotlib axis to plot out the matrix of correlation values found when using the corresponding point functionality imagefile) a string with the path of the file which contains the full resolution image that should be used when calculating the corresponding point funcationality currently the reading of the image is using PIL so the path specified must be an image which is PIL readable imagematrix) a numpy 2d matrix containing a low resolution varsion of the full resolution image, for the purposes of faster plotting/memory management extent) a list [minx,maxx,miny,maxy] of the corners of the image. This will specify the scale of the image, and allow the corresponding point functionality to specify how much the movable point should be shifted in the units given by this extent. If omitted the units will be in pixels and extent will default to [0,width,height,0]. """ #define the attributes of this class self.axis=axis self.one_axis=one_axis self.two_axis=two_axis self.corr_axis=corr_axis #initialize the images for the various subplots as None self.oneImage=None self.twoImage=None self.corrImage=None self.imgCollection=ImageCollection(rootpath=rootPath,imageSource=imgSrc,axis=self.axis) (x,y)=imgSrc.get_xy() bbox=imgSrc.calc_bbox(x,y) self.imgCollection.set_view_home(bbox) self.imgCollection.loadImageCollection() self.maxvalue=255 imgSrc.set_channel('Violet') imgSrc.set_exposure(250) self.axis.set_title('Mosaic Image')
class MosaicImage(): """A class for storing the a large mosaic imagein a matplotlib axis. Also contains functions for finding corresponding points in the larger mosaic image, and plotting informative graphs about that process in different axis""" def __init__(self,axis,one_axis,two_axis,corr_axis,imgSrc,rootPath): """initialization function which will plot the imagematrix passed in and set the bounds according the bounds specified by extent keywords) axis)the matplotlib axis to plot the image into one_axis) the matplotlib axis to plot the cutout of the fixed point when using the corresponding point functionality two_axis) the matplotlib axis to plot the cutout of the point that should be moved when using the corresponding point functionality corr_axis) the matplotlib axis to plot out the matrix of correlation values found when using the corresponding point functionality imagefile) a string with the path of the file which contains the full resolution image that should be used when calculating the corresponding point funcationality currently the reading of the image is using PIL so the path specified must be an image which is PIL readable imagematrix) a numpy 2d matrix containing a low resolution varsion of the full resolution image, for the purposes of faster plotting/memory management extent) a list [minx,maxx,miny,maxy] of the corners of the image. This will specify the scale of the image, and allow the corresponding point functionality to specify how much the movable point should be shifted in the units given by this extent. If omitted the units will be in pixels and extent will default to [0,width,height,0]. """ #define the attributes of this class self.axis=axis self.one_axis=one_axis self.two_axis=two_axis self.corr_axis=corr_axis #initialize the images for the various subplots as None self.oneImage=None self.twoImage=None self.corrImage=None self.imgCollection=ImageCollection(rootpath=rootPath,imageSource=imgSrc,axis=self.axis) (x,y)=imgSrc.get_xy() bbox=imgSrc.calc_bbox(x,y) self.imgCollection.set_view_home(bbox) self.imgCollection.loadImageCollection() self.maxvalue=255 imgSrc.set_channel('Violet') imgSrc.set_exposure(250) self.axis.set_title('Mosaic Image') # def paintImage(self): # """plots self.imagematrix in self.axis using self.extent to define the boundaries""" # self.Image=self.axis.imshow(self.imagematrix,cmap='gray',extent=self.extent) # (minval,maxval)=self.Image.get_clim() # self.maxvalue=maxval # #self.axis.canvas.get_toolbar().slider.SetSelection(minval,self.maxvalue) # self.axis.autoscale(False) # self.axis.set_xlabel('X Position (pixels)') # self.axis.set_ylabel('Y Position (pixels)') # self.Image.set_clim(0,25000) def set_maxval(self,maxvalue): """set the maximum value in the image colormap""" self.maxvalue=maxvalue; self.repaint() def set_view_home(self): self.imgCollection.set_view_home() def repaint(self): """sets the new clim for the Image using self.maxvalue as the new maximum value""" #(minval,maxval)=self.Image.get_clim() self.imgCollection.update_clim(max=self.maxvalue) if self.oneImage!=None: self.oneImage.set_clim(0,self.maxvalue) if self.twoImage!=None: self.twoImage.set_clim(0,self.maxvalue) def paintImageCenter(self,cut,theaxis,xc=0,yc=0,skip=1,cmap='gray',scale=1): """paints an image and redefines the coordinates such that 0,0 is at the center keywords cut)the 2d numpy matrix with the image data the axis)the matplotlib axis to plot it in skip)the factor to rescale the axis by so that 1 entry in the cut, is equal to skip units on the axis (default=1) cmap)the colormap designation to use for the plot (default 'gray') """ theaxis.cla() (h,w)=cut.shape dh=skip*1.0*(h-1)/2 dw=skip*1.0*(w-1)/2 dh=dh*scale; dw=dw*scale; left=xc-dw right=xc+dw top=yc-dh bot=yc+dh ext=[left,right,bot,top] image=theaxis.imshow(cut,cmap=cmap,extent=ext) theaxis.set_xlim(left=xc-dw,right=xc+dw) theaxis.set_ylim(bottom=yc+dh,top=yc-dh) theaxis.hold(True) return image def updateImageCenter(self,cut,theimage,theaxis,xc=0,yc=0,skip=1,scale=1): """updates an image with a new image keywords cut) the 2d numpy matrix with the image data theimage) the image to update theaxis) the axis that the image is in skip)the factor to rescale the axis by so that 1 entry in the cut, is equal to skip units on the axis (default=1) """ (h,w)=cut.shape[0:2] dh=skip*1.0*(h-1)/2 dw=skip*1.0*(w-1)/2 dh=dh*scale; dw=dw*scale; theimage.set_array(cut) left=xc-dw right=xc+dw theaxis.set_xlim(left=xc-dw,right=xc+dw) top=yc-dh bot=yc+dh theaxis.set_ylim(top=yc-dh,bottom=yc+dh) ext=[left,right,bot,top] theimage.set_extent(ext) def paintImageOne(self,cut,xy=(0,0),dxy_pix=(0,0),window=0): """paints an image in the self.one_axis axis, plotting a box of size 2*window+1 around that point keywords cut) the 2d numpy matrix with the image data dxy_pix) the center of the box to be drawn given as an (x,y) tuple window)the size of the box, where the height is 2*window+1 """ (xc,yc)=xy (dx,dy)=dxy_pix pixsize=self.imgCollection.get_pixel_size() dx=dx*pixsize; dy=dy*pixsize; #the size of the cutout box in microns boxsize_um=(2*window+1)*pixsize; #if there is no image yet, create one and a box if self.oneImage==None: self.oneImage=self.paintImageCenter(cut, self.one_axis,xc=xc,yc=yc,scale=pixsize) self.oneBox=CenterRectangle((xc+dx,yc+dy),width=50,height=50,edgecolor='r',linewidth=1.5,fill=False) self.one_axis.add_patch(self.oneBox) self.one_axis_center=Line2D([xc],[yc],marker='+',markersize=7,markeredgewidth=1.5,markeredgecolor='r') self.one_axis.add_line(self.one_axis_center) self.one_axis.set_title('Point 1') self.one_axis.set_ylabel('Microns') self.one_axis.autoscale(False) self.oneImage.set_clim(0,self.maxvalue) #if there is an image update it and the self.oneBox else: self.updateImageCenter(cut, self.oneImage, self.one_axis,xc=xc,yc=yc,scale=pixsize) self.oneBox.set_center((dx+xc,dy+yc)) self.oneBox.set_height(boxsize_um) self.oneBox.set_width(boxsize_um) self.one_axis_center.set_xdata([xc]) self.one_axis_center.set_ydata([yc]) def paintImageTwo(self,cut,xy=(0,0),xyp=None,pointcolor='r'): """paints an image in the self.two_axis, with 0,0 at the center cut=the 2d numpy""" #create or update appropriately pixsize=self.imgCollection.get_pixel_size() (xc,yc)=xy if xyp is not None: (xp,yp)=xyp else: (xp,yp)=xy if self.twoImage==None: self.twoImage=self.paintImageCenter(cut, self.two_axis,xc=xc,yc=yc,scale=pixsize) self.two_axis_center=Line2D([xp],[yp],marker='+',markersize=7,markeredgewidth=1.5,markeredgecolor=pointcolor) self.two_axis.add_line(self.two_axis_center) self.two_axis.set_title('Point 2') self.two_axis.set_ylabel('Pixels from point 2') self.two_axis.autoscale(False) self.twoImage.set_clim(0,self.maxvalue) else: self.updateImageCenter(cut, self.twoImage, self.two_axis,xc=xc,yc=yc,scale=pixsize) self.two_axis_center.set_xdata([xp]) self.two_axis_center.set_ydata([yp]) def paintCorrImage(self,corrmat,dxy_pix,skip): """paints an image in the self.corr_axis, with 0,0 at the center and rescaled by skip, plotting a point at dxy_pix keywords) corrmat) the 2d numpy matrix with the image data dxy_pix) the offset in pixels from the center of the image to plot the point skip) the factor to rescale the axis by, so that when corrmat was produced by mycorrelate2d with a certain skip value, the axis will be in units of pixels """ #unpack the values (dx,dy)=dxy_pix #update or create new if self.corrImage==None: self.corrImage=self.paintImageCenter(corrmat, self.corr_axis,skip=skip,cmap='jet') self.maxcorrPoint,=self.corr_axis.plot(dx,dy,'ro') self.colorbar=self.corr_axis.figure.colorbar(self.corrImage,shrink=.9) self.corr_axis.set_title('Cross Correlation') self.corr_axis.set_ylabel('Pixels shifted') else: self.updateImageCenter(corrmat, self.corrImage, self.corr_axis,skip=skip) self.maxcorrPoint.set_data(dx,dy) #hard code the correlation maximum at .5 self.corrImage.set_clim(0,.5) def cutout_window(self,x,y,window): """returns a cutout of the original image at a certain location and size keywords) x)x position in microns y)y position in microns window) size of the patch to cutout, will cutout +/- window in both vertical and horizontal dimensions note.. behavior not well specified at edges, may crash function uses PIL to read in image and crop it appropriately returns) cut: a 2d numpy matrix containing the removed patch """ box=Rectangle(x-window,x+window,y-window,y+window) return self.imgCollection.get_cutout(box) def cross_correlate_two_to_one(self,xy1,xy2,window=60,delta=40,skip=3): """take two points in the image, and calculate the 2d cross correlation function of the image around those two points keywords) xy1) a (x,y) tuple specifying point 1, the point that should be fixed xy2) a (x,y) tuple specifiying point 2, the point that should be moved window) the size of the patch to cutout (+/- window around the points) for calculating the correlation (default = 100 um) delta) the size of the maximal shift +/- delta from no shift to calculate skip) the number of integer pixels to skip over when calculating the correlation returns (one_cut,two_cut,corrmat) one_cut) the patch cutout around point 1 two_cut) the patch cutout around point 2 corrmat) the matrix of correlation values measured with 0,0 being a shift of -delta,-delta """ (x1,y1)=xy1 (x2,y2)=xy2 one_cut=self.cutout_window(x1,y1,window+delta) two_cut=self.cutout_window(x2,y2,window) #return (target_cut,source_cut,mycorrelate2d(target_cut,source_cut,mode='valid')) return (one_cut,two_cut,mycorrelate2d(one_cut,two_cut,skip)) def align_by_correlation(self,xy1,xy2,window=60,delta=40,skip=3): """take two points in the image, and calculate the 2d cross correlation function of the image around those two points plots the results in the appropriate axis, and returns the shift which aligns the two points given in microns keywords) xy1) a (x,y) tuple specifying point 1, the point that should be fixed xy2) a (x,y) tuple specifiying point 2, the point that should be moved window) the size of the patch to cutout (+/- window around the points) for calculating the correlation (default = 100 pixels) delta) the size of the maximal shift +/- delta from no shift to calculate skip) the number of integer pixels to skip over when calculating the correlation returns) (maxC,dxy_um) maxC)the maximal correlation measured dxy_um) the (x,y) tuple which contains the shift in microns necessary to align point xy2 with point xy1 """ pixsize=self.imgCollection.get_pixel_size() #calculate the cutout patches and the correlation matrix (one_cut,two_cut,corrmat)=self.cross_correlate_two_to_one(xy1,xy2,window,delta,skip) #find the peak of the matrix maxind=corrmat.argmax() (h,w)=corrmat.shape #determine the indices of that peak (max_i,max_j)=np.unravel_index(maxind,corrmat.shape) #calculate the shift for that index in pixels dy_pix=int((max_i-(h/2))*skip) dx_pix=int((max_j-(w/2))*skip) #convert those indices into microns dy_um=dy_pix*pixsize dx_um=dx_pix*pixsize #pack up the shifts into tuples dxy_pix=(dx_pix,dy_pix) dxy_um=(dx_um,dy_um) #calculate what the maximal correlation was corrval=corrmat.max() print "(correlation,(dx,dy))=" print (corrval,dxy_pix) #paint the patch around the first point in its axis, with a box of size of the two_cut centered around where we found it self.paintImageOne(one_cut,xy=xy1,dxy_pix=dxy_pix, window=window) #paint the patch around the second point in its axis self.paintImageTwo(two_cut,xy=xy2) #paint the correlation matrix in its axis self.paintCorrImage(corrmat, dxy_pix,skip) return (corrmat.max(),dxy_um) def explore_match(self,img1, kp1,img2,kp2, status = None, H = None): h1, w1 = img1.shape[:2] h2, w2 = img2.shape[:2] vis = np.zeros((max(h1, h2), w1+w2), np.uint8) vis[:h1, :w1] = img1 vis[:h2, w1:w1+w2] = img2 vis = cv2.cvtColor(vis, cv2.COLOR_GRAY2BGR) if H is not None: corners = np.float32([[0, 0], [w1, 0], [w1, h1], [0, h1]]) corners = np.int32( cv2.perspectiveTransform(corners.reshape(1, -1, 2), H).reshape(-1, 2) + (w1, 0) ) cv2.polylines(vis, [corners], True, (255, 255, 255)) if status is None: status = np.ones(len(kp1), np.bool_) p1 = np.int32([kpp.pt for kpp in kp1]) p2 = np.int32([kpp.pt for kpp in kp2]) + (w1, 0) green = (0, 255, 0) red = (0, 0, 255) white = (255, 255, 255) kp_color = (51, 103, 236) for (x1, y1), (x2, y2), inlier in zip(p1, p2, status): if inlier: col = green cv2.circle(vis, (x1, y1), 2, col, -1) cv2.circle(vis, (x2, y2), 2, col, -1) else: col = red r = 2 thickness = 3 cv2.line(vis, (x1-r, y1-r), (x1+r, y1+r), col, thickness) cv2.line(vis, (x1-r, y1+r), (x1+r, y1-r), col, thickness) cv2.line(vis, (x2-r, y2-r), (x2+r, y2+r), col, thickness) cv2.line(vis, (x2-r, y2+r), (x2+r, y2-r), col, thickness) vis0 = vis.copy() for (x1, y1), (x2, y2), inlier in zip(p1, p2, status): if inlier: cv2.line(vis, (x1, y1), (x2, y2), green) else: cv2.line(vis, (x1, y1), (x2, y2), red) return vis def align_by_sift(self,xy1,xy2,window=70): """take two points in the image, and calculate SIFT features image around those two points cutting out size window keywords) xy1) a (x,y) tuple specifying point 1, the point that should be fixed xy2) a (x,y) tuple specifiying point 2, the point that should be moved window) the size of the patch to cutout (+/- window around the points) for calculating the correlation (default = 70 um) returns) (maxC,dxy_um) maxC)the maximal correlation measured dxy_um) the (x,y) tuple which contains the shift in microns necessary to align point xy2 with point xy1 """ print "starting align by sift" pixsize=self.imgCollection.get_pixel_size() #cutout the images around the two points (x1,y1)=xy1 (x2,y2)=xy2 one_cut=self.cutout_window(x1,y1,window) two_cut=self.cutout_window(x2,y2,window) #one_cuta=np.minimum(one_cut*256.0/self.maxvalue,255.0).astype(np.uint8) #two_cuta=np.minimum(two_cut*256.0/self.maxvalue,255.0).astype(np.uint8) one_cuta=cv2.equalizeHist(one_cut) two_cuta=cv2.equalizeHist(two_cut) sift = cv2.SIFT(nfeatures=500,contrastThreshold=.2) kp1, des1 = sift.detectAndCompute(one_cuta,None) kp2, des2 = sift.detectAndCompute(two_cuta,None) print "features1:%d"%len(kp1) print "features2:%d"%len(kp2) img_one = cv2.drawKeypoints(one_cuta,kp1) img_two = cv2.drawKeypoints(two_cuta,kp2) #image2=self.two_axis.imshow(img_two) # FLANN parameters FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5) search_params = dict(checks=50) # or pass empty dictionary flann = cv2.FlannBasedMatcher(index_params,search_params) matches = flann.knnMatch(des1,des2,k=2) # Need to draw only good matches, so create a mask matchesMask = np.zeros(len(matches)) kp1matchIdx=[] kp2matchIdx=[] # ratio test as per Lowe's paper for i,(m,n) in enumerate(matches): if m.distance < 0.9*n.distance: kp1matchIdx.append(m.queryIdx) kp2matchIdx.append(m.trainIdx) p1 = np.array([kp1[i].pt for i in kp1matchIdx]) p2 = np.array([kp2[i].pt for i in kp2matchIdx]) # p1c = [pt-np.array[window,window] for pt in p1] # p2c = [pt-np.array[window,window] for pt in p2] kp1m = [kp1[i] for i in kp1matchIdx] kp2m = [kp2[i] for i in kp2matchIdx] #print "kp1matchshape" #print matchesMask #print len(kp1match) #print len(kp2match) #draw_params = dict(matchColor = (0,255,0), # singlePointColor = (255,0,0), # matchesMask = matchesMask, # flags = 0) #img3 = cv2.drawMatches(one_cut,kp1,two_cut,kp2,matches,None,**draw_params) transModel=ransac.RigidModel() bestModel,bestInlierIdx=ransac.ransac(p1,p2,transModel,2,300,20.0,3,debug=True,return_all=True) if bestModel is not None: the_center = np.array([[one_cut.shape[0]/2,one_cut.shape[1]/2]]) trans_center=transModel.transform_points(the_center,bestModel) offset=the_center-trans_center xc=x2+offset[0,0]*pixsize yc=y2-offset[0,1]*pixsize #newcenter=Line2D([trans_center[0,0]+one_cut.shape[1]],[trans_center[0,1]],marker='+',markersize=7,markeredgewidth=1.5,markeredgecolor='r') #oldcenter=Line2D([the_center[0,0]],[the_center[0,1]],marker='+',markersize=7,markeredgewidth=1.5,markeredgecolor='r') dx_um=-bestModel.t[0]*pixsize dy_um=-bestModel.t[1]*pixsize print "matches:%d"%len(kp1matchIdx) print "inliers:%d"%len(bestInlierIdx) print ('translation',bestModel.t) print ('rotation',bestModel.R) mask = np.zeros(len(p1), np.bool_) mask[bestInlierIdx]=1 #img3 = self.explore_match(one_cuta,kp1m,two_cuta,kp2m,mask) #self.corr_axis.cla() #self.corr_axis.imshow(img3) #self.corr_axis.add_line(newcenter) #self.corr_axis.add_line(oldcenter) #self.repaint() #self.paintImageOne(img_one,xy=xy1) #paint the patch around the second point in its axis #self.paintImageTwo(img_two,xy=xy2) #paint the correlation matrix in its axis #self.paintCorrImage(corrmat, dxy_pix,skip) print (dx_um,dy_um) self.paintImageOne(img_one,xy=xy1) self.paintImageTwo(img_two,xy=xy2,xyp=(x2-dx_um,y2-dy_um)) return ((dx_um,dy_um),len(bestInlierIdx)) else: self.paintImageOne(img_one,xy=xy1) self.paintImageTwo(img_two,xy=xy2) return ((0.0,0.0),0) def paintPointsOneTwo(self,xy1,xy2,window): (x1,y1)=xy1 (x2,y2)=xy2 print "getting p1 window at ",x1,y1 print "getting p2 window at ",x2,y2 one_cut=self.cutout_window(x1,y1,window) two_cut=self.cutout_window(x2,y2,window) self.paintImageOne(one_cut,xy1) #paint the patch around the second point in its axis self.paintImageTwo(two_cut,xy2) def make_preview_stack(self,xpos,ypos,width,height,directory): print "make a preview stack" hw_pix=int(round(width*.5/self.orig_um_per_pix)) hh_pix=int(round(height*.5/self.orig_um_per_pix)) queue = Queue.Queue() #spawn a pool of threads, and pass them queue instance for i in range(4): t = ImageCutThread(queue) t.setDaemon(True) t.start() for i in range(len(self.mosaicArray.xpos)): (cx_pix,cy_pix)=self.convert_pos_to_ind(xpos[i],ypos[i]) rect=[cx_pix-hw_pix,cy_pix-hh_pix,cx_pix+hw_pix,cy_pix+hh_pix] queue.put((self.imagefile,rect,i)) queue.join()
class MosaicImage(): """A class for storing the a large mosaic imagein a matplotlib axis. Also contains functions for finding corresponding points in the larger mosaic image, and plotting informative graphs about that process in different axis""" def __init__(self, axis, one_axis, two_axis, corr_axis, imgSrc, rootPath, figure=None, load_callback=None): """initialization function which will plot the imagematrix passed in and set the bounds according the bounds specified by extent keywords) axis)the matplotlib axis to plot the image into one_axis) the matplotlib axis to plot the cutout of the fixed point when using the corresponding point functionality two_axis) the matplotlib axis to plot the cutout of the point that should be moved when using the corresponding point functionality corr_axis) the matplotlib axis to plot out the matrix of correlation values found when using the corresponding point functionality imagefile) a string with the path of the file which contains the full resolution image that should be used when calculating the corresponding point funcationality currently the reading of the image is using PIL so the path specified must be an image which is PIL readable imagematrix) a numpy 2d matrix containing a low resolution varsion of the full resolution image, for the purposes of faster plotting/memory management extent) a list [minx,maxx,miny,maxy] of the corners of the image. This will specify the scale of the image, and allow the corresponding point functionality to specify how much the movable point should be shifted in the units given by this extent. If omitted the units will be in pixels and extent will default to [0,width,height,0]. """ #define the attributes of this class self.axis = axis self.one_axis = one_axis self.two_axis = two_axis self.corr_axis = corr_axis #initialize the images for the various subplots as None self.oneImage = None self.twoImage = None self.corrImage = None self.imgSrc = imgSrc self.imgCollection = ImageCollection(rootpath=rootPath, imageSource=imgSrc, axis=self.axis) (x, y) = imgSrc.get_xy() bbox = imgSrc.calc_bbox(x, y) self.imgCollection.set_view_home() self.imgCollection.load_image_collection(load_callback=load_callback) self.maxvalue = 512 self.currentPosLine2D = Line2D([x], [y], marker='o', markersize=7, markeredgewidth=1.5, markeredgecolor='r', zorder=100) self.axis.add_line(self.currentPosLine2D) self.axis.set_title('Mosaic Image') self.fig = figure self.update_pos_cursor() # def paintImage(self): # """plots self.imagematrix in self.axis using self.extent to define the boundaries""" # self.Image=self.axis.imshow(self.imagematrix,cmap='gray',extent=self.extent) # (minval,maxval)=self.Image.get_clim() # self.maxvalue=maxval # #self.axis.canvas.get_toolbar().slider.SetSelection(minval,self.maxvalue) # self.axis.autoscale(False) # self.axis.set_xlabel('X Position (pixels)') # self.axis.set_ylabel('Y Position (pixels)') # self.Image.set_clim(0,25000) def update_pos_cursor(self): x, y = self.imgSrc.get_xy() self.currentPosLine2D.set_xdata([x]) self.currentPosLine2D.set_ydata([y]) self.axis.draw_artist(self.currentPosLine2D) self.fig.canvas.draw() #self.cursor_timer = threading.Timer(1, self.update_pos_cursor) #self.cursor_timer.start() def set_maxval(self, maxvalue): """set the maximum value in the image colormap""" self.maxvalue = maxvalue self.repaint() def set_view_home(self): self.imgCollection.set_view_home() def crop_to_images(self, evt): self.imgCollection.crop_to_images(evt) def repaint(self): """sets the new clim for the Image using self.maxvalue as the new maximum value""" #(minval,maxval)=self.Image.get_clim() self.imgCollection.update_clim(max=self.maxvalue) if self.oneImage != None: self.oneImage.set_clim(0, self.maxvalue) if self.twoImage != None: self.twoImage.set_clim(0, self.maxvalue) def paintImageCenter(self, cut, theaxis, xc=0, yc=0, skip=1, cmap='gray', scale=1, interpolation='nearest'): """paints an image and redefines the coordinates such that 0,0 is at the center keywords cut)the 2d numpy matrix with the image data the axis)the matplotlib axis to plot it in skip)the factor to rescale the axis by so that 1 entry in the cut, is equal to skip units on the axis (default=1) cmap)the colormap designation to use for the plot (default 'gray') """ theaxis.cla() (h, w) = cut.shape dh = skip * 1.0 * (h - 1) / 2 dw = skip * 1.0 * (w - 1) / 2 dh = dh * scale dw = dw * scale left = xc - dw right = xc + dw top = yc - dh bot = yc + dh ext = [left, right, bot, top] image = theaxis.imshow(cut, cmap=cmap, extent=ext, interpolation=interpolation) theaxis.set_xlim(left=xc - dw, right=xc + dw) theaxis.set_ylim(bottom=yc + dh, top=yc - dh) theaxis.hold(True) return image def updateImageCenter(self, cut, theimage, theaxis, xc=0, yc=0, skip=1, scale=1): """updates an image with a new image keywords cut) the 2d numpy matrix with the image data theimage) the image to update theaxis) the axis that the image is in skip)the factor to rescale the axis by so that 1 entry in the cut, is equal to skip units on the axis (default=1) """ (h, w) = cut.shape[0:2] dh = skip * 1.0 * (h - 1) / 2 dw = skip * 1.0 * (w - 1) / 2 dh = dh * scale dw = dw * scale theimage.set_array(cut) left = xc - dw right = xc + dw theaxis.set_xlim(left=xc - dw, right=xc + dw) top = yc - dh bot = yc + dh theaxis.set_ylim(top=yc - dh, bottom=yc + dh) ext = [left, right, bot, top] theimage.set_extent(ext) def paintImageOne(self, cut, xy=(0, 0), dxy_pix=(0, 0), window=0): """paints an image in the self.one_axis axis, plotting a box of size 2*window+1 around that point keywords cut) the 2d numpy matrix with the image data dxy_pix) the center of the box to be drawn given as an (x,y) tuple window)the size of the box, where the height is 2*window+1 """ (xc, yc) = xy (dx, dy) = dxy_pix pixsize = self.imgCollection.get_pixel_size() dx = dx * pixsize dy = dy * pixsize #the size of the cutout box in microns boxsize_um = (2 * window + 1) * pixsize #if there is no image yet, create one and a box if self.oneImage == None: self.oneImage = self.paintImageCenter(cut, self.one_axis, xc=xc, yc=yc, scale=pixsize) self.oneBox = CenterRectangle((xc + dx, yc + dy), width=50, height=50, edgecolor='r', linewidth=1.5, fill=False) self.one_axis.add_patch(self.oneBox) self.one_axis_center = Line2D([xc], [yc], marker='+', markersize=7, markeredgewidth=1.5, markeredgecolor='r') self.one_axis.add_line(self.one_axis_center) self.one_axis.set_title('Point 1') self.one_axis.set_ylabel('Microns') self.one_axis.autoscale(False) self.oneImage.set_clim(0, self.maxvalue) #if there is an image update it and the self.oneBox else: self.updateImageCenter(cut, self.oneImage, self.one_axis, xc=xc, yc=yc, scale=pixsize) self.oneBox.set_center((dx + xc, dy + yc)) self.oneBox.set_height(boxsize_um) self.oneBox.set_width(boxsize_um) self.one_axis_center.set_xdata([xc]) self.one_axis_center.set_ydata([yc]) def paintImageTwo(self, cut, xy=(0, 0), xyp=None, pointcolor='r'): """paints an image in the self.two_axis, with 0,0 at the center cut=the 2d numpy""" #create or update appropriately pixsize = self.imgCollection.get_pixel_size() (xc, yc) = xy if xyp is not None: (xp, yp) = xyp else: (xp, yp) = xy if self.twoImage == None: self.twoImage = self.paintImageCenter(cut, self.two_axis, xc=xc, yc=yc, scale=pixsize) self.two_axis_center = Line2D([xp], [yp], marker='+', markersize=7, markeredgewidth=1.5, markeredgecolor=pointcolor) self.two_axis.add_line(self.two_axis_center) self.two_axis.set_title('Point 2') self.two_axis.set_ylabel('Pixels from point 2') self.two_axis.autoscale(False) self.twoImage.set_clim(0, self.maxvalue) else: self.updateImageCenter(cut, self.twoImage, self.two_axis, xc=xc, yc=yc, scale=pixsize) self.two_axis_center.set_xdata([xp]) self.two_axis_center.set_ydata([yp]) def paintCorrImage(self, corrmat, dxy_pix, skip=1): """paints an image in the self.corr_axis, with 0,0 at the center and rescaled by skip, plotting a point at dxy_pix keywords) corrmat) the 2d numpy matrix with the image data dxy_pix) the offset in pixels from the center of the image to plot the point skip) the factor to rescale the axis by, so that when corrmat was produced by mycorrelate2d with a certain skip value, the axis will be in units of pixels """ #unpack the values (dx, dy) = dxy_pix #update or create new if self.corrImage == None: self.corrImage = self.paintImageCenter(corrmat, self.corr_axis, skip=skip, cmap='jet') self.maxcorrPoint, = self.corr_axis.plot(dx, dy, 'ro') self.colorbar = self.corr_axis.figure.colorbar( self.corrImage, shrink=.9, ticks=[0.2, 0.4, 0.6, 0.8, 1.0]) self.corrImage.set_clim(vmin=0.0, vmax=1.0) self.corr_axis.set_title('Cross Correlation') self.corr_axis.set_ylabel('Pixels shifted') else: self.updateImageCenter(corrmat, self.corrImage, self.corr_axis, skip=skip) self.maxcorrPoint.set_data(dx, dy) #hard code the correlation maximum at .5 #self.corrImage.set_clim(0,.5) def cutout_window(self, x, y, window): """returns a cutout of the original image at a certain location and size keywords) x)x position in microns y)y position in microns window) size of the patch to cutout (microns), will cutout +/- window in both vertical and horizontal dimensions note.. behavior not well specified at edges, may crash function uses PIL to read in image and crop it appropriately returns) cut: a 2d numpy matrix containing the removed patch """ box = Rectangle(x - window, x + window, y - window, y + window) return self.imgCollection.get_cutout(box) def cross_correlate_two_to_one(self, xy1, xy2, window=60, delta=40, skip=3): """take two points in the image, and calculate the 2d cross correlation function of the image around those two points keywords) xy1) a (x,y) tuple specifying point 1, the point that should be fixed xy2) a (x,y) tuple specifiying point 2, the point that should be moved window) the size of the patch to cutout (+/- window around the points) for calculating the correlation (default = 100 um) delta) the size of the maximal shift +/- delta from no shift to calculate skip) the number of integer pixels to skip over when calculating the correlation returns (one_cut,two_cut,corrmat) one_cut) the patch cutout around point 1 two_cut) the patch cutout around point 2 corrmat) the matrix of correlation values measured with 0,0 being a shift of -delta,-delta """ (x1, y1) = xy1 (x2, y2) = xy2 one_cut = self.cutout_window(x1, y1, window + delta) two_cut = self.cutout_window(x2, y2, window) #return (target_cut,source_cut,mycorrelate2d(target_cut,source_cut,mode='valid')) return (one_cut, two_cut, mycorrelate2d(one_cut, two_cut, skip)) def _cross_correlation_shift(self, fixed_cutout, to_shift_cutout): ''' :param one_cut: cutout around point 1 :param two_cut: cutout around point 2 :return: corrmatt, corval, dx_pix, dy_pix ''' src_image = np.array(fixed_cutout, dtype=np.complex128, copy=False) target_image = np.array(to_shift_cutout, dtype=np.complex128, copy=False) f1 = np.std(fixed_cutout) f2 = np.std(to_shift_cutout) normfactor = f1 * f2 * fixed_cutout.size src_freq = np.fft.fftn(src_image) target_freq = np.fft.fftn(target_image) shape = src_freq.shape image_product = src_freq * target_freq.conj() corrmat = np.fft.ifftn(image_product) corrmat = np.fft.fftshift(corrmat.real / normfactor) #find the peak of the matrix maxind = corrmat.argmax() (h, w) = corrmat.shape #determine the indices of that peak (max_i, max_j) = np.unravel_index(maxind, corrmat.shape) #calculate the shift for that index in pixels dy_pix = int((max_i - (h / 2))) dx_pix = int((max_j - (w / 2))) #calculate what the maximal correlation was corrval = corrmat.max() return corrmat, corrval, dx_pix, dy_pix def _get_faster_pixel_dimension(self, current_dimension): ''' Uses a list of pre-calculated dimensions to cut the image size down to one that is faster for np.fft.fftn(). Dimensions are all integers of the form k*2^n for small k. :param current_dimension: :return: new dimension ''' better_dimensions = [ 80, 84, 88, 92, 96, 104, 110, 112, 120, 128, 130, 132, 136, 140, 152, 156, 160, 168, 176, 184, 192, 208, 220, 224, 240, 256, 260, 264, 272, 280, 304, 312, 320, 336, 352, 368, 384, 416, 440, 448, 480, 512, 520, 528, 544, 560, 608, 624, 640, 672, 704, 736, 768, 832, 880, 896, 960, 1024, 1040, 1056, 1088, 1120, 1216, 1248, 1280, 1344, 1408, 1472, 1536, 1664, 1760, 1792, 1920, 2048 ] pos = bisect_right(better_dimensions, current_dimension) - 1 print 'pos', pos return better_dimensions[pos] def get_central_region(self, cutout, dim): ''' :param cutout: a 2d numpy array, could be non square :param dim: an integer dimensional :return: cutout_central, the central dim x dim region of cutout ''' cut_height = cutout.shape[0] - dim cut_width = cutout.shape[1] - dim top_pix = np.int(np.floor(cut_height / 2.0)) left_pix = np.int(np.floor(cut_width / 2.0)) cutout_central = cutout[top_pix:top_pix + dim, left_pix:left_pix + dim] return cutout_central def fix_cutout_size(self, cutout1, cutout2): ''' :param cutout1,2: two 2d numpy array representing a windowed cutouts around a point of interest, should be in the range of 100-2048 pixels in height/width :return: cutout1_fix,cutout2_fix: the a 2d numpy arrays that are square, and have been cropped to be of a size that will be relatively fast to calculate a 2d FFT of. ''' min_dim = min(cutout1.shape[0], cutout1.shape[1], cutout2.shape[0], cutout2.shape[1]) new_dim = self._get_faster_pixel_dimension(min_dim) cutout1_fix = self.get_central_region(cutout1, new_dim) cutout2_fix = self.get_central_region(cutout2, new_dim) return (cutout1_fix, cutout2_fix) def align_by_correlation(self, xy1, xy2, CorrSettings=CorrSettings()): """take two points in the image, and calculate the 2d cross correlation function of the image around those two points plots the results in the appropriate axis, and returns the shift which aligns the two points given in microns keywords) xy1) a (x,y) tuple specifying point 1, the point that should be fixed xy2) a (x,y) tuple specifiying point 2, the point that should be moved window) the size of the patch to cutout (+/- window around the points) for calculating the correlation (default = 100 pixels) delta) the size of the maximal shift +/- delta from no shift to calculate skip) the number of integer pixels to skip over when calculating the correlation returns) (maxC,dxy_um) maxC)the maximal correlation measured dxy_um) the (x,y) tuple which contains the shift in microns necessary to align point xy2 with point xy1 """ start_time = time.time() window = CorrSettings.window delta = CorrSettings.delta skip = CorrSettings.skip pixsize = self.imgCollection.get_pixel_size() #calculate the cutout patches and the correlation matrix #(one_cut,two_cut,corrmat)=self.cross_correlate_two_to_one(xy1,xy2,window,delta,skip) (x1, y1) = xy1 (x2, y2) = xy2 one_cut = self.cutout_window(x1, y1, window) two_cut = self.cutout_window(x2, y2, window) print("---cutout a . %s seconds ---" % (time.time() - start_time)) print 'one_shape,two_shape ', one_cut.shape, two_cut.shape one_cut, two_cut = self.fix_cutout_size(one_cut, two_cut) one_cut = one_cut - np.mean(one_cut) two_cut = two_cut - np.mean(two_cut) print 'new dimensions ', one_cut.shape, two_cut.shape print("---cutout ended. %s seconds ---" % (time.time() - start_time)) corrmat, corrval, dx_pix, dy_pix = self._cross_correlation_shift( one_cut, two_cut) #convert dy_pix and dx_pix into microns dy_um = dy_pix * pixsize dx_um = dx_pix * pixsize #pack up the shifts into tuples dxy_pix = (dx_pix, dy_pix) dxy_um = (dx_um, dy_um) print("---correlation ended. %s seconds ---" % (time.time() - start_time)) print "(correlation,(dx,dy))= ", print(corrval, dxy_pix) #paint the patch around the first point in its axis, with a box of size of the two_cut centered around where we found it self.paintImageOne(one_cut, xy=xy1, dxy_pix=dxy_pix) #paint the patch around the second point in its axis self.paintImageTwo(two_cut, xy=xy2, xyp=(xy2[0] - dx_um, xy2[1] - dy_um)) #paint the correlation matrix in its axis self.paintCorrImage(corrmat, dxy_pix) print("---painting ended %s seconds ---" % (time.time() - start_time)) return (corrval, dxy_um) def explore_match(self, img1, kp1, img2, kp2, status=None, H=None): h1, w1 = img1.shape[:2] h2, w2 = img2.shape[:2] vis = np.zeros((max(h1, h2), w1 + w2), np.uint8) vis[:h1, :w1] = img1 vis[:h2, w1:w1 + w2] = img2 vis = cv2.cvtColor(vis, cv2.COLOR_GRAY2BGR) if H is not None: corners = np.float32([[0, 0], [w1, 0], [w1, h1], [0, h1]]) corners = np.int32( cv2.perspectiveTransform(corners.reshape(1, -1, 2), H).reshape( -1, 2) + (w1, 0)) cv2.polylines(vis, [corners], True, (255, 255, 255)) if status is None: status = np.ones(len(kp1), np.bool_) p1 = np.int32([kpp.pt for kpp in kp1]) p2 = np.int32([kpp.pt for kpp in kp2]) + (w1, 0) green = (0, 255, 0) red = (0, 0, 255) white = (255, 255, 255) kp_color = (51, 103, 236) for (x1, y1), (x2, y2), inlier in zip(p1, p2, status): if inlier: col = green cv2.circle(vis, (x1, y1), 2, col, -1) cv2.circle(vis, (x2, y2), 2, col, -1) else: col = red r = 2 thickness = 3 cv2.line(vis, (x1 - r, y1 - r), (x1 + r, y1 + r), col, thickness) cv2.line(vis, (x1 - r, y1 + r), (x1 + r, y1 - r), col, thickness) cv2.line(vis, (x2 - r, y2 - r), (x2 + r, y2 + r), col, thickness) cv2.line(vis, (x2 - r, y2 + r), (x2 + r, y2 - r), col, thickness) vis0 = vis.copy() for (x1, y1), (x2, y2), inlier in zip(p1, p2, status): if inlier: cv2.line(vis, (x1, y1), (x2, y2), green) else: cv2.line(vis, (x1, y1), (x2, y2), red) return vis def align_by_sift(self, xy1, xy2, window=70, SiftSettings=SiftSettings()): """take two points in the image, and calculate SIFT features image around those two points cutting out size window keywords) xy1) a (x,y) tuple specifying point 1, the point that should be fixed xy2) a (x,y) tuple specifiying point 2, the point that should be moved window) the size of the patch to cutout (+/- window around the points) for calculating the correlation (default = 70 um) returns) (maxC,dxy_um) maxC)the maximal correlation measured dxy_um) the (x,y) tuple which contains the shift in microns necessary to align point xy2 with point xy1 """ print "starting align by sift" pixsize = self.imgCollection.get_pixel_size() #cutout the images around the two points (x1, y1) = xy1 (x2, y2) = xy2 one_cut = self.cutout_window(x1, y1, window) two_cut = self.cutout_window(x2, y2, window) #one_cuta=np.minimum(one_cut*256.0/self.maxvalue,255.0).astype(np.uint8) #two_cuta=np.minimum(two_cut*256.0/self.maxvalue,255.0).astype(np.uint8) one_cuta = np.copy(one_cut) two_cuta = np.copy(two_cut) one_cuta = cv2.equalizeHist(one_cuta) two_cuta = cv2.equalizeHist(two_cuta) sift = cv2.SIFT(nfeatures=SiftSettings.numFeatures, contrastThreshold=SiftSettings.contrastThreshold) kp1, des1 = sift.detectAndCompute(one_cuta, None) kp2, des2 = sift.detectAndCompute(two_cuta, None) print "features1:%d" % len(kp1) print "features2:%d" % len(kp2) #img_one = cv2.drawKeypoints(one_cut,kp1) #img_two = cv2.drawKeypoints(two_cut,kp2) #image2=self.two_axis.imshow(img_two) # FLANN parameters FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) # or pass empty dictionary flann = cv2.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(des1, des2, k=2) # Need to draw only good matches, so create a mask matchesMask = np.zeros(len(matches)) kp1matchIdx = [] kp2matchIdx = [] # ratio test as per Lowe's paper for i, (m, n) in enumerate(matches): if m.distance < 0.9 * n.distance: kp1matchIdx.append(m.queryIdx) kp2matchIdx.append(m.trainIdx) p1 = np.array([kp1[i].pt for i in kp1matchIdx]) p2 = np.array([kp2[i].pt for i in kp2matchIdx]) # p1c = [pt-np.array[window,window] for pt in p1] # p2c = [pt-np.array[window,window] for pt in p2] kp1m = [kp1[i] for i in kp1matchIdx] kp2m = [kp2[i] for i in kp2matchIdx] #print "kp1matchshape" #print matchesMask #print len(kp1match) #print len(kp2match) #draw_params = dict(matchColor = (0,255,0), # singlePointColor = (255,0,0), # matchesMask = matchesMask, # flags = 0) #img3 = cv2.drawMatches(one_cut,kp1,two_cut,kp2,matches,None,**draw_params) transModel = ransac.RigidModel() bestModel, bestInlierIdx = ransac.ransac(p1, p2, transModel, 2, 300, 20.0, 3, debug=True, return_all=True) if bestModel is not None: the_center = np.array( [[one_cut.shape[0] / 2, one_cut.shape[1] / 2]]) trans_center = transModel.transform_points(the_center, bestModel) offset = the_center - trans_center xc = x2 + offset[0, 0] * pixsize yc = y2 - offset[0, 1] * pixsize #newcenter=Line2D([trans_center[0,0]+one_cut.shape[1]],[trans_center[0,1]],marker='+',markersize=7,markeredgewidth=1.5,markeredgecolor='r') #oldcenter=Line2D([the_center[0,0]],[the_center[0,1]],marker='+',markersize=7,markeredgewidth=1.5,markeredgecolor='r') dx_um = -bestModel.t[0] * pixsize dy_um = -bestModel.t[1] * pixsize print "matches:%d" % len(kp1matchIdx) print "inliers:%d" % len(bestInlierIdx) print('translation', bestModel.t) print('rotation', bestModel.R) mask = np.zeros(len(p1), np.bool_) mask[bestInlierIdx] = 1 #img3 = self.explore_match(one_cuta,kp1m,two_cuta,kp2m,mask) #self.corr_axis.cla() #self.corr_axis.imshow(img3) #self.corr_axis.add_line(newcenter) #self.corr_axis.add_line(oldcenter) #self.repaint() #self.paintImageOne(img_one,xy=xy1) #paint the patch around the second point in its axis #self.paintImageTwo(img_two,xy=xy2) #paint the correlation matrix in its axis #self.paintCorrImage(corrmat, dxy_pix,skip) print(dx_um, dy_um) self.paintImageOne(one_cut, xy=xy1) self.paintImageTwo(two_cut, xy=xy2, xyp=(x2 - dx_um, y2 - dy_um)) return ((dx_um, dy_um), len(bestInlierIdx)) else: print "no model found" self.paintImageOne(one_cut, xy=xy1) self.paintImageTwo(two_cut, xy=xy2) return ((0.0, 0.0), 0) def paintPointsOneTwo(self, xy1, xy2, window=None): (x1, y1) = xy1 (x2, y2) = xy2 print "getting p1 window at ", x1, y1 print "getting p2 window at ", x2, y2 fw, fh = self.imgCollection.get_image_size_um() if window is None: min_dim = min(fw, fh) window = min_dim * .8 / 2 one_cut = self.cutout_window(x1, y1, window) two_cut = self.cutout_window(x2, y2, window) self.paintImageOne(one_cut, xy1) #paint the patch around the second point in its axis self.paintImageTwo(two_cut, xy2) def make_preview_stack(self, xpos, ypos, width, height, directory): print "make a preview stack" hw_pix = int(round(width * .5 / self.orig_um_per_pix)) hh_pix = int(round(height * .5 / self.orig_um_per_pix)) queue = Queue.Queue() #spawn a pool of threads, and pass them queue instance for i in range(4): t = ImageCutThread(queue) t.setDaemon(True) t.start() for i in range(len(self.mosaicArray.xpos)): (cx_pix, cy_pix) = self.convert_pos_to_ind(xpos[i], ypos[i]) rect = [ cx_pix - hw_pix, cy_pix - hh_pix, cx_pix + hw_pix, cy_pix + hh_pix ] queue.put((self.imagefile, rect, i)) queue.join()
#tetra_fn='/home/carlos/PycharmProjects/margreet_code_review/rough_ave.tif' #image_fn ='/home/carlos/PycharmProjects/margreet_code_review/hel4.pma' tmp=Mapping(tetra_fn) if 1: root=os.path.normpath("N:/tnw/BN/CMJ/Shared/Margreet/20181203_HJ_training/#3.10_0.1mg-ml_streptavidin_50pM_HJC_G_movies") name='hel4.pma' else: root=os.path.normpath("N:/tnw/BN/CMJ/Shared/Margreet/181218 - First single-molecule sample (GattaQuant)/RawData") name='Spooled files.sifx' image_fn=os.path.join(root,name) imc = ImageCollection(tetra_fn, image_fn) # better: give image directory, and search for specific name or extension img = imc.get_image(1) #tmp._tf2_matrix #imc.mapping._tf2_matrix #imc.pts_number # is too 19 for the pma #import matplotlib.pyplot as plt; plt.imshow(imc.im_mean20_correct) traces_fn=os.path.join(root,name[:-4]+'-P.traces') Ncolours=2 if os.path.isfile(traces_fn): with open(traces_fn, 'r') as infile: Nframes = np.fromfile(infile, dtype = np.int32, count = 1).item() Ntraces = np.fromfile(infile, dtype = np.int16, count = 1).item() rawData = np.fromfile(infile, dtype = np.int16, count = Ncolours*Nframes * Ntraces)