def ruler_scale_factor(image, distance): """Returns the scale factor to convert from image coordinates to real world coordinates Args: image: BGR image of shape n x m x 3. distance: The real world size of the smallest graduation spacing Returns: float: Unitless scale factor from image coordinates to real world coordinates. """ height, width = image.shape[:2] image, mask = find_ruler(image) binary_image = mask * threshold(image, mask) if binary_image[mask].mean() > 0.5: binary_image[mask] = ~binary_image[mask] remove_large_components(binary_image, max(height, width)) edges = skeletonize(binary_image) hspace, angles, distances = hough_transform(edges) features = hspace_features(hspace, splits=16) angle_index = best_angles(np.array(features)) max_graduation_size = int(max(image.shape)) line_separation_pixels = find_grid(hspace[:, angle_index], max_graduation_size) logging.info('Line separation: {:.3f}'.format(line_separation_pixels)) return distance / line_separation_pixels
def crop_by_saliency(saliency_map, closing_size=11, border=50): binary_image = threshold(saliency_map) selem = np.ones((closing_size, closing_size)) binary_image = binary_closing(binary_image, selem) labels = label(binary_image) roi = max(regionprops(labels), key=attrgetter('filled_area')) border = 50 return (slice(roi.bbox[0] - border, roi.bbox[2] + 2 * border), slice(roi.bbox[1] - border, roi.bbox[3] + 2 * border))
points = shape[:, [1, 0]] perimeter = draw.polygon_perimeter(points[:, 0], points[:, 1]) draw.set_color(output_image, (perimeter[0].astype(np.int), perimeter[1].astype(np.int)), [0, 0, 1]) return output_image shapes = [smoothed_shape(read_shape(i)) for i in range(4)] aligned_shapes = procrustes.generalized_procrustes(shapes) shape_model = subspace_shape.learn(aligned_shapes, K=8) # wings_image = get_test_image('wing_area', 'cropped', 'unlabelled', '7.png') wings_image = get_test_image('wing_area', 'pinned', '1.png') edges = canny(wings_image[:, :, 1], 3) saliency = saliency_dragonfly(wings_image) thresh = threshold(saliency) edges = skeletonize(edges) gaps = scipy.ndimage.filters.convolve(1 * edges, np.ones((3, 3)), mode='constant', cval=False) edges[(gaps == 2) & ~edges] = True edges = skeletonize(edges) distance = scipy.ndimage.distance_transform_edt(~edges) labels = label(edges) regions = regionprops(labels) edge_lengths = np.zeros_like(labels) for i, edge in enumerate(sorted(regions, key=attrgetter('filled_area'))): edge_lengths[labels == edge.label] = edge.filled_area
points = shape[:, [1, 0]] perimeter = draw.polygon_perimeter(points[:, 0], points[:, 1]) draw.set_color(output_image, (perimeter[0].astype(np.int), perimeter[1].astype(np.int)), [0, 0, 1]) return output_image shapes = [smoothed_shape(read_shape(i)) for i in range(4)] aligned_shapes = procrustes.generalized_procrustes(shapes) shape_model = subspace_shape.learn(aligned_shapes, K=8) wings_image = get_test_image('wing_area', 'cropped', 'unlabelled', '7.png') # write_image('wings.png', wings_image) edges = canny(wings_image[:, :, 1], 3) saliency = saliency_dragonfly(wings_image) thresh = threshold(saliency) background = threshold(scipy.ndimage.distance_transform_edt(~thresh)) contours = find_contours(thresh, level=0.5) outline = max(contours, key=attrgetter('size')).astype(np.int) outline_image = np.zeros_like(edges) draw.set_color(outline_image, (outline[:, 0], outline[:, 1]), True) edges = skeletonize(edges) gaps = scipy.ndimage.filters.convolve(1 * edges, np.ones((3, 3)), mode='constant', cval=False) edges[(gaps == 2) & ~edges] = True edges = skeletonize(edges) # write_image('wing_edge.png', edges) distance = scipy.ndimage.distance_transform_edt(~edges)