def to_rgb_uint8(image, autoscale=True, force_color=None): ndim = image.ndim shape = image.shape try: colors = image.metadata['colors'] if len(colors) != shape[0]: colors = None except (AttributeError, KeyError): colors = None # 2D, grayscale if ndim == 2: force_color = [force_color] if force_color is not None else None image = to_rgb(image, force_color) # 2D non-interleaved RGB elif ndim == 3 and shape[0] in [3, 4]: image = image.transpose([1, 2, 0]) autoscale = False # 2D, has colors attribute elif ndim == 3 and colors is not None: image = to_rgb(image, colors, True) # 2D, RGB elif ndim == 3 and shape[2] in [3, 4]: pass # 2D, is multichannel elif ndim == 3 and shape[0] < 5: # guessing; could be small z-stack image = to_rgb(image, None, True) # 3D, grayscale elif ndim == 3: grayscale = True # 3D, has colors attribute elif ndim == 4 and colors is not None: image = to_rgb(image, colors, True) # 3D, RGB elif ndim == 4 and shape[3] in [3, 4]: pass # 3D, is multichannel elif ndim == 4 and shape[0] < 5: image = to_rgb(image, None, True) else: raise ValueError( "No display possible for frames of shape {0}".format(shape)) if autoscale: image = (normalize(image) * 255).astype(np.uint8) elif not np.issubdtype(image.dtype, np.uint8): if np.issubdtype(image.dtype, np.integer): max_value = np.iinfo(image.dtype).max # sometimes 12-bit images are stored as unsigned 16-bit if max_value == 2**16 - 1 and image.max() < 2**12: max_value = 2**12 - 1 image = (image / max_value * 255).astype(np.uint8) else: if image.max() > 1: # unnormalized floats! normalize anyway image = normalize(image) image = (image * 255).astype(np.uint8) return image
def annotate3d(centroids, image, **kwargs): """ An extension of annotate that annotates a 3D image and returns a scrollable stack for display in IPython. Parameters: see annotate. """ if plots_to_frame is None: raise ImportError('annotate3d requires pims 0.3 or later, please ' 'update pims') import matplotlib as mpl import matplotlib.pyplot as plt if image.ndim != 3 and not (image.ndim == 4 and image.shape[-1] in (3, 4)): raise ValueError("image has incorrect dimensions. Please input a 3D " "grayscale or RGB(A) image. For 2D image annotation, " "use annotate. Multichannel images can be " "converted to RGB using pims.display.to_rgb.") # We want to normalize on the full image and stop imshow from normalizing. normalized = (normalize(image) * 255).astype(np.uint8) imshow_style = dict(vmin=0, vmax=255) if '_imshow_style' in kwargs: kwargs['imshow_style'].update(imshow_style) else: kwargs['imshow_style'] = imshow_style # Suppress warning when >20 figures are opened max_open_warning = mpl.rcParams['figure.max_open_warning'] mpl.rc('figure', max_open_warning=0) figures = [] for i, imageZ in enumerate(normalized): fig = plt.figure() kwargs['ax'] = fig.gca() centroidsZ = centroids[(centroids['z'] > i - 0.5) & (centroids['z'] < i + 0.5)] annotate(centroidsZ, imageZ, **kwargs) figures.append(fig) result = plots_to_frame(figures, width=512, bbox_inches='tight') for fig in figures: plt.close(fig) mpl.rc('figure', max_open_warning=max_open_warning) return result
def annotate3d(centroids, image, **kwargs): """Annotates a 3D image and returns a scrollable stack for display in IPython. Parameters ---------- centroids : DataFrame including columns x and y image : image array (or string path to image file) circle_size : Deprecated. This will be removed in a future version of trackpy. Use `plot_style={'markersize': ...}` instead. color : single matplotlib color or a list of multiple colors default None invert : If you give a filepath as the image, specify whether to invert black and white. Default True. ax : matplotlib axes object, defaults to current axes split_category : string, parameter to use to split the data into sections default None split_thresh : single value or list of ints or floats to split particles into sections for plotting in multiple colors. List items should be ordered by increasing value. default None imshow_style : dictionary of keyword arguments passed through to the `Axes.imshow(...)` command the displays the image plot_style : dictionary of keyword arguments passed through to the `Axes.plot(...)` command that marks the features Returns ------- pims.Frame object containing a three-dimensional RGBA image See Also -------- annotate : annotation of 2D images """ if plots_to_frame is None: raise ImportError('annotate3d requires pims 0.3 or later. Please ' 'install/update pims') import matplotlib as mpl import matplotlib.pyplot as plt if image.ndim != 3 and not (image.ndim == 4 and image.shape[-1] in (3, 4)): raise ValueError("image has incorrect dimensions. Please input a 3D " "grayscale or RGB(A) image. For 2D image annotation, " "use annotate. Multichannel images can be " "converted to RGB using pims.display.to_rgb.") # We want to normalize on the full image and stop imshow from normalizing. normalized = (normalize(image) * 255).astype(np.uint8) imshow_style = dict(vmin=0, vmax=255) if '_imshow_style' in kwargs: kwargs['imshow_style'].update(imshow_style) else: kwargs['imshow_style'] = imshow_style max_open_warning = mpl.rcParams['figure.max_open_warning'] was_interactive = plt.isinteractive() try: # Suppress warning when many figures are opened mpl.rc('figure', max_open_warning=0) # Turn off interactive mode (else the closed plots leave emtpy space) plt.ioff() figures = [None] * len(normalized) for i, imageZ in enumerate(normalized): fig = plt.figure() kwargs['ax'] = fig.gca() centroidsZ = centroids[(centroids['z'] > i - 0.5) & (centroids['z'] < i + 0.5)] annotate(centroidsZ, imageZ, **kwargs) figures[i] = fig result = plots_to_frame(figures, width=512, close_fig=True, bbox_inches='tight') finally: # put matplotlib back in original state if was_interactive: plt.ion() mpl.rc('figure', max_open_warning=max_open_warning) return result
def annotate3d(centroids, image, **kwargs): """Annotates a 3D image and returns a scrollable stack for display in IPython. Parameters ---------- centroids : DataFrame including columns x and y image : image array (or string path to image file) circle_size : Deprecated. This will be removed in a future version of trackpy. Use `plot_style={'markersize': ...}` instead. color : single matplotlib color or a list of multiple colors default None invert : If you give a filepath as the image, specify whether to invert black and white. Default True. ax : matplotlib axes object, defaults to current axes split_category : string, parameter to use to split the data into sections default None split_thresh : single value or list of ints or floats to split particles into sections for plotting in multiple colors. List items should be ordered by increasing value. default None imshow_style : dictionary of keyword arguments passed through to the `Axes.imshow(...)` command the displays the image plot_style : dictionary of keyword arguments passed through to the `Axes.plot(...)` command that marks the features Returns ------- pims.Frame object containing a three-dimensional RGBA image See Also -------- annotate : annotation of 2D images """ if plots_to_frame is None: raise ImportError('annotate3d requires pims 0.3 or later, please ' 'update pims') import matplotlib as mpl import matplotlib.pyplot as plt if image.ndim != 3 and not (image.ndim == 4 and image.shape[-1] in (3, 4)): raise ValueError("image has incorrect dimensions. Please input a 3D " "grayscale or RGB(A) image. For 2D image annotation, " "use annotate. Multichannel images can be " "converted to RGB using pims.display.to_rgb.") # We want to normalize on the full image and stop imshow from normalizing. normalized = (normalize(image) * 255).astype(np.uint8) imshow_style = dict(vmin=0, vmax=255) if '_imshow_style' in kwargs: kwargs['imshow_style'].update(imshow_style) else: kwargs['imshow_style'] = imshow_style max_open_warning = mpl.rcParams['figure.max_open_warning'] was_interactive = plt.isinteractive() try: # Suppress warning when many figures are opened mpl.rc('figure', max_open_warning=0) # Turn off interactive mode (else the closed plots leave emtpy space) plt.ioff() figures = [None] * len(normalized) for i, imageZ in enumerate(normalized): fig = plt.figure() kwargs['ax'] = fig.gca() centroidsZ = centroids[(centroids['z'] > i - 0.5) & (centroids['z'] < i + 0.5)] annotate(centroidsZ, imageZ, **kwargs) figures[i] = fig result = plots_to_frame(figures, width=512, close_fig=True, bbox_inches='tight') finally: # put matplotlib back in original state if was_interactive: plt.ion() mpl.rc('figure', max_open_warning=max_open_warning) return result