def unscramble(num_im, num_slices, input_file_name, output_file_name): interlaced_image_raw = tif_to_array(input_file_name).astype(np.float64) ##check to make sure I am divisible by num_im num_columns = interlaced_image_raw.shape[-1] extra_pixels = num_columns % num_im if extra_pixels == 0: interlaced_image = interlaced_image_raw else: interlaced_image = interlaced_image_raw[:, :, :num_columns-extra_pixels] zstacks = num_im * num_slices yrows = interlaced_image.shape[-2] xcolumns = (interlaced_image.shape[-1]/num_im) sorted_image_stack = np.zeros((zstacks, yrows, xcolumns), dtype= interlaced_image.dtype) for j in range(num_slices): ##l2r for i in range(num_im): sorted_image_stack[(j*num_im) + i, :, :] = interlaced_image[j, :, i::num_im] ##r2l for i in range(num_im): sorted_image_stack[(j*num_im) + i, :, :] = interlaced_image[j, :, i::num_im] array_to_tif(sorted_image_stack.astype(np.float32), output_file_name) print "Image 1:", sorted_image_stack.shape, sorted_image_stack.dtype
def unscramble(num_im, num_slices, input_file_name, output_file_name): interlaced_image_raw = tif_to_array(input_file_name).astype(np.float64) ##check to make sure I am divisible by num_im num_columns = interlaced_image_raw.shape[-1] extra_pixels = num_columns % num_im if extra_pixels == 0: interlaced_image = interlaced_image_raw else: interlaced_image = interlaced_image_raw[:, :, :num_columns - extra_pixels] zstacks = num_im * num_slices yrows = interlaced_image.shape[-2] xcolumns = (interlaced_image.shape[-1] / num_im) sorted_image_stack = np.zeros((zstacks, yrows, xcolumns), dtype=interlaced_image.dtype) for j in range(num_slices): ##l2r for i in range(num_im): sorted_image_stack[(j * num_im) + i, :, :] = interlaced_image[j, :, i::num_im] ##r2l for i in range(num_im): sorted_image_stack[(j * num_im) + i, :, :] = interlaced_image[j, :, i::num_im] array_to_tif(sorted_image_stack.astype(np.float32), output_file_name) print "Image 1:", sorted_image_stack.shape, sorted_image_stack.dtype
def msim_data_to_3D_visualization(msim_data, outfile=None): enderlein_data_stack = np.zeros((msim_data.shape[2] * msim_data.shape[3], msim_data.shape[0], msim_data.shape[1]), dtype=np.float64) for row in range(msim_data.shape[2]): #print "Row", row for col in range(msim_data.shape[3]): enderlein_data_stack[row * msim_data.shape[3] + col, :, :] = msim_data[:, :, row, col] if outfile is not None: array_to_tif(enderlein_data_stack.astype(np.float32), outfile) return enderlein_data_stack
def sim_data_to_visualization(sim_data, outfile=None): image_stack = np.zeros( (num_rotations*num_phases, sim_data.shape[2], sim_data.shape[3]), dtype=np.float64) s = -1 for t in range(num_rotations): for p in range(num_phases): s += 1 image_stack[s, :, :] = sim_data[t, p, :, :] if outfile is not None: array_to_tif(image_stack.astype(np.float32), outfile) return image_stack
def save(self, filename, verbose=True): ptr = dll.get_image_pointer(self.handle) if verbose: print " Image stored at:", ptr image_buffer = buffer_from_memory( ptr, self.width * self.height * self.bit_depth // 8) image = np.frombuffer(image_buffer, np.uint16) image = image.reshape(1, self.height, self.width) image = np.right_shift(image, 4) if verbose: print image.shape, image.dtype, print image.min(), image.max(), image.mean() assert filename.endswith('.tif') simple_tif.array_to_tif(image, filename)
def msim_data_to_2D_visualization(msim_data, outfile=None): enderlein_data_image = np.zeros( (1, msim_data.shape[0] * msim_data.shape[2], msim_data.shape[1] * msim_data.shape[3]), dtype=np.float64) for row in range(msim_data.shape[0]): #print "Row", row for col in range(msim_data.shape[1]): enderlein_data_image[0, msim_data.shape[2] * row:msim_data.shape[2] * (row + 1), msim_data.shape[3] * col:msim_data.shape[3] * (col + 1)] = msim_data[row, col, :, :] if outfile is not None: array_to_tif(enderlein_data_image.astype(np.float32), outfile) return enderlein_data_image
def msim_data_to_3D_visualization(msim_data, outfile=None): enderlein_data_stack = np.zeros( (msim_data.shape[2]*msim_data.shape[3], msim_data.shape[0], msim_data.shape[1]), dtype=np.float64) for row in range(msim_data.shape[2]): #print "Row", row for col in range(msim_data.shape[3]): enderlein_data_stack[ row*msim_data.shape[3] + col, :, : ] = msim_data[:, :, row, col] if outfile is not None: array_to_tif(enderlein_data_stack.astype(np.float32), outfile) return enderlein_data_stack
def msim_data_to_2D_visualization(msim_data, outfile=None): enderlein_data_image = np.zeros( (1, msim_data.shape[0]*msim_data.shape[2], msim_data.shape[1]*msim_data.shape[3]), dtype=np.float64) for row in range(msim_data.shape[0]): #print "Row", row for col in range(msim_data.shape[1]): enderlein_data_image[ 0, msim_data.shape[2]*row:msim_data.shape[2]*(row+1), msim_data.shape[3]*col:msim_data.shape[3]*(col+1) ] = msim_data[row, col, :, :] if outfile is not None: array_to_tif(enderlein_data_image.astype(np.float32), outfile) return enderlein_data_image
def file_saving_child_process( data_buffers, buffer_shape, input_queue, output_queue, commands, ): buffer_size = np.prod(buffer_shape) while True: if commands.poll(): cmd, args = commands.recv() if cmd == 'set_buffer_shape': buffer_shape = args['shape'] buffer_size = np.prod(buffer_shape) commands.send(buffer_shape) continue try: permission_slip = input_queue.get_nowait() except Queue.Empty: time.sleep(0.001) continue if permission_slip is None: break else: process_me = permission_slip['which_buffer'] info("start buffer %i"%(process_me)) if 'file_info' in permission_slip: """ We only save the file if we have information for it. """ info("saving buffer %i"%(process_me)) """Copy the buffer to disk""" file_info = permission_slip['file_info'] with data_buffers[process_me].get_lock(): a = np.frombuffer(data_buffers[process_me].get_obj(), dtype=np.uint16)[:buffer_size ].reshape(buffer_shape) simple_tif.array_to_tif(a, **file_info) info("end buffer %i"%(process_me)) output_queue.put(permission_slip) return None
def file_saving_child_process( data_buffers, buffer_shape, input_queue, output_queue, commands, ): buffer_size = np.prod(buffer_shape) while True: if commands.poll(): cmd, args = commands.recv() if cmd == 'set_buffer_shape': buffer_shape = args['shape'] buffer_size = np.prod(buffer_shape) commands.send(buffer_shape) continue try: permission_slip = input_queue.get_nowait() except Queue.Empty: time.sleep(0.001) continue if permission_slip is None: break else: process_me = permission_slip['which_buffer'] info("start buffer %i" % (process_me)) if 'file_info' in permission_slip: """ We only save the file if we have information for it. """ info("saving buffer %i" % (process_me)) """Copy the buffer to disk""" file_info = permission_slip['file_info'] with data_buffers[process_me].get_lock(): a = np.frombuffer( data_buffers[process_me].get_obj(), dtype=np.uint16)[:buffer_size].reshape(buffer_shape) simple_tif.array_to_tif(a, **file_info) info("end buffer %i" % (process_me)) output_queue.put(permission_slip) return None
return multiview_data """ Load and truncate the object """ print "Loading resolution_target.tif..." actual_object = tif_to_array('resolution_target.tif' )[0, :, :].astype(np.float64) print "Done loading." print "Apodizing resolution target..." mask = np.zeros_like(actual_object) trim_size = 40 blur_size = 10 mask[trim_size:-trim_size, trim_size:-trim_size] = 1 gaussian_filter(mask, sigma=blur_size, output=mask) array_to_tif( mask.reshape((1,)+mask.shape).astype(np.float32), outfile='mask.tif') np.multiply(actual_object, mask, out=actual_object) print "Done apodizing." """ Generate noiseless data """ print "Generating multiview data from resolution target..." noisy_multiview_data = density_to_multiview_data(actual_object) print "Done generating." print "Saving visualization..." multiview_data_to_visualization( noisy_multiview_data, outfile='multiview_data.tif') print "Done saving" print "Saving unprocessed image..." array_to_tif(
signal_range = np.linspace(1, .1, num_timepoints) blurred_object = np.zeros( (num_timepoints,) + actual_object.shape, dtype=np.float64) blurred_pointlike_object = np.zeros_like(blurred_object) print "Blurring..." for i in range(num_timepoints): print " Blurring timepoint", i gaussian_filter(signal_range[i] * actual_object, sigma=sigma_range[i], output=blurred_object[i, :, :]) gaussian_filter(signal_range[i] * pointlike_object, sigma=sigma_range[i], output=blurred_pointlike_object[i, :, :]) print "Done blurring." print "Saving blurred_object.tif" array_to_tif(blurred_object.astype(np.float32), 'blurred_object.tif') print "Done saving." print "Saving blurred_pointlike_object.tif" array_to_tif(blurred_pointlike_object.astype(np.float32), 'blurred_pointlike_object.tif') print "Done saving." noisy_object = np.zeros(blurred_object.shape, dtype=np.float64) print "Adding noise..." print " Seeding random number generator with value: 0" np.random.seed(0) #For now, we want repeatably random for p in range(num_timepoints): print " Adding Poisson noise to slice", p noisy_object[p, :, :] = np.random.poisson(lam=0.5*blurred_object[p, :, :]) print "Saving noisy_object.tif" array_to_tif(noisy_object.astype(np.float32), 'noisy_object.tif')
""" Load and truncate the object """ print "Loading resolution_target.tif..." actual_object = tif_to_array('resolution_target-2.tif')[0, :, :].astype( np.float64) print "Done loading." print "Apodizing resolution target..." mask = np.zeros_like(actual_object) trim_size = 40 blur_size = 10 mask[trim_size:-trim_size, trim_size:-trim_size] = 1 gaussian_filter(mask, sigma=blur_size, output=mask) array_to_tif(mask.reshape((1, ) + mask.shape).astype(np.float32), outfile='mask.tif') np.multiply(actual_object, mask, out=actual_object) print "Done apodizing." """ Generate noiseless data """ print "Generating sim data from resolution target..." noisy_palm_and_widefield_data = density_to_palm_and_widefield_data( actual_object.astype(np.float32)) print "Done generating." print "Saving visualization..." array_to_tif(noisy_palm_and_widefield_data.astype(np.float32), outfile='palm_and_widefield_data.tif') print "Done saving" print "Saving unprocessed image..." array_to_tif(noisy_palm_and_widefield_data.sum(
predicted_result = H(correction_voltage) correction_factor = regularization * H_transpose(residual - predicted_result) correction_voltage += correction_factor plt.clf() plt.plot(correction_voltage, label='Voltage') plt.plot(residual, '.', ms=4, label='Desired residual') plt.plot(predicted_result, '-', label='Expected residual') plt.grid() plt.legend() plt.savefig('./comparison/%06i.png'%i) plt.clf() plt.plot(residual - predicted_result) plt.grid() plt.savefig('./differences/%06i.png'%i) voltage_to_save = convert_units.voltage_optimization_units_to_mirror_units( previous_input_voltage + 0.8 * correction_voltage) for tries in range(10): try: simple_tif.array_to_tif( voltage_to_save.astype(np.float32 ).reshape(voltage_to_save.size, 1, 1), new_input_voltage_filename) break except IOError: sleep(0.05) else: print "Seriously? C'mon, Windows."
return density """ Load and truncate the object """ print "Loading resolution_target.tif..." actual_object = tif_to_array('resolution_target-2.tif' )[0, :, :].astype(np.float64) print "Done loading." print "Apodizing resolution target..." mask = np.zeros_like(actual_object) trim_size = 40 blur_size = 10 mask[trim_size:-trim_size, trim_size:-trim_size] = 1 gaussian_filter(mask, sigma=blur_size, output=mask) array_to_tif( mask.reshape((1,)+mask.shape).astype(np.float32), outfile='mask.tif') np.multiply(actual_object, mask, out=actual_object) print "Done apodizing." """ Generate noiseless data """ print "Generating sim data from resolution target..." noisy_palm_and_widefield_data = density_to_palm_and_widefield_data( actual_object.astype(np.float32)) print "Done generating." print "Saving visualization..." array_to_tif(noisy_palm_and_widefield_data.astype(np.float32), outfile='palm_and_widefield_data.tif') print "Done saving" print "Saving unprocessed image..." array_to_tif(noisy_palm_and_widefield_data.sum(
lag_time = 25 #DAQ pix t = np.arange(200*period, dtype=np.float64) impulse_response = (offset + amplitude * np.sin(t * 2*np.pi/period + phase) * np.exp(-t * 1.0 / decay_time)) lag_convolution = np.exp(-t/lag_time) impulse_response = np.convolve(impulse_response, lag_convolution) impulse_response /= impulse_response.sum() impulse_response = impulse_response[:6000].copy() t = t[:6000].copy() #Maybe leave room for a 'dead zone' too? simple_tif.array_to_tif( impulse_response.astype(np.float32).reshape(impulse_response.size, 1, 1), 'impulse_response.tif') camera_exposures = 2 #Has to be an even number sweeps_per_exposure = 4 len_warmup = 200 len_sweep = 79 #DAQ pix len_ramp = 60 #DAQ pix len_undefined = len_sweep - len_ramp len_voltage = (len_warmup + (camera_exposures * sweeps_per_exposure * len_sweep)) len_response = (camera_exposures * sweeps_per_exposure * len_ramp)
signal_range = np.linspace(1, .1, num_timepoints) blurred_object = np.zeros((num_timepoints, ) + actual_object.shape, dtype=np.float64) blurred_pointlike_object = np.zeros_like(blurred_object) print "Blurring..." for i in range(num_timepoints): print " Blurring timepoint", i gaussian_filter(signal_range[i] * actual_object, sigma=sigma_range[i], output=blurred_object[i, :, :]) gaussian_filter(signal_range[i] * pointlike_object, sigma=sigma_range[i], output=blurred_pointlike_object[i, :, :]) print "Done blurring." print "Saving blurred_object.tif" array_to_tif(blurred_object.astype(np.float32), 'blurred_object.tif') print "Done saving." print "Saving blurred_pointlike_object.tif" array_to_tif(blurred_pointlike_object.astype(np.float32), 'blurred_pointlike_object.tif') print "Done saving." noisy_object = np.zeros(blurred_object.shape, dtype=np.float64) print "Adding noise..." print " Seeding random number generator with value: 0" np.random.seed(0) #For now, we want repeatably random for p in range(num_timepoints): print " Adding Poisson noise to slice", p noisy_object[p, :, :] = np.random.poisson(lam=0.5 * blurred_object[p, :, :]) print "Saving noisy_object.tif"
def result_mirror_units_to_optimization_units(er): return (((er - shift + 46.0) * 1.0 / scale)) / 155.0 assert ( result_mirror_units_to_optimization_units(result_optimization_units_to_mirror_units(1)) == 1.0 ) # Careful! Floats! if __name__ == "__main__": input_voltage = simple_tif.tif_to_array("input_voltage.tif").astype(np.float64) expected_result = simple_tif.tif_to_array("expected_result.tif").astype(np.float64) simple_tif.array_to_tif( voltage_optimization_units_to_mirror_units(input_voltage).astype(np.float32), "input_voltage_to_mirror.tif" ) simple_tif.array_to_tif( result_optimization_units_to_mirror_units(expected_result).astype(np.float32), "expected_result_from_chip.tif" ) plt.figure() plt.subplot(2, 1, 1) plt.plot(voltage_optimization_units_to_mirror_units(input_voltage).ravel(), label="Voltage to mirror") plt.grid("on") plt.legend() plt.subplot(2, 1, 2) plt.plot(result_optimization_units_to_mirror_units(expected_result).ravel(), label="Expected result") plt.legend() plt.grid("on") plt.show()
return image_stack """ Load and truncate the object """ print "Loading resolution_target.tif..." actual_object = tif_to_array('resolution_target.tif' )[0, :, :].astype(np.float64) print "Done loading." print "Apodizing resolution target..." mask = np.zeros_like(actual_object) trim_size = 40 blur_size = 10 mask[trim_size:-trim_size, trim_size:-trim_size] = 1 gaussian_filter(mask, sigma=blur_size, output=mask) array_to_tif( mask.reshape((1,)+mask.shape).astype(np.float32), outfile='mask.tif') np.multiply(actual_object, mask, out=actual_object) print "Done apodizing." """ Generate noiseless data """ print "Generating sim data from resolution target..." noisy_sim_data = density_to_sim_data(actual_object) print "Done generating." print "Saving visualization..." sim_data_to_visualization(noisy_sim_data, outfile='sim_data.tif') print "Done saving" print "Saving unprocessed image..." array_to_tif(noisy_sim_data.sum(axis=(0, 1) ).reshape((1,) + noisy_sim_data.shape[2:]
print "Iteration", i predicted_result = H(correction_voltage) correction_factor = regularization * H_transpose(residual - predicted_result) correction_voltage += correction_factor plt.clf() plt.plot(correction_voltage, label='Voltage') plt.plot(residual, '.', ms=4, label='Desired residual') plt.plot(predicted_result, '-', label='Expected residual') plt.grid() plt.legend() plt.savefig('./comparison/%06i.png' % i) plt.clf() plt.plot(residual - predicted_result) plt.grid() plt.savefig('./differences/%06i.png' % i) voltage_to_save = convert_units.voltage_optimization_units_to_mirror_units( previous_input_voltage + 0.8 * correction_voltage) for tries in range(10): try: simple_tif.array_to_tif( voltage_to_save.astype(np.float32).reshape( voltage_to_save.size, 1, 1), new_input_voltage_filename) break except IOError: sleep(0.05) else: print "Seriously? C'mon, Windows."
return shifted_msim_data """ Load and truncate the object """ print "Loading resolution_target.tif..." actual_object = tif_to_array('ladder_complete.tif' )[0, :, :].astype(np.float64) print "Done loading." print "Apodizing resolution target..." mask = np.zeros_like(actual_object) trim_size = 20#40 blur_size = 2#10 mask[trim_size:-trim_size, trim_size:-trim_size] = 1 gaussian_filter(mask, sigma=blur_size, output=mask) array_to_tif( mask.reshape((1,)+mask.shape).astype(np.float32), outfile='mask.tif') np.multiply(actual_object, mask, out=actual_object) print "Done apodizing." """ Generate noiseless data """ print "Generating msim data from resolution target..." noisy_msim_data = density_to_msim_data(actual_object) print "Done generating." print "Saving visualization..." msim_data_to_2D_visualization(noisy_msim_data, outfile='msim_data.tif') msim_data_to_3D_visualization(noisy_msim_data, outfile='msim_data_stack.tif') print "Done saving" print "Saving unprocessed image..." array_to_tif(noisy_msim_data.sum(axis=(2, 3)
def result_optimization_units_to_mirror_units(er): return (er * 155.) * scale + shift - 46. #Watch out for DC drift here def result_mirror_units_to_optimization_units(er): return (((er - shift + 46.) * 1.0 / scale) ) / 155. assert result_mirror_units_to_optimization_units( result_optimization_units_to_mirror_units(1)) == 1. #Careful! Floats! if __name__ == '__main__': input_voltage = simple_tif.tif_to_array( 'input_voltage.tif').astype(np.float64) expected_result = simple_tif.tif_to_array( 'expected_result.tif').astype(np.float64) simple_tif.array_to_tif( voltage_optimization_units_to_mirror_units(input_voltage ).astype(np.float32), 'input_voltage_to_mirror.tif') simple_tif.array_to_tif( result_optimization_units_to_mirror_units(expected_result ).astype(np.float32), 'expected_result_from_chip.tif') plt.figure() plt.subplot(2, 1, 1) plt.plot( voltage_optimization_units_to_mirror_units(input_voltage).ravel(), label='Voltage to mirror') plt.grid('on') plt.legend() plt.subplot(2, 1, 2) plt.plot(
def multiview_data_to_visualization(multiview_data, outfile=None): if outfile is not None: array_to_tif(multiview_data.astype(np.float32), outfile) return multiview_data
return shifted_msim_data """ Load and truncate the object """ print "Loading resolution_target.tif..." actual_object = tif_to_array('ladder_complete.tif')[0, :, :].astype(np.float64) print "Done loading." print "Apodizing resolution target..." mask = np.zeros_like(actual_object) trim_size = 20 #40 blur_size = 2 #10 mask[trim_size:-trim_size, trim_size:-trim_size] = 1 gaussian_filter(mask, sigma=blur_size, output=mask) array_to_tif(mask.reshape((1, ) + mask.shape).astype(np.float32), outfile='mask.tif') np.multiply(actual_object, mask, out=actual_object) print "Done apodizing." """ Generate noiseless data """ print "Generating msim data from resolution target..." noisy_msim_data = density_to_msim_data(actual_object) print "Done generating." print "Saving visualization..." msim_data_to_2D_visualization(noisy_msim_data, outfile='msim_data.tif') msim_data_to_3D_visualization(noisy_msim_data, outfile='msim_data_stack.tif') print "Done saving" print "Saving unprocessed image..." array_to_tif(noisy_msim_data.sum( axis=(2, 3)).reshape((1, ) + noisy_msim_data.shape[:2]).astype(np.float32),
decay_time = 1600 #DAQ pix lag_time = 25 #DAQ pix t = np.arange(200 * period, dtype=np.float64) impulse_response = (offset + amplitude * np.sin(t * 2 * np.pi / period + phase) * np.exp(-t * 1.0 / decay_time)) lag_convolution = np.exp(-t / lag_time) impulse_response = np.convolve(impulse_response, lag_convolution) impulse_response /= impulse_response.sum() impulse_response = impulse_response[:6000].copy() t = t[:6000].copy() #Maybe leave room for a 'dead zone' too? simple_tif.array_to_tif( impulse_response.astype(np.float32).reshape(impulse_response.size, 1, 1), 'impulse_response.tif') camera_exposures = 2 #Has to be an even number sweeps_per_exposure = 4 len_warmup = 200 len_sweep = 79 #DAQ pix len_ramp = 60 #DAQ pix len_undefined = len_sweep - len_ramp len_voltage = (len_warmup + (camera_exposures * sweeps_per_exposure * len_sweep)) len_response = (camera_exposures * sweeps_per_exposure * len_ramp) assert impulse_response.size >= len_voltage def H(voltage):
def richardson_lucy_deconvolution( image_data=None, psf_data=None, num_iterations=None, modify_psf=False, image_data_shape=None, image_data_dtype=None, psf_data_shape=None, psf_data_dtype=None, psf_sigma=None, verbose=True, output_name=None, tk_master=None, which_channel = 'all', truncate_negative_values=False, ): """Deconvolve a 2D or 3D image using the Richardson-Lucy algorithm from an image and a point-spread funciton (PSF) 'image_data': a numpy array, a filename, or None to have the user select a file with a graphical interface. If a filename, 'psf_type': 'gaussian', a numpy array, a filename, or None to have the user select a PSF data file using the graphical interface. num_iterations: The number of times to iteratively refine the object estimate. modify_psf: Boolean. If True, then both the PSF and the image data are modified on every iteration. If false, then tne PSF is assumed to be exact, and only the image data is modified. """ """ Select and load image data. """ if tk_master is None: tk_master = Tk.Tk() tk_master.withdraw() config = get_config() image_data, output_name, num_channels = image_data_as_array( image_data, image_data_shape, image_data_dtype, output_name, verbose, config) if image_data == 'cancelled': print "Deconvolution cancelled.\n" return None else: if image_data.min() < 0: if truncate_negative_values: image_data[image_data < 0] = 0 else: raise UserWarning( "Image data has negative elements!\n" + "This violates the assumptions of Richardson-Lucy" + " deconvolution.") image_data = 1e-12 + image_data.astype(numpy.float64) output_basename, output_extension = os.path.splitext(output_name) estimate_name = output_basename + '_estimate' + output_extension history_name = output_basename + '_history' + output_extension if psf_data is None: psf_data = ask_psf_type(config, master=tk_master) if psf_data == 'cancelled': print "Deconvolution cancelled.\n" return None if psf_data == 'gaussian': if psf_sigma is None: psf_sigma = ask_psf_sigma(config, master=tk_master) else: assert len(psf_sigma) == len(image_data.shape) for s in psf_sigma: try: assert float(s) == s except(AssertionError, ValueError): print "psf_sigma:", psf_sigma raise UserWarning( "'psf_sigma' must be either None or a tuple of" + " numbers with one entry for each dimension" + " of the input image.") else: psf_data, trash, trash = image_data_as_array( psf_data, psf_data_shape, psf_data_dtype, output_name=None, verbose=verbose, config=config, title='Select a PSF file', initialfile='psf.tif') if psf_data == 'cancelled': print "Deconvolution cancelled\n" return None else: psf_data = 1e-12 + psf_data.astype(numpy.float64) psf_data = condition_psf_data( psf_data, new_shape=image_data.shape) if num_iterations is None: try: initial_value = int(config.get('File', 'last_num_iterations')) except: initial_value = 10 num_iterations = tkSimpleDialog.askinteger( title="Iterations", prompt="How many deconvolution iterations?", initialvalue=initial_value, minvalue=1) if num_iterations is None: print "Deconvolution cancelled\n" return None config.set('File', 'last_num_iterations', num_iterations) save_config(config) "Number of iterations to perform:", num_iterations if psf_data != 'gaussian': print "Precomputing..." start = clock() psf_data_fft = fftn(psf_data) psf_data_fft_r = psf_data_fft[::-1, ::-1, ::-1] end = clock() print "Done precomputing. Time:", end - start assert which_channel == 'all' or which_channel < num_channels if num_channels > 1 and which_channel != 'all': """Pick out just one color channel to deconvolve""" image_data = image_data[which_channel::num_channels, :, :] num_channels = 1 if which_channel == 'all' and num_channels > 1: data_slices = image_data.shape[0] // num_channels history_slices = num_iterations + 1 channels = num_channels else: data_slices = None history_slices = None channels = None full_estimate = image_data.copy() history = numpy.zeros((num_channels * (num_iterations + 1),) + (image_data.shape[1:])) for c in range(num_channels): estimate = full_estimate[c::num_channels, :, :] image_channel = image_data[c::num_channels, :, :] history[c, :, :] = (estimate.max(axis=0) / estimate.max(axis=0).mean()) for i in range(num_iterations): print "Computing iteration %i..."%i start = clock() if psf_data == 'gaussian': blurred_estimate = gaussian_filter(estimate, sigma=psf_sigma) estimate *= gaussian_filter((image_channel / blurred_estimate), sigma=psf_sigma) else: blurred_estimate = ifftn(psf_data_fft * fftn(estimate)).real estimate *= ifftn(psf_data_fft_r * fftn(image_channel / blurred_estimate) ).real end = clock() print " Time:", end - start print " Done computing." print "Saving..." history[(i+1)*num_channels + c, :, :] = estimate.max(axis=0) / ( estimate.max(axis=0).mean()) if output_extension in ('.tif', '.tiff'): array_to_tif( full_estimate.astype(numpy.float32), outfile=estimate_name, slices=data_slices, channels=channels) array_to_tif( history.astype(numpy.float32), outfile=history_name, slices=history_slices, channels=channels) else: #Use raw binary full_estimate.tofile(estimate_name) history.tofile(history_name) print "Done saving." sys.stdout.flush() return (full_estimate, history)