def acquireImage(channelGroup, channelName, hook): x_array = [] y_array = [] z_array = [] for idx in range(pos_list.get_number_of_positions()): pos = pos_list.get_position(idx) #pos.go_to_position(pos, mmc) x = pos_list.get_position(idx).get(0).x y = pos_list.get_position(idx).get(0).y z = pos_list.get_position(idx).get(1).x x_array.append(x) y_array.append(y) z_array.append(z) x_array = np.array(x_array) y_array = np.array(y_array) z_array = np.array(z_array) with Acquisition(directory=directoryPATH, name=nameofSAVEDFILE, post_hardware_hook_fn=hook, post_camera_hook_fn=hook_fn) as acq: x = np.hstack([x_array[:, None]]) y = np.hstack([y_array[:, None]]) z = np.hstack([z_array[:, None]]) #Generate the events for a single z-stack xyz = np.hstack([x_array[:, None], y_array[:, None], z_array[:, None]]) events = multi_d_acquisition_events(xyz_positions=xyz, channel_group=channelGroup, channels=[channelName]) acq.acquire(events) #acquire a 2 x 1 grid #acq.acquire({'row': 0, 'col': 0}) #acq.acquire({'row': 1, 'col': 0}) stackfolder = "**/*" folder = Path(directoryPATH) foldernames = [] for name in folder.glob('saving_name_*'): print(name.stem) foldernames.append(name.stem) maximum = 1 for file in foldernames: number = int( re.search(nameofSAVEDFILE + "_" + '(\d*)', file).group(1)) # assuming filename is "filexxx.txt" # compare num to previous max, e.g. maximum = number if number > maximum else maximum # set max = 0 before for-loop print(number) highest = nameofSAVEDFILE + "_" + str(maximum) data_path = os.path.join(folder, highest) dataset = Dataset(data_path) #dataset = acq.get_dataset() #dataset = acq.get_dataset() #print(dataset) #data_path=str(directoryPATH/saving_name) dataset = Dataset(data_path) print(dataset.axes) print("data_path", data_path) length = (len(xyz)) dataset_metadata = dataset.read_metadata(channel=0, position=1) print(dataset_metadata) pos = dataset_metadata["Axes"]["position"] print(pos) if (dataset): sizeimg = dataset.read_image(channel=0, position=0) sizeimg = cv2.cvtColor(sizeimg, cv2.COLOR_GRAY2RGB) h, w, c = sizeimg.shape length = int( (sqrt(length) )) #size of the grid (row or column should be same technically) blank_image = np.zeros((h * (math.ceil(math.sqrt(length)) + 2), w * (math.ceil(math.sqrt(length)) + 2), 3), np.uint16) print("image size ", blank_image.shape) pixelsizeinum = dataset_metadata["PixelSizeUm"] #get size of pixel in um print(pixelsizeinum) """ for datarow in range(10): for datacolumn in range(10): metadata = dataset.read_metadata(row=datarow, col=datacolumn) if(metadata["Axes"]["position"]>=0): pos=metadata["Axes"]["position"] #print(pos) img = dataset.read_image(position=pos) img = cv2.cvtColor(img,cv2.COLOR_GRAY2RGB) cv2.imshow("test",img) """ xtotaloffset = 0 ytotaloffset = 0 for dataposition in range( len(xyz)): #do range for all positions in micromanager print(dataposition) metadata = dataset.read_metadata(channel=0, position=dataposition) img = dataset.read_image(channel=0, position=dataposition) img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB) img = cv2.flip(img, 1) xoffset_um = metadata["XPosition_um_Intended"] yoffset_um = metadata["YPosition_um_Intended"] print("Intended location is : ", xoffset_um, yoffset_um) # cv2.imshow("test",img) # cv2.waitKey(0) xoffset_px = (xoffset_um - dataset.read_metadata( channel=0, position=0)['XPosition_um_Intended']) / pixelsizeinum yoffset_px = (yoffset_um - dataset.read_metadata( channel=0, position=0)['YPosition_um_Intended']) / pixelsizeinum xoffset_px = int(xoffset_px) print("Xoffset ", xoffset_px) #print("img max X ",blank_image.shape[0]) yoffset_px = int(yoffset_px) print("Yoffset ", yoffset_px) #print("img max Y ",blank_image.shape[1]) alpha = 0 blank_image[xoffset_px:xoffset_px + (img.shape[1]), yoffset_px:yoffset_px + (img.shape[0])] = cv2.addWeighted( blank_image[xoffset_px:xoffset_px + (img.shape[1]), yoffset_px:yoffset_px + (img.shape[0])], alpha, img, 1 - alpha, 0) #blank_image[:yoffset_px+img.shape[0], :xoffset_px+img.shape[1]] = img #blank_image = cv2.addWeighted(blank_image[yoffset_px:yoffset_px+img.shape[0], xoffset_px:xoffset_px+img.shape[1]],img) #################### #printout only ignore #################### scale_percent = 5 width = int(blank_image.shape[1] * scale_percent / 100) height = int(blank_image.shape[0] * scale_percent / 100) dim = (width, height) resized = cv2.resize(blank_image, dim, interpolation=cv2.INTER_AREA) ''' #show image winname = "test" cv2.namedWindow(winname) # Create a named window cv2.moveWindow(winname, 1000,1000) # Move it to (40,30) cv2.imshow(winname, resized) cv2.waitKey(0) ''' blank_image = cv2.cvtColor(blank_image, cv2.COLOR_BGR2GRAY) return blank_image, pixelsizeinum
def direct_stitch(data_path): dataset = Dataset(data_path) print(dataset.axes) dataset_metadata = dataset.read_metadata(channel=0, position=0) print(dataset_metadata) pos = dataset_metadata["Axes"]["position"] print(pos) if (dataset): sizeimg = dataset.read_image(channel=0, position=0) sizeimg = cv2.cvtColor(sizeimg, cv2.COLOR_GRAY2RGB) h, w, c = sizeimg.shape length = 10 #size of the grid (row or column should be same technically) blank_image = np.ones((h * (length + 1), w * (length + 1), 3), np.uint16) print("image size ", blank_image.shape) print(dataset_metadata) pixelsizeinum = dataset_metadata["PixelSizeUm"] #get size of pixel in um print(pixelsizeinum) """ for datarow in range(10): for datacolumn in range(10): metadata = dataset.read_metadata(row=datarow, col=datacolumn) if(metadata["Axes"]["position"]>=0): pos=metadata["Axes"]["position"] #print(pos) img = dataset.read_image(position=pos) img = cv2.cvtColor(img,cv2.COLOR_GRAY2RGB) cv2.imshow("test",img) """ xtotaloffset = 0 ytotaloffset = 0 for dataposition in range(70): print(dataposition) metadata = dataset.read_metadata(channel=0, position=dataposition) img = dataset.read_image(channel=0, position=dataposition) img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB) img = cv2.flip(img, 1) xoffset_um = metadata["XPosition_um_Intended"] yoffset_um = metadata["YPosition_um_Intended"] print("Intended location is : ", xoffset_um, yoffset_um) # cv2.imshow("test",img) # cv2.waitKey(0) xoffset_px = (xoffset_um - dataset.read_metadata( channel=0, position=0)['XPosition_um_Intended']) / pixelsizeinum yoffset_px = (yoffset_um - dataset.read_metadata( channel=0, position=0)['YPosition_um_Intended']) / pixelsizeinum xoffset_px = int(xoffset_px) print("Xoffset ", xoffset_px) #print("img max X ",blank_image.shape[0]) yoffset_px = int(yoffset_px) print("Yoffset ", yoffset_px) #print("img max Y ",blank_image.shape[1]) blank_image[xoffset_px:xoffset_px + (img.shape[1]), yoffset_px:yoffset_px + (img.shape[0])] += img #blank_image[:yoffset_px+img.shape[0], :xoffset_px+img.shape[1]] = img #blank_image = cv2.addWeighted(blank_image[yoffset_px:yoffset_px+img.shape[0], xoffset_px:xoffset_px+img.shape[1]],img) #################### #printout only ignore #################### scale_percent = 5 width = int(blank_image.shape[1] * scale_percent / 100) height = int(blank_image.shape[0] * scale_percent / 100) dim = (width, height) resized = cv2.resize(blank_image, dim, interpolation=cv2.INTER_AREA) winname = "test" cv2.namedWindow(winname) # Create a named window cv2.moveWindow(winname, 1000, 1000) # Move it to (40,30) cv2.imshow(winname, resized) cv2.waitKey(0) return blank_image
import numpy as np from pycromanager import Dataset import napari #This path is to the top level of the magellan dataset (i.e. the one that contains the Full resolution folder) # data_path = '/Users/henrypinkard/megllandump/l_axis_1' # data_path = '/Users/henrypinkard/megllandump/l_axis_3' data_path = '/Users/henrypinkard/megllandump/experiment_1_11' #open the dataset dataset = Dataset(data_path) #read tiles or tiles + metadata by channel, slice, time, and position indices #img is a numpy array and md is a python dictionary img, img_metadata = dataset.read_image(l=10, read_metadata=True) dask_array = dataset.as_array(stitched=True) with napari.gui_qt(): v = napari.Viewer() v.add_image(dask_array)
def main(argv): # parse directory name from command line argument input_dir_string = '' output_dir_string = '' try: arguments, values = getopt.getopt(argv,"hi:o:n:c:",["help","ipath=","opath="]) except getopt.GetoptError: print('Error. stage_recon.py -i <inputdirectory> -o <outputdirectory>') sys.exit(2) for current_argument, current_value in arguments: if current_argument == '-h': print('Usage. stage_recon.py -i <inputdirectory> -o <outputdirectory>') sys.exit() elif current_argument in ("-i", "--ipath"): input_dir_string = current_value elif current_argument in ("-o", "--opath"): output_dir_string = current_value if (input_dir_string == ''): print('Input parse error.') sys.exit(2) # Load data # this approach assumes data is generated by QI2lab pycromanager control code # https://docs.python.org/3/library/pathlib.html # Create Path object to directory input_dir_path=Path(input_dir_string) # determine number of directories in root directory. loop over each one. tile_dir_path = [f for f in input_dir_path.iterdir() if f.is_dir()] num_tiles = len(tile_dir_path) # TO DO: read text file with this information in root directory num_y = 73 num_z = 3 num_channels = 2 split=40 # create parameter array # [theta, stage move distance, camera pixel size] # units are [degrees,nm,nm] params=np.array([30,200,115],dtype=np.float32) # check if user provided output path if (output_dir_string==''): output_dir_path = input_dir_path else: output_dir_path = Path(output_dir_string) # https://github.com/nvladimus/npy2bdv # create BDV H5 file with sub-sampling for BigStitcher output_path = output_dir_path / 'full.h5' bdv_writer = npy2bdv.BdvWriter(str(output_path), nchannels=num_channels, ntiles=(num_z*num_y*split)+1, \ subsamp=((1,1,1),(2,2,2),(4,4,4),(8,8,8),(16,16,16)),blockdim=((16, 16, 8),)) # loop over each directory. Each directory will be placed as a "tile" into the BigStitcher file # TO DO: implement directory polling to do this in the background while data is being acquired. for tile in range(0,num_tiles): # load tile tile_dir_path_to_load = tile_dir_path[tile] print('Loading directory: '+str(tile_dir_path_to_load)) # decode directory name to determine tile_id in h5. reverse Z order, normal y order test_string = tile_dir_path_to_load.parts[-1].split('_') for i in range(len(test_string)): if 'y0' in test_string[i]: y_idx = int(test_string[i].split('y')[1]) if 'z0' in test_string[i]: z_idx = int(test_string[i].split('z')[1]) tile_id = ((num_z-z_idx-1)*(num_y))+y_idx print('y index: '+str(y_idx)+' z index: '+str(z_idx)+' H5 tile id: '+str(tile_id)) # https://pycro-manager.readthedocs.io/en/latest/read_data.html dataset = Dataset(tile_dir_path_to_load) # extract number of images in the tile num_x = len(dataset.axes['x']) num_x = num_x-10 # loop over channels inside tile for channel_id in range(num_channels): # read images from dataset. Skip first 10 images for stage speed up sub_stack = np.zeros([num_x,256,1600]) for i in range(num_x): sub_stack[i,:,:] = dataset.read_image(channel=channel_id, x=i+10, y=0, z=0, read_metadata=False) #TO DO: Integrate Microvolution hook here to do deconvolution on skewed data before deskewing. print('Deskew tile.') # run deskew deskewed = stage_deskew(data=sub_stack,parameters=params) del sub_stack gc.collect() # downsample by 2x in z due to oversampling when going from OPM to coverslip geometry deskewed_downsample = block_reduce(deskewed, block_size=(2,1,1), func=np.mean) del deskewed gc.collect() print('Split and write tiles.') # write BDV tile # https://github.com/nvladimus/npy2bdv for split_id in range(split): size = np.floor(num_x/split) size_overlap = size * 1.1 if split_id == split-1: deskewed_downsample_substack = deskewed_downsample[split_id*size:] else: deskewed_downsample_substack = deskewed_downsample[split_id*size:(split_id+1)*size_overlap] bdv_writer.append_view(deskewed_downsample_substack, time=0, channel=channel_id, tile=(tile_id*split)+split_id, voxel_size_xyz=(.115,.115,.200), voxel_units='um') # free up memory del deskewed_downsample #del deskewed_downsample gc.collect() # write BDV xml file # https://github.com/nvladimus/npy2bdv bdv_writer.write_xml_file(ntimes=1) bdv_writer.close() # clean up memory gc.collect()