def test_moments_coords(): image = np.zeros((20, 20), dtype=np.double) image[13:17, 13:17] = 1 mu_image = moments(image) coords = np.array([[r, c] for r in range(13, 17) for c in range(13, 17)], dtype=np.double) mu_coords = moments_coords(coords) assert_almost_equal(mu_coords, mu_image)
def test_moments_coords(): image = np.zeros((20, 20), dtype=np.double) image[13:17, 13:17] = 1 mu_image = moments(image) coords = np.array([[r, c] for r in range(13, 17) for c in range(13, 17)], dtype=np.double) mu_coords = moments_coords(coords) assert_almost_equal(mu_coords, mu_image)
def centroids(points): """ Calculate X and Y centroids for a polygon using OpenCV input: list[tuple(x, y)] output: (centroidx, centroidy) """ # Determine moments from points using OpenCV im_moment = moments_coords(points, order=1) # Use moments to determine centroids cx = im_moment[1, 0] / im_moment[0, 0] cy = im_moment[0, 1] / im_moment[0, 0] return cx, cy
def test_moments_coords_dtype(dtype): image = np.zeros((20, 20), dtype=dtype) image[13:17, 13:17] = 1 expected_dtype = _supported_float_type(dtype) mu_image = moments(image) assert mu_image.dtype == expected_dtype coords = np.array([[r, c] for r in range(13, 17) for c in range(13, 17)], dtype=dtype) mu_coords = moments_coords(coords) assert mu_coords.dtype == expected_dtype assert_almost_equal(mu_coords, mu_image)
def get_max_contour_colors(contour, image_shape): """Determine number of colors to fill a contour with gradient or random colors""" # Determine contour perimeter try: rr, cc = draw.polygon_perimeter(contour[:, 0], contour[:, 1], shape=image_shape) perimeter = np.column_stack((rr, cc)) M = measure.moments_coords(perimeter) centroid = (M[1, 0] / M[0, 0], M[0, 1] / M[0, 0]) area_center = np.array([centroid]) # Determine distance of each point from the center D = distance.cdist(perimeter, area_center, metric='euclidean') # Get nunber of colors num_colors = int(np.max(D)) + 1 return num_colors except IndexError: return None
def draw_contour_(contour_img, contour, color, gradient_colors=("red", "blue"), min_size=10, filled=True, compute_mask=False): """ Draw a contour as optionally fill it with color. Differs from draw_contour() in that in addition to contour_img and mask also returns perimeter, area, contour center and distance of each pixel of area in a center""" # Determine contour perimeter mask, perimeter, area, centroid, D = None, None, None, None, None try: rr, cc = draw.polygon_perimeter(contour[:, 0], contour[:, 1], shape=contour_img.shape) if max(rr.shape[0], cc.shape[0]) < min_size: return perimeter = np.column_stack((rr, cc)) except IndexError: return None, None if not filled: # Contour not filled, draw it color = ensure_numeric_color(color) contour_img[rr, cc] = color else: # Get contour area rr, cc = draw.polygon(contour[:, 0], contour[:, 1], shape=contour_img.shape) if max(rr.shape[0], cc.shape[0]) < min_size: return area = np.column_stack((rr, cc)) if compute_mask: mask = np.zeros((contour_img.shape[0], contour_img.shape[1]), dtype="uint8") mask[rr, cc] = True if color != "random" and color != "gradient" and type(color) != list: # If a solid color provided, simply fill the polygon color = ensure_numeric_color(color) contour_img[rr, cc] = color else: # Gradient, random colors or list of colors specified # Define contour center M = measure.moments_coords(perimeter) centroid = (M[1, 0] / M[0, 0], M[0, 1] / M[0, 0]) area_center = np.array([centroid]) # Determine distance of each area point from the center D = distance.cdist(area, area_center, metric='euclidean') # Define colors num_colors = int(np.max(D)) + 1 colours = ensure_numeric_color(color, gradient_colors, num_colors) # Fill polygon by colors specified by distance of each pixel from the center for n, p in enumerate(area): d = int(D[n]) c = colours[d] if len(colours) > 1 else colours[0] contour_img[p[0], p[1]] = c if compute_mask: return contour_img, mask, perimeter, area, centroid, D else: return contour_img, None, perimeter, area, centroid, D
quoting=csv.QUOTE_MINIMAL) post_writer.writerow([ 'X center (um)', 'Y center (um)', 'Z minimum (um)', 'Z maximum (um)', 'Radius (um)' ]) for layer in range(0, num): data = np.squeeze(bin_index[:, :, start + step * layer]) contours = measure.find_contours(data, 0.5) post_data = [] post_idx = 0 for contour in contours: M = measure.moments_coords(contour, order=1) area = M[0, 0] radius = np.sqrt(area / np.pi) center_x = (M[1, 0] / M[0, 0] ) * device_size_lateral_um / device_voxels_lateral center_y = (M[0, 1] / M[0, 0] ) * device_size_lateral_um / device_voxels_lateral draw_circle = plt.Circle((center_x, center_y), radius, fill=False, edgecolor='r', linewidth=2) z_start_um = layer * um_per_layer z_end_um = z_start_um + um_per_layer
def find_centre(c): moments = measure.moments_coords(c) m0 = int(moments[1, 0] / moments[0, 0]) m1 = int(moments[0, 1] / moments[0, 0]) return (m0, m1)
def get_mu(coord): """return moments from coordinates""" return measure.moments_coords(coord)