def pointTransform(self,x,y, check=0): """ illuminates a single point while performing a mapping transform function exists primarily for testing """ MF = self.MF coord = self.ccd_to_dmd(x,y) # TODO: # multiplying by 4 because of confusing SUBPIXEL stuff fix in image # generator # do all floats in FUTURE PI.py_illuminate_enable() PI.py_clear_framebuffer() PI.py_illuminate_point(coord[0],coord[1], MF.mask_number1) PI.py_illuminate_expose() # turn on the frame buffer if check == 1: img_array = PC.snapPtr(0.35,180,"spare") # just clobber the illumination point a = numpy.array([coord[0]]) b = numpy.array([coord[1]]) max_val = PI.py_illuminate_spot_find(img_array, a,b) if max_val < 100: print("point not found") # end if else: print("found(%d,%d)" % (a[0],b[0])) # end else PC.cameraClose() # also frees up image buffer memory
def snapUVPNG(exposure, gain,filename): """ snaps an image and saves the 14bit image as an 8 bit greyscale PNG by shifting out 6 bits """ global img_array global img_array_float global frames global beadpos_xcol global beadpos_yrow global num_beads for i in range(frames): PC.py_snapPtr(img_array, exposure,gain,'spare') img_array_float += img_array.astype(np.float) # sum accumulator # end for img_array_out = (img_array_float/frames).astype(np.uint16) img_array_float *= 0 # reset accumulator img_array_out.tofile(filename+'.raw') image_8bit = (img_array_out >> 6).astype(np.uint8) im = Image.fromarray(image_8bit.reshape((1000,1000)),'L') PC.cameraClose() # also frees up image buffer memory im.save(filename + ".png", "png")
def snapPicPNG(exposure, gain, color, filename): """ snaps an image and saves the 14bit image as an 8 bit greyscale PNG by shifting out 6 bits """ temp = PC.snap(exposure, gain, color, filename + ".raw") im = Image.new('L', (1000,1000)) pix = im.load() for i in range(1000): for j in range(1000): pix[j,i] = PC.py_14to8bit(temp, 1000*i+j) # end for # end for PC.cameraClose() # also frees up image buffer memory im.save(filename + ".png", "png")
def snapPicPNG(exposure, gain, color, filename): """ snaps an image and saves the 14bit image as an 8 bit greyscale PNG by shifting out 6 bits """ global img_array global img_array_float global frames global beadpos_xcol global beadpos_yrow global num_beads global my_color for i in range(frames): PC.py_snapPtr(img_array, exposure,gain,color) img_array_float += img_array.astype(np.float) # sum accumulator # end for img_array_out = (img_array_float/frames).astype(np.uint16) img_array_float *= 0 # reset accumulator img_array_out.tofile(filename+'.raw') image_8bit = (img_array_out >> 6).astype(np.uint8) im = Image.fromarray(image_8bit.reshape((1000,1000)),'L') PC.cameraClose() # also frees up image buffer memory im.save(filename + ".png", "png") if num_beads != 0 and my_color == color: print("value at 1st point: %d" % \ img_array_out[beadpos_xcol[0]+1000*beadpos_yrow[0]]) print("value at 2nd point: %d" % \ img_array_out[beadpos_xcol[1]+1000*beadpos_yrow[1]]) print("value at 3rd point: %d" % \ img_array_out[beadpos_xcol[2]+1000*beadpos_yrow[2]]) # end if del img_array_out del image_8bit del im
def collect(): """ 1) Snaps 4 pictures at the "exposures" and "gains" settings 2) saves them to the "_after" image files 3) closes the camera and the DMD 4) creates an overlay png image for evaluation """ global exposures global gains global my_color global my_color_ind #MapFunc.illum_light_all() snapAllPics(exposures, gains, "_after") PC.cameraClose() # also frees up image buffer memory stop_release() imR = Image.open("map_0_1" +".png") # just beads imG = Image.open("colorsnap-" + my_color + "_after" + ".png") # just beads imB = Image.open("map_0_2" +".png") # the found beads im = Image.new('RGB', (1000,1000)) pix = im.load() pixR = imR.load() pixG = imG.load() pixB = imB.load() for i in range(1000): for j in range(1000): #pix[i,j] = (0,pixG[i,j],pixB[i,j]) #px = -238501 pix[i,j] = (pixR[i,j],pixG[i,j],pixB[i,j]) #px = -238501 # end for # end for im.save("color_overlay_current" +".png", "png") # free up the allocated memory del imR del imG del imB del im del pix del pixR del pixG del pixB
def snapAllPics(exposure, gain,suffix): """ exposure and gain are lists also creates an RGB overlay image """ global exposures global gains global MapFunc global MaestroF global colors global filenames MapFunc.illum_light_all() MaestroF.filter_goto(colors[0]) snapPicPNG(exposures[0], gains[0], colors[0], filenames[0] + suffix) MaestroF.filter_goto(colors[1]) snapPicPNG(exposures[1], gains[1], colors[1], filenames[1] + suffix) MaestroF.filter_goto(colors[2]) snapPicPNG(exposures[2], gains[2], colors[2], filenames[2] + suffix) MaestroF.filter_goto(colors[3]) snapPicPNG(exposures[3], gains[3], colors[3], filenames[3] + suffix) im = Image.new('RGB', (1000,1000)) imR = Image.open(filenames[1] + suffix + ".png") # cy5 is red imG = Image.open(filenames[0] + suffix + ".png") # cy3 is green imB = Image.open(filenames[2] + suffix + ".png") # txred is blue pix = im.load() pixR = imR.load() pixG = imG.load() pixB = imB.load() for i in range(1000): for j in range(1000): pix[i,j] = (pixR[i,j],pixG[i,j],pixB[i,j]) # end for # end for im.save(filename4 + suffix +".png", "png") PC.cameraClose() # also frees up image buffer memory del imR del imG del imB del im del pix del pixR del pixG del pixB
PC.py_snapPtr(img_array, .35,80,my_color) #invert for images where beads are lighter than background img_array = 16383 - img_array # invert the 14 bit image num_beads = FO.find_objects(1000, 1000, \ img_array, \ beadpos_xcol, beadpos_yrow, \ segmask_image) print("The number of beads found: %d" % num_beads) MapFunc.convertPicPNG2(16383-img_array,0,1) MapFunc.convertPicPNG2(segmask_image*65535, 0,2) #MapFunc.convertPicPNG(segmask_image*65535+img_array, 0,3) print("phase ONE complete!!!!!!!!!!!!!") PC.cameraClose() # also frees up image buffer memory #MapFunc.illum_bitmap() MapFunc.illum_vector(beadpos_yrow,beadpos_xcol) time.sleep(1) PC.py_snapPtr(img_array2,.35,80,my_color) MapFunc.convertPicPNG2(img_array2,0,3) PC.cameraClose() # also frees up image buffer memory imR = Image.open("map_0_1" +".png") # just beads imG = Image.open("map_0_3" +".png") # the selected illuminated beads imB = Image.open("map_0_2" +".png") # the found beads im = Image.new('RGB', (1000,1000)) pix = im.load()
def mapGen(self, test_me = False): """ This function generates the mapping it: 1) loads the points to illuminate 2) generates a image for the DMD based on said coordinates 3) illuminates the image 4) takes a picture 5) copies the picture from the frame buffer 6) finds the illuminated points in the camera coordinates 7) generates a mapping to the DMD using a pseudoinverse 8) writes the mapping to class memory 9) writes the mapping to file Polonator_IlluminateFunctions is SWIGed as follows Illuminate and Hardware coordinates are mapped using the SWIG This allows you to access an array of Coordinates in C and python as follows once the IlluminateCoords_type struct is also interfaced in SWIG : new_coordArray(int size) -- creates an array of size delete_coordArray(IlluminateCoords_type * arry) -- deletes and array coordArray_get_x(IlluminateCoords_type *c_xy, int i) -- gets an value coordArray_set_x(IlluminateCoords_type *c_xy, int i, signed short int val) -- sets a value ptr_coordArray(IlluminateCoords_type *c_xy, int i) returns a pointer to an index """ """ get points for bitmap and load them SWIG style mapping_basis is just a list of points to to illuminate to generate a good and sufficient mapping basis coordinates are given as a range from -1 to 1 with 0,0 being the image center """ MF = self.MF print("STATUS:\tMappingFunctions: opening frame buffer\n") mapping_basis = open(MF.config_dir +'/mapping_basis.coordinates') print( "STATUS:\tMappingFunctions: getting list of points \ to illuminate from file\n") idx = -1 num_points = 0 for line in mapping_basis: if line[0] != '#': # '#' is reserved for comments on a separate line basis_coordinate = line.split() # tab delimited fields print(basis_coordinate) if basis_coordinate[0] == 'number': # this is the number of basis points we need to illuminate num_points = int(basis_coordinate[1]) idx = num_points # this creates the array of coordinates to illuminate points_to_illum_x = numpy.empty(idx, dtype=numpy.int32) # this is the array containing the found points on the CCD points_found_x = numpy.empty(idx, dtype=numpy.int32) points_to_illum_y = numpy.empty(idx, dtype=numpy.int32) points_found_y = numpy.empty(idx, dtype=numpy.int32) # write coordinates in reverse idx = idx - 1 print("number of Points to Illuminate: " + str(num_points)) elif (basis_coordinate[0] == 'XY') and (idx > -1): # make sure its tagged as a coordinate and the index is positive # scale to dimensions of the DMD bc_x = int( float(MF.IlluminateWidth)/2 \ *float(basis_coordinate[1]) ) \ + (float(MF.IlluminateWidth)-1)/2 bc_y = int( float(MF.IlluminateHeight)/2 \ *float(basis_coordinate[2]) ) \ + (float(MF.IlluminateHeight)-1)/2 print("read(%d,%d)\n" % (bc_x, bc_y)) points_to_illum_x[idx] = bc_x points_to_illum_y[idx] = bc_y idx = idx - 1 #end if #end if #end for """ Set up imaging """ MaestroF = MF.MaestroF MaestroF.darkfield_off() MaestroF.filter_home() MaestroF.filter_goto("spare") time.sleep(1) #MaestroF.filter_unlock() """ set up release hardware """ #self.illumInit() num_sub = 0 # keeps track of not found points data_size = 1000000 img_array = numpy.empty(data_size, dtype=numpy.uint16) #img_array_out = numpy.empty(data_size, dtype=numpy.uint16) img_array_float = numpy.zeros(data_size, dtype=numpy.float) for idx in range(num_points): # generate bitmap print("STATUS:\tMappingFunctions: clearing frame buffer\n") PI.py_clear_framebuffer() print("STATUS:\tMappingFunctions: creating mask\n") print("STATUS:\tMappingFunctions: generating one image of with ' + \ 'one pixel\n") PI.py_illuminate_point( int(points_to_illum_x[idx]),\ int(points_to_illum_y[idx]),\ MF.mask_number0) # illuminate just ONE spot print("STATUS:\tMappingFunctions: illuminating one point\n") print("illuminating (%d,%d)\n" % \ (int(points_to_illum_x[idx]), int(points_to_illum_y[idx]))) PI.py_illuminate_expose() # turn on the frame buffer #time.sleep(1) # analyze image for centroid print("STATUS:\tMappingFunctions: taking picture \ of one illuminated point\n") # take a picture and get a pointer to the picture frames = 5 for i in range(frames): PC.py_snapPtr(img_array, MF.expose,MF.gain,"spare") # sum accumulator img_array_float += img_array.astype(numpy.float) # end for # average over frames img_array_out = (img_array_float/frames).astype(numpy.uint16) img_array_float *= 0 # reset accumulator self.convertPicPNG(img_array_out, \ points_to_illum_x[idx], points_to_illum_y[idx]) # read in the config file. must be formated correctly print("STATUS:\tMappingFunctions: find illuminated point\n") # SWIGged function for finding the centroid # doing array[x:x+1] returns a pointer to an index x in an array # essentially in numpy a = points_found_x[idx:idx+1] b = points_found_y[idx:idx+1] max_val = PI.py_illuminate_spot_find(img_array_out,a,b) if max_val < 100: print("point not found") num_sub += 1 # end if else: print("found(%d,%d)" % \ (points_found_x[idx],points_found_y[idx]) ) # end else # free up memory #unload_camera_image(img_array) PI.py_clear_framebuffer() PI.py_illuminate_float() #PC.cameraClose() # also frees up image buffer memory #end for num_points -= num_sub # perform mapping operation print("STATUS:\tMappingFunctions: generating mapping\n") PC.cameraClose() # also frees up image buffer memory self.generateMapping(points_found_x, points_found_y, \ points_to_illum_x, points_to_illum_y, num_points) self.writeMappingFile() for i in range(num_points): print("illuminated(%d,%d)" % \ (points_to_illum_x[i],points_to_illum_y[i]) ) print("found(%d,%d)" % (points_found_x[i],points_found_y[i]) ) print(" ") # end for print("Finished map generation\n")