def test_lmpf_uniform_peak(): data_array = np.zeros(shape=(1, 1, 1, 100, 100), dtype=np.float32) data_array[0, 0, 0, 45:55, 45:55] = 1 imagestack = ImageStack.from_numpy(data_array) # standard local max peak finder, should find spots for all the evenly illuminated pixels. lmpf_no_kwarg = FindSpots.LocalMaxPeakFinder(1, 1, 1, sys.maxsize) peaks = lmpf_no_kwarg.run(imagestack) results_no_kwarg = peaks[{Axes.ROUND: 0, Axes.CH: 0}] assert len(results_no_kwarg.spot_attrs.data) == 100 # local max peak finder, capped at one peak per label. lmpf_kwarg = FindSpots.LocalMaxPeakFinder(1, 1, 1, sys.maxsize, num_peaks_per_label=1) peaks = lmpf_kwarg.run(imagestack) results_kwarg = peaks[{Axes.ROUND: 0, Axes.CH: 0}] assert len(results_kwarg.spot_attrs.data) == 1
# are not missed, increasing values such as ``max_sigma``, ``max_obj_area``, ``spot_diameter``, # and ``max_size`` could include them. Moreover, signal enhancement and background reduction # prior to this step can also improve accuracy of spot finding. bd = FindSpots.BlobDetector( min_sigma=2, max_sigma=6, num_sigma=20, threshold=0.1, is_volume=True, measurement_type='mean', ) lmp = FindSpots.LocalMaxPeakFinder(min_distance=2, stringency=8, min_obj_area=6, max_obj_area=600, is_volume=True) tlmpf = FindSpots.TrackpyLocalMaxPeakFinder( spot_diameter=11, min_mass=0.2, max_size=8, separation=3, preprocess=False, percentile=80, verbose=True, ) # crop imagestacks crop_selection = {Axes.X: (300, 700), Axes.Y: (300, 700)}
.. warning:: :py:class:`.LocalMaxPeakFinder` is not compatible with cropped data sets. """ # Load osmFISH experiment from starfish import FieldOfView, data from starfish.image import Filter from starfish.spots import DecodeSpots, FindSpots from starfish.types import Axes, TraceBuildingStrategies experiment = data.osmFISH(use_test_data=True) imgs = experiment["fov_000"].get_image(FieldOfView.PRIMARY_IMAGES) # filter raw data filter_ghp = Filter.GaussianHighPass(sigma=(1, 8, 8), is_volume=True) filter_laplace = Filter.Laplace(sigma=(0.2, 0.5, 0.5), is_volume=True) filter_ghp.run(imgs, in_place=True) filter_laplace.run(imgs, in_place=True) # z project max_imgs = imgs.reduce({Axes.ZPLANE}, func="max") # run LocalMaxPeakFinder on max projected image lmp = FindSpots.LocalMaxPeakFinder(min_distance=6, stringency=0, min_obj_area=6, max_obj_area=600, is_volume=False) spots = lmp.run(max_imgs)
imageio.imsave(args.out_path, imarr.max(0)) else: imarr_orig = np.copy(imarr) #adds a "channel" dimension imarr = np.expand_dims(imarr, axis=0) #adds a "round" dimension imarr = np.expand_dims(imarr, axis=0) thresh = np.percentile(imarr, args.intensity_ptile) imarr[imarr > thresh] = thresh + ( np.log(imarr[imarr > thresh] - thresh) / np.log(1.1)).astype( imarr.dtype) bandpass = Filter.Bandpass(lshort=.5, llong=7, threshold=0.0) lmp_small = FindSpots.LocalMaxPeakFinder( min_distance=args.small_peak_dist, stringency=0, min_obj_area=args.small_peak_min, max_obj_area=args.small_peak_max, min_num_spots_detected=2500, is_volume=False, verbose=False) lmp_big = FindSpots.LocalMaxPeakFinder(min_distance=args.big_peak_dist, stringency=0, min_obj_area=args.big_peak_min, max_obj_area=args.big_peak_max, min_num_spots_detected=2500, is_volume=False, verbose=False) sd = Codebook.synthetic_one_hot_codebook(n_round=1, n_channel=1, n_codes=1) decoder = DecodeSpots.PerRoundMaxChannel(codebook=sd) block_dim = int(max(imarr.shape) * args.block_dim_fraction)
def find_spots(input_path, output_path, intensity_percentile=99.995, filter_width=2, small_peak_min=4, small_peak_max=100, big_peak_min=25, big_peak_max=10000, small_peak_dist=2, big_peak_dist=0.75, block_dim_fraction=0.25, spot_pad_pixels=2, keep_existing=False): """ Find and keep only spots from stitched images. """ image_stack = imageio.volread(input_path) print(image_stack.shape) thresholded_image = np.copy(image_stack) _, height, width = image_stack.shape threshold = np.percentile(thresholded_image, intensity_percentile) thresholded_image[thresholded_image > threshold] = threshold + ( np.log(thresholded_image[thresholded_image > threshold] - threshold) / np.log(1.1)).astype(thresholded_image.dtype) #May need to fiddle with the sigma parameters in each step, depending on the image. #High Pass Filter (Background Subtraction) gaussian_high_pass = Filter.GaussianHighPass(sigma=(1, filter_width, filter_width), is_volume=True) # enhance brightness of spots laplace_filter = Filter.Laplace(sigma=(0.2, 0.5, 0.5), is_volume=True) local_max_peakfinder_small = FindSpots.LocalMaxPeakFinder( min_distance=small_peak_dist, stringency=0, min_obj_area=small_peak_min, max_obj_area=small_peak_max, min_num_spots_detected=2500, is_volume=True, verbose=True) local_max_peakfinder_big = FindSpots.LocalMaxPeakFinder( min_distance=big_peak_dist, stringency=0, min_obj_area=big_peak_min, max_obj_area=big_peak_max, min_num_spots_detected=2500, is_volume=True, verbose=True) synthetic_codebook = Codebook.synthetic_one_hot_codebook(n_round=1, n_channel=1, n_codes=1) decoder = DecodeSpots.PerRoundMaxChannel(codebook=synthetic_codebook) block_dimension = int(max(thresholded_image.shape) * block_dim_fraction) spot_coordinates = np.zeros((0, 2), dtype=np.int64) # Finding spots by block_dimension x block_dimension size blocks # We skip the blocks at the edges with the - 1 (TODO: pad to full block size) for row in range(0, height - 1, block_dimension): for column in range(0, width - 1, block_dimension): # Cutout block and expand dimensions for channel and round block = thresholded_image[np.newaxis, np.newaxis, :, row:row + block_dimension, column:column + block_dimension] images = ImageStack.from_numpy(block) high_pass_filtered = gaussian_high_pass.run(images, verbose=False, in_place=False) laplace = laplace_filter.run(high_pass_filtered, in_place=False, verbose=False) small_spots = local_max_peakfinder_small.run( laplace.reduce({Axes.ZPLANE}, func="max")) decoded_intensities = decoder.run(spots=small_spots) small_spot_coords = np.stack([ decoded_intensities[Axes.Y.value], decoded_intensities[Axes.X.value] ]).T big_spots = local_max_peakfinder_big.run( laplace.reduce({Axes.ZPLANE}, func="max")) decoded_intensities = decoder.run(spots=big_spots) big_spot_coords = np.stack([ decoded_intensities[Axes.Y.value], decoded_intensities[Axes.X.value] ]).T all_spot_coords = np.vstack([small_spot_coords, big_spot_coords]) all_spot_coords += (row, column) spot_coordinates = np.vstack([spot_coordinates, all_spot_coords]) # Copying over only non-zero pixels image_spots = np.zeros((height, width), dtype=np.uint16) for spot_coordinate in spot_coordinates: spot_column, spot_row = spot_coordinate for row in range(max(0, spot_column - spot_pad_pixels), min(spot_column + spot_pad_pixels + 1, height)): for column in range(max(0, spot_row - spot_pad_pixels), min(spot_row + spot_pad_pixels + 1, width)): # Max projecting over z-stack image_spots[row, column] = image_stack[:, row, column].max(0) imageio.imsave(output_path, image_spots) return image_spots