def nfold(im, mod, img_plane=(0, 1), center=None, mask=None, fill_value=0.0): """ Returns an images averaged according to n-fold rotational symmetry. This can be used to boost the signal-to-noise ratio on an image with known symmetry, e.g. a diffraction pattern. Parameters ---------- im : array_like, ndim 2 Image to be azimuthally-symmetrized. center : array_like, shape (2,) or None, optional Coordinates of the center (in pixels). If ``center=None``, the image is rotated around its center, i.e. ``center=(rows / 2 - 0.5, cols / 2 - 0.5)``. mod : int Fold symmetry number. Valid numbers must be a divisor of 360. mask : `~numpy.ndarray` or None, optional Mask of `image`. The mask should evaluate to `True` (or 1) on valid pixels. If None (default), no mask is used. fill_value : float, optional In the case of a mask that overlaps with itself when rotationally averaged, the overlapping regions will be filled with this value. Returns ------- out : `~numpy.ndarray`, dtype float Symmetrized image. Raises ------ ValueError : If `mod` is not a divisor of 360 deg. """ if 360 % mod: raise ValueError( f"{mod}-fold rotational symmetry is not valid (not a divisor of 360)." ) angles = range(0, 360, int(360 / mod)) ax = (5, 3) # Data-type must be float because of use of NaN im = np.array(im, dtype=np.float, copy=True) # sort axis to have image plane "in front" im = im.swapaxes(0, img_plane[0]).swapaxes(1, img_plane[1]) if mask is not None: im[np.logical_not(mask)] = np.nan kwargs = { "center": center, "mode": "constant", "cval": 0, "preserve_range": True } # Use weights because edges of the pictures, which might be cropped by the rotation # should not count in the average wt = np.ones_like(im, dtype=np.uint8) weights = (skrotate(wt, angle, **kwargs) for angle in angles) rotated = (skrotate(im, angle, **kwargs) for angle in angles) avg = average(rotated, weights=weights) #, ignore_nan=True) # sort axis back to original positions avg = avg.swapaxes(img_plane[1], 1).swapaxes(img_plane[0], 0) return nan_to_num(avg, fill_value, copy=False)
def rotate(img, mask, angle): angle = np.random.uniform(-1,1) * angle imr = skrotate(img, angle, order=2) imr *= 255 maskr = skrotate(mask, angle, order=0) maskr *= 255 return imr.astype(np.uint8), maskr.astype(np.uint8)
def classify_image(sc, clf, rate, sliding_window, show_plot, rotate, ax): frame = read_image() if rotate: frame = skrotate(frame, rotate) if sliding_window: sections = list(slide(frame, (26,18), (5,5))) if show_plot: ax.clear() plt.imshow(frame) for coord, img in sections: if clf.predict(img.flatten().reshape(1, -1)) == 1: click.echo(coord) if show_plot: ax.add_patch( patches.Rectangle( coord, 18, 26, fill=False ) ) if show_plot: plt.draw() else: click.echo(clf.predict(frame.flatten().reshape(1, -1))) sc.enter(rate, 1, classify_image, (sc, clf, rate, sliding_window, show_plot, rotate, ax))
def rotate(proj_img_list, rotation_angle): '''rotates voronoi diagram according to the specified -rot_angle''' rotate_img_list = [] for img in proj_img_list: # do four 90 degree rotations if rot_angle = 0 if rotation_angle == 0: rotate_img_list.append(img) rotate_img_list.append(skrotate(img, angle=90)) rotate_img_list.append(skrotate(img, angle=180)) rotate_img_list.append(skrotate(img, angle=270)) elif rotation_angle == 1: # no rotation rotate_img_list.append(skrotate(img, angle=0)) elif rotation_angle == 2: # 90 degree rotation rotate_img_list.append(skrotate(img, angle=90)) elif rotation_angle == 3: # 180 degree rotation rotate_img_list.append(skrotate(img, angle=180)) elif rotation_angle == 4: # 270 degree rotation rotate_img_list.append(skrotate(img, angle=270)) return rotate_img_list
def rotate(proj_img_list, rotation_angle): rotate_img_list = [] for img in proj_img_list: if rotation_angle == 0: rotate_img_list.append(img) rotate_img_list.append(skrotate(img, angle=90)) rotate_img_list.append(skrotate(img, angle=180)) rotate_img_list.append(skrotate(img, angle=270)) elif rotation_angle == 1: rotate_img_list.append(skrotate(img, angle=0)) elif rotation_angle == 2: rotate_img_list.append(skrotate(img, angle=90)) elif rotation_angle == 3: rotate_img_list.append(skrotate(img, angle=180)) elif rotation_angle == 4: rotate_img_list.append(skrotate(img, angle=270)) return rotate_img_list
def symmetrize_rotation( self, rot_plane, order, spline_order=3, mode='wrap', method='xr', update=True, ret=False): # TODO: fix n-dimensional rotation and 0/nan handling if isinstance(rot_plane[0], int): rot_plane = rot_plane elif isinstance(rot_plane[0], str): rot_plane = [self.dims.index(x) for x in rot_plane] if 360 % order: raise ValueError( f"{order}-fold rotational symmetry is not valid (not a divisor of 360)." ) angles = range(0, 360, int(360 / order)) if method == 'np': symdata = self.data.copy( ) # np.array(self.data, dtype=np.float, copy=True) # bring plane on which to perform symmetrization to the "front" symdata = symdata.swapaxes(0, rot_plane[0]).swapaxes(1, rot_plane[1]) wt = np.ones_like(symdata, dtype=np.uint8) kwargs = { "mode": "constant", "cval": 0, "preserve_range": True } # TODO: re-introduce "center": center weights = [skrotate(wt, angle, **kwargs) for angle in angles] rotated = [skrotate(symdata, angle, **kwargs) for angle in angles] symdata = np.average(rotated, weights=weights, axis=0) symdata = symdata.swapaxes(rot_plane[1], 1).swapaxes(rot_plane[0], 0) elif method == 'xr': rotargs = { 'axes': rot_plane, 'reshape': True, 'output': None, 'order': spline_order, 'mode': mode, 'cval': 0.0, 'prefilter': True } rotated = [ xr.DataArray(data=sprotate(self.data, angle, **rotargs), coords=self.coords, dims=self.dims) for angle in angles ] symdata = xr.concat( [self.where(self > 0), *[r.where(r > 0) for r in rotated]], dim='temp').mean('temp') if update: self.data = symdata if ret: return symdata
def reflection(im, angle, img_plane=(0, 1), center=None, mask=None, fill_value=0.0): """ Symmetrize an image according to a reflection plane. Parameters ---------- im : array_like, ndim 2 Image to be symmetrized. angle : float Angle (in degrees) of the line that defines the reflection plane. This angle increases counter-clockwise from the positive x-axis. Angles larger that 360 are mapped back to [0, 360). Note that ``angle`` and ``angle + 180`` are equivalent. center : array_like, shape (2,) or None, optional Coordinates of the center (in pixels). If ``center=None``, the image is rotated around its center, i.e. ``center=(rows / 2 - 0.5, cols / 2 - 0.5)``. mask : `~numpy.ndarray` or None, optional Mask of `image`. The mask should evaluate to `True` (or 1) on valid pixels. If None (default), no mask is used. fill_value : float, optional In the case of a mask that overlaps with itself when rotationally averaged, the overlapping regions will be filled with this value. Returns ------- out : `~numpy.ndarray`, dtype float Symmetrized image. """ angle = float(angle) % 360 # Data-type must be float because of use of NaN im = np.array(im, dtype=np.float, copy=True) # sort axis to have image plane "in front" im = im.swapaxes(0, img_plane[0]).swapaxes(1, img_plane[1]) reflected = np.array(im, copy=True) # reflected image if mask is not None: invalid_pixels = np.logical_not(mask) im[invalid_pixels] = np.nan reflected[invalid_pixels] = np.nan kwargs = { "center": center, "mode": "constant", "cval": 0, "preserve_range": True } # Rotate the 'reflected' image so that the reflection line is the x-axis # Flip the image along the y-axis # Rotate back to original orientation # FIXME: this will not work properly for images that are offcenter # print(type(reflected)) reflected = skrotate(reflected, -angle, **kwargs) reflected = mirror(reflected, axes=0) reflected = skrotate(reflected, angle, **kwargs) out = nan_to_num(average([im, reflected]), fill_value, copy=False) out = out.swapaxes(img_plane[1], 1).swapaxes(img_plane[0], 0) return out