def polar_analysis(data, image, label=None, threshold=0.5): """ A routine that extracts one contour (default being biggest) to analyse it and plot in polar coordinates ARGS : data (pd.DataFrame) resulting from analyse_frame_dissolution image (np 2d array) the padded image from analyse_frame_dissolution label (optional) the label of the object we want to study. Default is biggest object RETURNS : interface_data (pd.DataFrame) containing theta and the various definitions of r """ # Handling the inputs interface_data = pd.DataFrame({ 'theta': np.linspace(-np.pi, np.pi, 360), 'r_fourier': np.nan * np.ones(360), 'r_max_gradient': np.nan * np.ones(360) }) polar_images = { 'polar': [np.zeros((360, 100))], 'polar_thresholded': [np.zeros((360, 100))] } if len(data) > 0: if not label: obj = data.iloc[np.argmax(data['rad'])] else: obj = data[data['label'] == label] if len( image ) == 1: # Probably means image was "Bokehified" : img --> [img], we need to revert that image = image[0] contour = obj['contour'] contour_x, contour_y = (contour[:, 1] - obj['x_px']) / obj['rad'], ( contour[:, 0] - obj['y_px']) / obj['rad'] r_th, theta_th = np.sqrt(contour_x**2 + contour_y**2), np.arctan2( contour_y, contour_x) amps, phs = proj_fourier(r_th[np.argsort(theta_th)], np.sort(theta_th)) r_fourier = build_fourier(amps, phs, np.linspace(-np.pi, np.pi, 360)) max_radius = 1.4 polar_image = sktr.warp_polar(image, center=(obj['y_px'], obj['x_px']), radius=max_radius * obj['rad'], output_shape=(360, 100)).transpose() polar_img_th = polar_image > threshold polar_image_grad = np.diff(skfi.gaussian(polar_image, sigma=2, preserve_range=True, mode='reflect'), axis=0) r_max_gradient = (np.argmax(polar_image_grad, axis=0) + 0.5) / np.shape(polar_image)[0] * max_radius interface_data['r_fourier'] = r_fourier interface_data['r_max_gradient'] = r_max_gradient polar_images['polar'] = [polar_image] polar_images['polar_thresholded'] = [polar_img_th] return interface_data, polar_images
def compute_log_polar_tf( image: np.ndarray, wrexp: float = 3, order: int = 5 ) -> np.ndarray: """Compute log-scaled polar coordinate transform of center shifted FFT. Parameters ---------- image : numpy.ndarray The input image to transform (expects center shifted FFT magnitude) wrexp : float, optional Cutoff exponent factor for higher frequencies, larger wrexp => faster computation min value: 1 Returns ------- numpy.ndarray log-scaled polar transformed of the input image """ warp_radius = ImageMethods.compute_warp_radius(min(image.shape), wrexp) # NOTE: we can use 5th order approximation here, as a the computation time on our image # only increases lineary with the interpolation order, whereas the mean squared error # decreases pretty much exponentially warped = warp_polar( image, radius=warp_radius, output_shape=image.shape, scaling="log", order=order, ) # FFT magnitude is symmetric => div by 2 return cast(np.ndarray, warped[: image.shape[0] // 2, :])
def getPolar(grayimg): """ transformation into polar coordinates note: angles are transformed into x-axis """ radius = int(len(grayimg) / 2) return warp_polar(grayimg, radius=radius).T
def image_to_polar( image, delta_r=1.0, delta_theta=1, max_r=None, find_direct_beam=False, direct_beam_position=None, ): """Convert a single image to polar coordinates including the option to find the direct beam and take this as the center. Parameters ---------- image : 2D numpy.ndarray Experimental image delta_r : float, optional The radial increment, determines how many columns will be in the polar image. delta_theta : float, optional The angular increment, determines how many rows will be in the polar image max_r : float, optional The maximum radial distance to include, in units of pixels. By default this is the distance from the center of the image to a corner in pixel units and rounded up to the nearest integer find_direct_beam : bool Whether to roughly find the direct beam using `find_beam_center_blur` using a gaussian smoothing with sigma = 1. If False then the middle of the image will be the center for the polar transform. direct_beam_position : 2-tuple (x, y) position of the central beam in pixel units. This overrides the automatic find_maximum parameter if set to True. Returns ------- polar_image : 2D numpy.ndarray Array representing the polar transform of the image with shape (360/delta_theta, max_r/delta_r) """ half_x, half_y = image.shape[1] / 2, image.shape[0] / 2 if direct_beam_position is not None: c_x, c_y = direct_beam_position elif find_direct_beam: c_y, c_x = find_beam_center_blur(image, 1) else: c_x, c_y = half_x, half_y output_shape = get_polar_pattern_shape(image.shape, delta_r, delta_theta, max_r=max_r) return warp_polar( image, center=(c_y, c_x), output_shape=output_shape, radius=max_r, preserve_range=True, )
def test_linear_warp_polar(): radii = [5, 10, 15, 20] image = np.zeros([51, 51]) for rad in radii: rr, cc, val = circle_perimeter_aa(25, 25, rad) image[rr, cc] = val warped = warp_polar(image, radius=25) profile = warped.mean(axis=0) peaks = peak_local_max(profile) assert np.alltrue([peak in radii for peak in peaks])
def _find_angle(img_original, img_deformed): # First, band-pass filter both images image = img_original rts_image = img_deformed image = difference_of_gaussians(image, 5, 15) rts_image = difference_of_gaussians(rts_image, 5, 15) # window images wimage = image * window('hann', image.shape) rts_wimage = rts_image * window('hann', rts_image.shape) # work with shifted FFT magnitudes image_fs = np.abs(fftshift(fft2(wimage))) rts_fs = np.abs(fftshift(fft2(rts_wimage))) # Create log-polar transformed FFT mag images and register shape_or = image_fs.shape shape_def = rts_fs.shape radius_or = shape_or[0] // 8 radius_def = shape_def[0] // 8 # only take lower frequencies warped_image_fs = warp_polar(image_fs, radius=radius_or, output_shape=shape_or, scaling='log', order=0) warped_rts_fs = warp_polar(rts_fs, radius=radius_def, output_shape=shape_or, scaling='log', order=0) warped_image_fs = warped_image_fs[:shape_or[ 0], :] # only use half of FFT warped_rts_fs = warped_rts_fs[:shape_or[0], :] shifts, error, phasediff = phase_cross_correlation(warped_image_fs, warped_rts_fs, upsample_factor=10) # Use translation parameters to calculate rotation and scaling parameters shiftr, shiftc = shifts[:2] recovered_angle = (360 / shape_or[0]) * shiftr return recovered_angle
def test_invalid_dimensions_polar(): with testing.raises(ValueError): warp_polar(np.zeros((10, 10, 3)), (5, 5)) with testing.raises(ValueError): warp_polar(np.zeros((10, 10)), (5, 5), multichannel=True) with testing.raises(ValueError): warp_polar(np.zeros((10, 10, 10, 3)), (5, 5), multichannel=True)
def azimuthal_avg(data_2d): ''' AZIMUTHAL_AVG Azimuthal average of a 2D square image azimuthal_avg(data_2d) :param data_2d: square 2D numpy array :return: numpy 1D array ''' Np = int(np.floor((len(data_2d) + 1) / 2)) azimuthal_avg = np.sum(warp_polar(data_2d), 0) return azimuthal_avg[0:(Np - 1)] #imshow(x_m, I, zoom=1.0)
def test_log_warp_polar(): radii = [np.exp(2), np.exp(3), np.exp(4), np.exp(5), np.exp(5)-1, np.exp(5)+1] radii = [int(x) for x in radii] image = np.zeros([301, 301]) for rad in radii: rr, cc, val = circle_perimeter_aa(150, 150, rad) image[rr, cc] = val warped = warp_polar(image, radius=200, scaling='log') profile = warped.mean(axis=0) peaks_coord = peak_local_max(profile) peaks_coord.sort(axis=0) gaps = peaks_coord[1:] - peaks_coord[:-1] assert np.alltrue([x >= 38 and x <= 40 for x in gaps])
def cartesian_to_polar( interpolated_data_cartesian: ndarray, extent_cartesian: Tuple[float, float, float, float], ) -> Tuple[ndarray, Tuple[float, float, float, float]]: """Convert interpolated Cartesian pixel grid to polar coordinates. Parameters ---------- interpolated_data_cartesian The interpolated data on a Cartesian grid. extent_cartesian The extent in Cartesian space as (xmin, xmax, ymin, ymax). It must be square. Returns ------- interpolated_data_polar The interpolated data on a polar grid (R, phi). extent_polar The extent on a polar grid (0, Rmax, 0, 2π). """ if transform is None: logger.error( 'cartesian_to_polar requires skimage (scikit-image) which is unavailable\n' 'try pip install scikit-image --or-- conda install scikit-image' ) data, extent = interpolated_data_cartesian, extent_cartesian if not np.allclose(extent[1] - extent[0], extent[3] - extent[2]): raise ValueError('Bad polar plot: x and y have different scales') num_pixels = data.shape radius_pix = 0.5 * data.shape[0] data = transform.warp_polar(data, radius=radius_pix) radius = 0.5 * (extent[1] - extent[0]) extent_polar = (0, radius, 0, 2 * np.pi) x_grid = np.linspace(*extent[:2], data.shape[0]) y_grid = np.linspace(*extent[2:], data.shape[1]) spl = RectBivariateSpline(x_grid, y_grid, data) x_regrid = np.linspace(extent[0], extent[1], num_pixels[0]) y_regrid = np.linspace(extent[2], extent[3], num_pixels[1]) interpolated_data_polar = spl(x_regrid, y_regrid) return interpolated_data_polar, extent_polar
def to_polar(im, rmax, cenx, ceny): x = warp_polar( im, center=(cenx,ceny), radius=rmax) return np.rot90(x, k=3)
img2_gray = cv2.cvtColor(RotImg, cv2.COLOR_BGR2GRAY) img2_gray = np.flipud(img2_gray) center_hor = 150 center_ver = 0 center = (center_ver, center_hor) min_idx = 0 min_error = 10000 final_rotation = 0 rotated_polar = warp_polar(img2_gray, scaling='linear', center=center, radius=radius, multichannel=False) center2 = (center_ver, center_hor) image_polar = warp_polar(img1_gray, scaling='linear', center=center2, radius=radius, multichannel=False) """ for y in range(0, 360): if y >= 90-theta and y <= 90+theta: continue else:
def test_invalid_scaling_polar(): with testing.raises(ValueError): warp_polar(np.zeros((10, 10)), (5, 5), scaling='invalid') with testing.raises(ValueError): warp_polar(np.zeros((10, 10)), (5, 5), scaling=None)
from skimage.transform import rescale, warp_polar, rotate from skimage.util import img_as_float from mas.tracking import roll import matplotlib.pyplot as plt import numpy as np # radius must be large enough to capture useful info in larger image radius = 1500 angle = 53.7 scale = 2.2 image = data.retina() image = img_as_float(image) rotated = rotate(image, angle) rescaled = rescale(rotated, scale, multichannel=True) image_polar = warp_polar(image, radius=radius, scaling='log', multichannel=True) rescaled_polar = warp_polar(rescaled, radius=radius, scaling='log', multichannel=True) rescaled_polar = roll(rescaled_polar, (10, 10)) fig, axes = plt.subplots(2, 2, figsize=(8, 8)) ax = axes.ravel() ax[0].set_title("Original") ax[0].imshow(image) ax[1].set_title("Rotated and Rescaled") ax[1].imshow(rescaled) ax[2].set_title("Log-Polar-Transformed Original") ax[2].imshow(image_polar)
fn = 'images/orion_stacked_135mm.TIF' # img_pil = Image.open(fn) # img = np.array(img_pil) raw_img = tiff.imread(fn) scale = np.max(raw_img) img = raw_img.astype('float64') / scale print(img.shape, img.dtype) radius = np.max(img.shape) // 2 radius = np.sqrt(img.shape[0]**2 + img.shape[1]**2) / 2 - 200 print(radius) polar_img = warp_polar(img, radius=radius, multichannel=True) plt.subplot(4, 1, 1) plt.imshow(img) plt.subplot(4, 1, 2) plt.imshow(polar_img) plt.subplot(4, 1, 3) channel_means = np.zeros((polar_img.shape[1], 3)) for channel in range(3): for r in range(polar_img.shape[1]): # x = np.mean(polar_img[:, r, channel]) vals = polar_img[:, r, channel] filtered_vals = vals[np.where(vals > 0)]
def circsum(IMG): return np.sum(warp_polar(np.abs(IMG)**2), 0)
# translation difference that can be recovered by phase correlation. import numpy as np import matplotlib.pyplot as plt from skimage import data from skimage.registration import phase_cross_correlation from skimage.transform import warp_polar, rotate, rescale from skimage.util import img_as_float radius = 705 angle = 35 image = data.retina() image = img_as_float(image) rotated = rotate(image, angle) image_polar = warp_polar(image, radius=radius, channel_axis=-1) rotated_polar = warp_polar(rotated, radius=radius, channel_axis=-1) fig, axes = plt.subplots(2, 2, figsize=(8, 8)) ax = axes.ravel() ax[0].set_title("Original") ax[0].imshow(image) ax[1].set_title("Rotated") ax[1].imshow(rotated) ax[2].set_title("Polar-Transformed Original") ax[2].imshow(image_polar) ax[3].set_title("Polar-Transformed Rotated") ax[3].imshow(rotated_polar) plt.show() shifts, error, phasediff = phase_cross_correlation(image_polar, rotated_polar)
# translation difference that can be recovered by phase correlation. import numpy as np import matplotlib.pyplot as plt from skimage import data from skimage.registration import phase_cross_correlation from skimage.transform import warp_polar, rotate, rescale from skimage.util import img_as_float radius = 705 angle = 35 image = data.retina() image = img_as_float(image) rotated = rotate(image, angle) image_polar = warp_polar(image, radius=radius, multichannel=True) rotated_polar = warp_polar(rotated, radius=radius, multichannel=True) fig, axes = plt.subplots(2, 2, figsize=(8, 8)) ax = axes.ravel() ax[0].set_title("Original") ax[0].imshow(image) ax[1].set_title("Rotated") ax[1].imshow(rotated) ax[2].set_title("Polar-Transformed Original") ax[2].imshow(image_polar) ax[3].set_title("Polar-Transformed Rotated") ax[3].imshow(rotated_polar) plt.show() shifts, error, phasediff = phase_cross_correlation(image_polar, rotated_polar)
rts_wimage = rts_image * skimage.filters.window('hann', image.shape) inverted_wimage = skimage.filters.difference_of_gaussians( original_wimage, low_sigma, high_sigma) # work with shifted FFT magnitudes original_image_fs = np.abs(fftshift(fft2(original_wimage))) image_fs = np.abs(fftshift(fft2(wimage))) rts_fs = np.abs(fftshift(fft2(rts_wimage))) # Create log-polar transformed FFT mag images and register shape = image_fs.shape radius = shape[0] // 8 # only take lower frequencies warped_image_fs = warp_polar(image_fs, radius=radius, output_shape=shape, scaling='log', order=0) warped_rts_fs = warp_polar(rts_fs, radius=radius, output_shape=shape, scaling='log', order=0) warped_image_fs = warped_image_fs[:shape[0] // 2, :] # only use half of FFT warped_rts_fs = warped_rts_fs[:shape[0] // 2, :] shifts, error, phasediff = phase_cross_correlation(warped_image_fs, warped_rts_fs, upsample_factor=400) # Use translation parameters to calculate rotation and scaling parameters
import numpy as np import matplotlib.pyplot as plt from skimage import data from skimage.registration import phase_cross_correlation from skimage.transform import warp_polar, rotate, rescale from skimage.util import img_as_float from img import mydata as my radius = 705 angle = 35 image = my.retina() image = img_as_float(image) rotated = rotate(image, angle) image_polar = warp_polar(image, radius=radius, multichannel=True) rotated_polar = warp_polar(rotated, radius=radius, multichannel=True) fig, axes = plt.subplots(2, 2, figsize=(8, 8)) ax = axes.ravel() ax[0].set_title("Original") ax[0].imshow(image) ax[1].set_title("Rotated") ax[1].imshow(rotated) ax[2].set_title("Polar-Transformed Original") ax[2].imshow(image_polar) ax[3].set_title("Polar-Transformed Rotated") ax[3].imshow(rotated_polar) plt.show() shifts, error, phasediff = phase_cross_correlation(image_polar, rotated_polar) print("Expected value for counterclockwise rotation in degrees: " f"{angle}")
class VisualCompass(): def __init__(self): # Determines how often images are taken during learning phase self.snap_interval = 5 self.list_length = 0 self.prev_list_length = 0 # vector which stores visual snapshots (electric sheep free) self.stored_memories = [] self.stored_vector = [] self.cur_vector = Twist() self.min_ctr_val = 0 #Thresholds self.follow_flag = False self.memory_match = False self.lower_thresh = 0.70 self.upper_thresh = 1.00 self.ctr = 0 self.search_ctr = 1 self.cb_ctr = 0 self.var = 1 #similarity metric self.cur_score = 0 self.min_score = -1 #vectors used for search step self.stop_vector = Twist() self.stop_vector.angular.x = 0.0 self.stop_vector.angular.y = 0.0 self.stop_vector.angular.z = 0.0 self.stop_vector.linear.x = 0.0 self.stop_vector.linear.y = 0.0 self.stop_vector.linear.z = 0.0 #rotate at 30 degrees per second self.spin_vector = Twist() self.spin_vector.angular.x = 0.0 self.spin_vector.angular.y = 0.0 self.spin_vector.angular.z = 1.04 self.spin_vector.linear.x = 0.0 self.spin_vector.linear.y = 0.0 self.spin_vector.linear.z = 0.0 self.forward_vector = Twist() self.forward_vector.angular.x = 0.0 self.forward_vector.angular.y = 0.0 self.forward_vector.angular.z = 0.0 self.forward_vector.linear.x = 3.0 self.forward_vector.linear.y = 0.0 self.forward_vector.linear.z = 0.0 #name of the robot for use in publishing to topics #(perhaps load from ROS parameters in future?) self.robot_name = "omni" self.img_ob = Image() #create window for display of camera topic cv2.namedWindow("Camera View", 1) cv2.namedWindow("Unfurled View", 1) cv2.startWindowThread() self.bridge = CvBridge() startWindowThread() #define publisher and subscriber for the robot motion and camera feed respectively self.motion_pub = rospy.Publisher(self.robot_name + "/wheel_base_controller/cmd_vel", Twist, queue_size=10) self.image_sub = rospy.Subscriber(self.robot_name + "/camera1/image_raw", Image, self.callback, queue_size=10) #self.motion_sub = rospy.Subscriber(self.robot_name+ #"/wheel_base_controller/cmd_vel",Twist,self.callback queue_size=10) def callback(self, some_img): cam_view = self.get_img(some_img) def get_img(self, some_img): try: #convert image data from topic into open cv format input_img = self.bridge.imgmsg_to_cv2(some_img, "bgr8") except CvBridgeError, e: print e #convert to greyscale for simpler image processing (perhaps use colour images in future) grey_img = cvtColor(input_img, COLOR_BGR2GRAY) #im2 = self.unfurl_img(grey_img) #cv2.imshow("Unfurled View",im2) grey_img = warp_polar(grey_img, (160, 160), radius=160, output_shape=(160, (160 * math.pi))) cv2.imshow("Camera View", grey_img) return grey_img
def warp_polarUzaysal(): global filterimage warped = warp_polar(img, scaling='log') filterimage = warped io.imshow(warped) io.show()