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 make_input_image(img, save_file_name, message = None, time_stamp = None, x_start = 440, y_start = 70, lamda = 1.33, uml=50, width = 6, fontsize = 18, y_time_stamp = 20): """mark the input image, img, at position needletip with a 50µm white scale bar. time_stamp and message are passed as content to plt.text. marked image saved to save_file_name. DONE: checked that the output still has 512x512 pixels. x_start and y_start are for the scale bar position and have units of pixels. time stamp might be '+{} min '.format(str(int(np.around(tmax,0))))', for instance. lamda is lengthscale in microns per pixel. uml is the length of the scale bar in microns width is the width of the scalebar""" #parse inputs # lamda = 1.33 #microns per pixel for 10X magnification ycoord = y_start#pixel xstart = x_start#pixel # dt = 1 #minutes per frame # self.lamda = 1.33 #microns per pixel # self.dt = 1 #minutes per frame # self.frm = -1 # lamda = self.lamda#1.33 #send grayscale/1_channel images to rgb if len(img.shape)==2: img = pims.to_rgb(img.copy()) mydpi=128#64 mult = 1.32642487 #calculate scale bar length s = 3 # uml = 50#um pxl = uml/lamda#pxl #plot image and mark fig = plt.figure(num=None, frameon=False, figsize=(mult*img.shape[0]/mydpi, mult*img.shape[1]/mydpi), dpi=mydpi, facecolor='w', edgecolor='k') #alternative initialization #fig = plt.figure(num=None, figsize=(8, 8), dpi=64, facecolor='w', edgecolor='k') ax = fig.add_subplot(111) ax.imshow(img) ax.axis('off') ## add scale lines l1 = lines.Line2D([xstart, xstart+pxl], [ycoord, ycoord], color='white', linewidth=width, solid_capstyle='butt') fig.lines.extend([l1]) ## add text boxes if message is not None: ax.text(x=15, y=50, c='white', s=message, weight='bold', fontsize=fontsize, horizontalalignment='left', verticalalignment='center') if time_stamp is not None: ax.text(x=15, y=y_time_stamp, c='white', s=time_stamp, weight='bold', fontsize=fontsize, horizontalalignment='left', verticalalignment='center') plt.savefig(save_file_name, bbox_inches='tight', pad_inches=0.) return True
def highlight(position, flow_in, flow_out, background_frame, r_c_mat=None, hue_scale=80, hue_scale_red=70, hue_scale_blue=90, r_thresh = 0, **kwargs): '''visualize overlay of outward optical flow over the background channel. for masking the highlight to not consider r_thresh pixels from the center, the center must also be provided by r_c_mat as returned by get_r_hat_mat Example Usage: img = highlight(position=(x_coord, y_coord), flow_in=flow_in, flow_out=flow_out, background_frame=frame_2) ''' #TODO: use more sophisticated/correct kwargs parsing as done elsewhere #TODO: add r_thresh set method to argument of highlight mfo = flow_out mfi = flow_in width=background_frame.shape[0] height=background_frame.shape[1] filt = np.zeros([width,height,3]) #3 channels for rgb img = pims.to_rgb(background_frame) if r_c_mat == None: r_filter = 1 elif r_c_mat.shape == (width, height): r_filter = (r_c_mat>r_thresh) else: r_filter = 1 #TODO(better): use colormap such as # im_color = cv2.applyColorMap(im_gray, cv2.COLORMAP_COOL) #subtract nonblue for outward flow filt[:,:,0] = hue_scale_blue*mfo*r_filter filt[:,:,1] = hue_scale_blue*mfo*r_filter #subtract nonred for inward flow filt[:,:,1] = hue_scale_red*mfi*r_filter filt[:,:,2] = hue_scale_red*mfi*r_filter # filt[:,:,2] = filt[:,:,2]/np.max(filt[:,:,2])+1 flowing = np.add(img, -filt) #clip to 0 to 255 # if np.isnan(np.sum(out_vec)): # out_vec = out_vec[~np.isnan(out_vec)] # just remove nan elements from out_vec flowing[flowing<0] = 0 flowing[flowing>255] = 255 #highlight needletip with a yellow x #TODO: make marker parameters accessable through **kwargs return drawMarker(flowing, position = position, color = (255,255,0), markerType = 1 , markerSize = 15, thickness = 2)
def imshow(image, ax=None, mpp=1., origin=(0, 0), ax_labels=False, **kwargs): """Show an image. Origin is in pixels.""" _imshow_style = dict(origin='lower', interpolation='nearest', cmap=plt.cm.gray, aspect='equal') _imshow_style.update(kwargs) if not is_rgb(image, ndim=2): try: from pims import to_rgb except ImportError: raise ImportError( "Imshow requires PIMS to display a non-RGB image") image = to_rgb(image, kwargs.pop('colors', None), normed=False) / 255. shape = image.shape[:2] mpp = validate_tuple(mpp, ndim=2) origin = validate_tuple(origin, ndim=2) # extent is defined on the outer edges of the pixels # we want the center of the topleft to intersect with the origin extent = [ (origin[1] - 0.5) * mpp[1], (origin[1] + shape[1] - 0.5) * mpp[1], (origin[0] - 0.5) * mpp[0], (origin[0] + shape[0] - 0.5) * mpp[0] ] ax.imshow(image, extent=extent, **_imshow_style) ax.set_xlim(extent[0], extent[1]) ax.set_ylim(extent[3], extent[2]) if ax_labels: if mpp == 1.: fmt = '{} [px]' elif mpl.rcParams['text.usetex']: fmt = r'{} [\textmu m]' else: fmt = r'{} [\xb5m]' ax.set_xlabel(fmt.format('x')) ax.set_ylabel(fmt.format('y')) return ax
def imshow(image, ax=None, mpp=1., origin=(0, 0), ax_labels=False, **kwargs): """Show an image. Origin is in pixels.""" _imshow_style = dict(origin='lower', interpolation='nearest', cmap=plt.cm.gray, aspect='equal') _imshow_style.update(kwargs) if not is_rgb(image, ndim=2): try: from pims import to_rgb except ImportError: raise ImportError("Imshow requires PIMS to display a non-RGB image") image = to_rgb(image, kwargs.pop('colors', None), normed=False) / 255. shape = image.shape[:2] mpp = validate_tuple(mpp, ndim=2) origin = validate_tuple(origin, ndim=2) # extent is defined on the outer edges of the pixels # we want the center of the topleft to intersect with the origin extent = [(origin[1] - 0.5) * mpp[1], (origin[1] + shape[1] - 0.5) * mpp[1], (origin[0] - 0.5) * mpp[0], (origin[0] + shape[0] - 0.5) * mpp[0]] ax.imshow(image, extent=extent, **_imshow_style) ax.set_xlim(extent[0], extent[1]) ax.set_ylim(extent[3], extent[2]) if ax_labels: if mpp == 1.: fmt = '{} [px]' elif mpl.rcParams['text.usetex']: fmt = r'{} [\textmu m]' else: fmt = r'{} [\xb5m]' ax.set_xlabel(fmt.format('x')) ax.set_ylabel(fmt.format('y')) return ax
def imshow3d(image3d, mode='max', center=None, mpp=1., origin=(0, 0, 0), axs=None, ax_labels=False, **kwargs): """Shows the xy, xz, and yz projections of a 3D image. Parameters ---------- image3d : ndarray mode : {'max' | 'slice'} aspect : number aspect ratio of pixel size z / xy. Default 1. center : tuple in pixels mpp : tuple microns per pixel origin : tuple coordinate of the (center of the) topleft pixel (in pixels) spacing : number spacing between images axs : t Returns ------- fig, (ax_xy, ax_zy, ax_zx, ax_extra) """ imshow_style = dict(origin='lower', interpolation='nearest', cmap=plt.cm.gray, aspect='auto') imshow_style.update(kwargs) if not is_rgb(image3d, ndim=3): try: from pims import to_rgb except ImportError: raise ImportError( "Imshow requires PIMS to display a non-RGB image") image3d = to_rgb(image3d, kwargs.pop('colors', None), normed=False) / 255. shape = image3d.shape[:3] mpp = validate_tuple(mpp, ndim=3) origin = validate_tuple(origin, ndim=3) ax_xy, ax_zy, ax_zx, ax_extra = axs if mode == 'max': image_xy = image3d.max(0) image_zx = image3d.max(1) image_zy = image3d.max(2) elif mode == 'slice': center_i = [int(round(c - o)) for c, o in zip(center, origin)] center_i = [min(max(c, 0), sh - 1) for c, sh in zip(center_i, shape)] image_xy = image3d[center_i[0], :, :] image_zx = image3d[:, center_i[1], :] image_zy = image3d[:, :, center_i[2]] else: raise ValueError('Unknown mode "{}"'.format(mode)) if image_zy.ndim == 3: image_zy = np.transpose(image_zy, (1, 0, 2)) else: image_zy = image_zy.T # extent is defined on the outer edges of the pixels # we want the center of the topleft to intersect with the origin extent = [ (origin[2] - 0.5) * mpp[2], (origin[2] + shape[2] - 0.5) * mpp[2], (origin[1] - 0.5) * mpp[1], (origin[1] + shape[1] - 0.5) * mpp[1], (origin[0] - 0.5) * mpp[0], (origin[0] + shape[0] - 0.5) * mpp[0] ] extent_xy = extent[:4] extent_zx = extent[:2] + extent[4:6] extent_zy = extent[4:6] + extent[2:4] ax_xy.imshow(image_xy, extent=extent_xy, **imshow_style) ax_zx.imshow(image_zx, extent=extent_zx, **imshow_style) ax_zy.imshow(image_zy, extent=extent_zy, **imshow_style) ax_xy.set_xlim(extent[0], extent[1], auto=False) ax_xy.set_ylim(extent[3], extent[2], auto=False) ax_zy.set_xlim(extent[4], extent[5], auto=False) ax_zy.set_ylim(extent[3], extent[2], auto=False) ax_zx.set_xlim(extent[0], extent[1], auto=False) ax_zx.set_ylim(extent[5], extent[4], auto=False) if ax_labels: if mpp == 1.: fmt = '{} [px]' elif mpl.rcParams['text.usetex']: fmt = r'{} [\textmu m]' else: fmt = r'{} [\xb5m]' ax_xy.set_xlabel(fmt.format('x')) ax_xy.set_ylabel(fmt.format('y')) ax_zy.set_xlabel(fmt.format('z')) ax_zx.set_ylabel(fmt.format('z')) return axs
def imshow3d(image3d, mode='max', center=None, mpp=1., origin=(0, 0, 0), axs=None, ax_labels=False, **kwargs): """Shows the xy, xz, and yz projections of a 3D image. Parameters ---------- image3d : ndarray mode : {'max' | 'slice'} aspect : number aspect ratio of pixel size z / xy. Default 1. center : tuple in pixels mpp : tuple microns per pixel origin : tuple coordinate of the (center of the) topleft pixel (in pixels) spacing : number spacing between images axs : t Returns ------- fig, (ax_xy, ax_zy, ax_zx, ax_extra) """ imshow_style = dict(origin='lower', interpolation='nearest', cmap=plt.cm.gray, aspect='auto') imshow_style.update(kwargs) if not is_rgb(image3d, ndim=3): try: from pims import to_rgb except ImportError: raise ImportError("Imshow requires PIMS to display a non-RGB image") image3d = to_rgb(image3d, kwargs.pop('colors', None), normed=False) / 255. shape = image3d.shape[:3] mpp = validate_tuple(mpp, ndim=3) origin = validate_tuple(origin, ndim=3) ax_xy, ax_zy, ax_zx, ax_extra = axs if mode == 'max': image_xy = image3d.max(0) image_zx = image3d.max(1) image_zy = image3d.max(2) elif mode == 'slice': center_i = [int(round(c - o)) for c, o in zip(center, origin)] center_i = [min(max(c, 0), sh - 1) for c, sh in zip(center_i, shape)] image_xy = image3d[center_i[0], :, :] image_zx = image3d[:, center_i[1], :] image_zy = image3d[:, :, center_i[2]] else: raise ValueError('Unknown mode "{}"'.format(mode)) if image_zy.ndim == 3: image_zy = np.transpose(image_zy, (1, 0, 2)) else: image_zy = image_zy.T # extent is defined on the outer edges of the pixels # we want the center of the topleft to intersect with the origin extent = [(origin[2] - 0.5) * mpp[2], (origin[2] + shape[2] - 0.5) * mpp[2], (origin[1] - 0.5) * mpp[1], (origin[1] + shape[1] - 0.5) * mpp[1], (origin[0] - 0.5) * mpp[0], (origin[0] + shape[0] - 0.5) * mpp[0]] extent_xy = extent[:4] extent_zx = extent[:2] + extent[4:6] extent_zy = extent[4:6] + extent[2:4] ax_xy.imshow(image_xy, extent=extent_xy, **imshow_style) ax_zx.imshow(image_zx, extent=extent_zx, **imshow_style) ax_zy.imshow(image_zy, extent=extent_zy, **imshow_style) ax_xy.set_xlim(extent[0], extent[1], auto=False) ax_xy.set_ylim(extent[3], extent[2], auto=False) ax_zy.set_xlim(extent[4], extent[5], auto=False) ax_zy.set_ylim(extent[3], extent[2], auto=False) ax_zx.set_xlim(extent[0], extent[1], auto=False) ax_zx.set_ylim(extent[5], extent[4], auto=False) if ax_labels: if mpp == 1.: fmt = '{} [px]' elif mpl.rcParams['text.usetex']: fmt = r'{} [\textmu m]' else: fmt = r'{} [\xb5m]' ax_xy.set_xlabel(fmt.format('x')) ax_xy.set_ylabel(fmt.format('y')) ax_zy.set_xlabel(fmt.format('z')) ax_zx.set_ylabel(fmt.format('z')) return axs
def array_to_pixmap(self, array): array = np.swapaxes(pims.to_rgb(array), 0, 1) image = pixmap_from_array(array) return image