def edge_detect(depth, color): # Get the gradient direction from the depth image graddir = grad_dir(depth) # plt.imshow(graddir) # plt.show() # kernel for dilation kernel = np.ones((5, 5), np.uint8) # Threshold the image so it is in the RGB color space bw2 = (((graddir - graddir.min()) / (graddir.max() - graddir.min())) * 255.9).astype(np.uint8) # removes the salt and pepper noise # by replacing pixels with # the median value of the area median = cv2.medianBlur(bw2, 9) # find edges with the canny edge detector bw2 = auto_canny(median) dilation2 = cv2.dilate(bw2, kernel, iterations=1) skel2 = morphology.skeletonize(dilation2 > 0) # Now run canny edge detector on the colour image # create a CLAHE object (Arguments are optional). # this does adaptive histogram equalization on the image clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) cl1 = clahe.apply(color) # median = cv2.medianBlur(bw2,5) # bw1 = cv2.GaussianBlur(cl1, (3,3), 0) # Perform canny edge detection on colour image, twice # 1. Detect outlines and fill with close function # 2. Detect outlines of now filled contoured image bw1 = auto_canny(cl1) closing = cv2.morphologyEx(bw1, cv2.MORPH_CLOSE, kernel, iterations=6) # dilation1 = cv2.dilate(bw1,kernel,iterations = 1) # skel1 = morphology.skeletonize(dilation1 > 0) bw1 = auto_canny(closing) # combine the edges from the color image and the depth image orop = (np.logical_or(bw1, skel2)).astype('uint8') # display results plt.subplot(1, 2, 1), plt.imshow(graddir, cmap='jet') plt.title('gradient dir'), plt.xticks([]), plt.yticks([]) plt.subplot(1, 2, 2), plt.imshow(median, cmap='gray') plt.title('blurred image'), plt.xticks([]), plt.yticks([]) plt.show() # dilate and skeletonize on combined image kernel = np.ones((5, 5), np.uint8) dilation = cv2.dilate(orop, kernel, iterations=1) img_out = morphology.skeletonize(dilation > 0) return img_out
def skeletonize_mitochondria(mch_channel): mch_collector = np.max(mch_channel, axis=0) # TODO: check max projection v.s. sum skeleton_labels = np.zeros(mch_collector.shape, dtype=np.uint8) # thresh = np.max(mch_collector)/2. thresh = threshold_otsu(mch_collector) # use adaptative threshold? => otsu seems to be sufficient in this case skeleton_labels[mch_collector > thresh] = 1 skeleton2 = skeletonize(skeleton_labels) skeleton, distance = medial_axis(skeleton_labels, return_distance=True) active_threshold = np.mean(mch_collector[skeleton_labels]) * 5 # print active_threshold transform_filter = np.zeros(mch_collector.shape, dtype=np.uint8) transform_filter[np.logical_and(skeleton > 0, mch_collector > active_threshold)] = 1 skeleton = transform_filter * distance skeleton_ma = np.ma.masked_array(skeleton, skeleton > 0) skeleton_convolve = ndi.convolve(skeleton_ma, np.ones((3, 3)), mode='constant', cval=0.0) divider_convolve = ndi.convolve(transform_filter, np.ones((3, 3)), mode='constant', cval=0.0) skeleton_convolve[divider_convolve > 0] = skeleton_convolve[divider_convolve > 0] / \ divider_convolve[divider_convolve > 0] new_skeleton = np.zeros_like(skeleton) new_skeleton[skeleton2] = skeleton_convolve[skeleton2] skeleton = new_skeleton return skeleton_labels, mch_collector, skeleton, transform_filter
def polylinesFromBinImage(img, minimum_cluster_size=6, remove_small_obj_size=3, reconnect_size=3, max_n_contours=None, max_len_contour=None, copy=True): ''' return a list of arrays of un-branching contours img -> (boolean) array optional: --------- minimum_cluster_size -> minimum number of pixels connected together to build a contour ##search_kernel_size -> TODO ##min_search_kernel_moment -> TODO numeric: ------------- max_n_contours -> maximum number of possible contours in img max_len_contour -> maximum contour length ''' assert minimum_cluster_size > 1 assert reconnect_size % 2, 'ksize needs to be odd' # assert search_kernel_size == 0 or search_kernel_size > 2 and search_kernel_size%2, 'kernel size needs to be odd' # assume array size parameters, is not given: if max_n_contours is None: max_n_contours = max(img.shape) if max_len_contour is None: max_len_contour = sum(img.shape[:2]) # array containing coord. of all contours: contours = np.zeros(shape=(max_n_contours, max_len_contour, 2), dtype=np.uint16) # if not search_kernel_size else np.float32) if img.dtype != np.bool: img = img.astype(bool) elif copy: img = img.copy() if remove_small_obj_size: remove_small_objects(img, remove_small_obj_size, connectivity=2, in_place=True) if reconnect_size: # remove gaps maximum_filter(img, reconnect_size, output=img) # reduce contour width to 1 img = skeletonize(img) n_contours = _populateContoursArray(img, contours, minimum_cluster_size) contours = contours[:n_contours] l = [] for c in contours: ind = np.zeros(shape=len(c), dtype=bool) _getValidInd(c, ind) # remove all empty spaces: l.append(c[ind]) return l
def skeletonize(mask): """Reduces binary objects to 1 pixel wide representations (skeleton) Inputs: mask = Binary image data Returns: skeleton = skeleton image :param mask: numpy.ndarray :return skeleton: numpy.ndarray """ # Store debug debug = params.debug params.debug = None # Convert mask to boolean image, rather than 0 and 255 for skimage to use it skeleton = skmorph.skeletonize(mask.astype(bool)) skeleton = skeleton.astype(np.uint8) * 255 # Reset debug mode params.debug = debug # Auto-increment device params.device += 1 if params.debug == 'print': print_image(skeleton, os.path.join(params.debug_outdir, str(params.device) + '_skeleton.png')) elif params.debug == 'plot': plot_image(skeleton, cmap='gray') return skeleton
def test_skeletonize_num_neighbours(self): # an empty image image = np.zeros((300, 300)) # foreground object 1 image[10:-10, 10:100] = 1 image[-100:-10, 10:-10] = 1 image[10:-10, -100:-10] = 1 # foreground object 2 rs, cs = draw.bresenham(250, 150, 10, 280) for i in range(10): image[rs + i, cs] = 1 rs, cs = draw.bresenham(10, 150, 250, 280) for i in range(20): image[rs + i, cs] = 1 # foreground object 3 ir, ic = np.indices(image.shape) circle1 = (ic - 135)**2 + (ir - 150)**2 < 30**2 circle2 = (ic - 135)**2 + (ir - 150)**2 < 20**2 image[circle1] = 1 image[circle2] = 0 result = skeletonize(image) # there should never be a 2x2 block of foreground pixels in a skeleton mask = np.array([[1, 1], [1, 1]], np.uint8) blocks = correlate(result, mask, mode='constant') assert not numpy.any(blocks == 4)
def formatTS(start, stop, r, useIntersects=True): aStarts = {} X = [] Y = [] coords = [] sigNum = [] strcArr = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] for sig in xrange(start, stop): if sig % 50 == 0: print sig path = np.array(sigs[sig]) imgO = imread(getFilePath(sig), as_grey=True) xs = [n for n in xrange()] plt.subplot(1, 2, 1) plt.imshow(imgO) plt.subplot(1, 2, 2) plt.imshow(guassian_filter(imgO, 1)) plt.show() thresh = 0.9 img = gaussian_filter(imgO, 1) < thresh imgX, imgY = np.nonzero(img) imgW = imgX.max() - imgX.min() imgH = imgY.max() - imgY.min() img = skeletonize(img) img = img[imgX.min() : imgX.max(), imgY.min() : imgY.max()] skltnSegs, nSkltnSegs = label(img, structure=strcArr) # print nSkltnSegs # plt.imshow(skltnSegs) # plt.show() imgO = imgO[imgX.min() : imgX.max(), imgY.min() : imgY.max()] sumArr = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) summed = convolve(img, sumArr, mode="constant", cval=0) corners = (summed == 2) & (img == 1) startx = path[0][0] * img.shape[1] starty = path[0][1] * img.shape[0] aStarts[sig] = [startx, starty] if useIntersects: intersects = (summed >= 4) & (img == 1) labeled, nLabels = label(intersects, structure=strcArr) itrscts = [] for l in xrange(1, nLabels + 1): intersect = np.array((labeled == l), dtype=int) posX, posY = np.nonzero(intersect) xC, yC = np.array([[np.sum(posX) / posX.size], [np.sum(posY) / posY.size]]) itrscts.append([xC[0], yC[0]]) itrscts = np.array(itrscts) corners = np.transpose(np.array(np.nonzero(corners))) if useIntersects: try: corners = np.vstack((itrscts, corners)) except: print "something went wrong at", sig corners[:, [0, 1]] = corners[:, [1, 0]] for i, corner in enumerate(corners): x, y = corner[0], corner[1] x = getFeatures(imgO, x, y, r, imgH, imgW, skltnSegs) X.append(x) sigNum.append(sig) coords.append([x, y]) return np.array(X), np.array(sigNum), np.array(coords)
def test_skeletonize_already_thinned(self): im = np.zeros((5, 5), np.uint8) im[3, 1:-1] = 1 im[2, -1] = 1 im[4, 0] = 1 result = skeletonize(im) numpy.testing.assert_array_equal(result, im)
def get_mask(img_org): noise_ratio = 0.3 img = img_org > noise_ratio * img_org.max() skeleton = skeletonize(img) mask = dilation(skeleton > 0, disk(2)) return mask
def calculate_rotation(image): # sometimes we snag corners, by cropping the left and right 10% of the image we focus only on the # vertical bars formed by the structure height, width = image.shape crop = int(width * 0.1) cropped_image = image[:, crop: width - crop] # Find edges that have a strong vertical direction vertical_edges = sobel_v(cropped_image) # Separate out the areas where there is a large amount of vertically-oriented stuff segmentation = segment_edge_areas(vertical_edges) # Draw a line that follows the center of the segments at each point, which should be roughly vertical # We should expect this to give us four approximately-vertical lines, possibly with many gaps in # each line skeletons = skeletonize(segmentation) # Use the Hough transform to get the closest lines that approximate those four lines hough = transform.hough_line(skeletons, np.arange(-constants.FIFTEEN_DEGREES_IN_RADIANS, constants.FIFTEEN_DEGREES_IN_RADIANS, 0.0001)) # Create a list of the angles (in radians) of all of the lines the Hough transform produced, with 0.0 # being completely vertical # These angles correspond to the angles of the four sides of the channels, which we need to # correct for angles = [angle for _, angle, dist in zip(*transform.hough_line_peaks(*hough))] if not angles: raise ValueError("Image rotation could not be calculated. Check the images to see if they're weird.") else: # Get the average angle and convert it to degrees offset = sum(angles) / len(angles) * 180.0 / math.pi if offset > constants.ACCEPTABLE_SKEW_THRESHOLD: log.warn("Image is heavily skewed. Check that the images are valid.") return offset
def get_thinned(binaryArr): """ Return thinned output Parameters ---------- binaryArr : Numpy array 2D or 3D binary numpy array Returns ------- result : boolean Numpy array 2D or 3D binary thinned numpy array of the same shape """ assert np.max(binaryArr) in [0, 1], "input must always be a binary array" voxCount = np.sum(binaryArr) if binaryArr.sum() == 0: return binaryArr.astype(bool) elif len(binaryArr.shape) == 2: return skeletonize(binaryArr).astype(bool) else: start_skeleton = time.time() zOrig, yOrig, xOrig = np.shape(binaryArr) orig = np.lib.pad(binaryArr, 1, 'constant') result = cy_get_thinned3D(np.uint64(orig)) print("thinned %i number of pixels in %0.2f seconds" % (voxCount, time.time() - start_skeleton)) return result[1:zOrig + 1, 1: yOrig + 1, 1: xOrig + 1].astype(bool)
def calculate(self, image: np.ndarray, disk_size: int=9, mean_threshold: int=100, min_object_size: int=750) -> float: # Find edges that have a strong vertical direction vertical_edges = sobel_v(image) # Separate out the areas where there is a large amount of vertically-oriented stuff segmentation = self._segment_edge_areas(vertical_edges, disk_size, mean_threshold, min_object_size) # Draw a line that follows the center of the segments at each point, which should be roughly vertical # We should expect this to give us four approximately-vertical lines, possibly with many gaps in # each line skeletons = skeletonize(segmentation) # Use the Hough transform to get the closest lines that approximate those four lines hough = transform.hough_line(skeletons, np.arange(-constants.FIFTEEN_DEGREES_IN_RADIANS, constants.FIFTEEN_DEGREES_IN_RADIANS, 0.0001)) # Create a list of the angles (in radians) of all of the lines the Hough transform produced, with 0.0 # being completely vertical # These angles correspond to the angles of the four sides of the channels, which we need to # correct for angles = [angle for _, angle, dist in zip(*transform.hough_line_peaks(*hough))] if not angles: raise ValueError("Image rotation could not be calculated. Check the images to see if they're weird.") else: # Get the average angle and convert it to degrees offset = sum(angles) / len(angles) * 180.0 / math.pi if offset > constants.ACCEPTABLE_SKEW_THRESHOLD: log.warn("Image is heavily skewed. Check that the images are valid.") return offset
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 skeletonize_mitochondria(mCh_channel): mch_collector = np.max(mCh_channel, axis=0) # TODO: check how max affects v.s. sum labels = np.zeros(mch_collector.shape, dtype=np.uint8) # thresh = np.max(mch_collector)/2. thresh = threshold_otsu(mch_collector) # TODO: use adaptative threshold? => otsu seems to be sufficient in this case # http://scikit-image.org/docs/dev/auto_examples/xx_applications/plot_thresholding.html#sphx # -glr-auto-examples-xx-applications-plot-thresholding-py # log-transform? => Nope, does not work # TODO: hessian/laplacian of gaussian blob detection? labels[mch_collector > thresh] = 1 skeleton2 = skeletonize(labels) skeleton, distance = medial_axis(labels, return_distance=True) active_threshold = np.mean(mch_collector[labels]) * 5 # print active_threshold transform_filter = np.zeros(mch_collector.shape, dtype=np.uint8) transform_filter[np.logical_and(skeleton > 0, mch_collector > active_threshold)] = 1 skeleton = transform_filter * distance skeleton_ma = np.ma.masked_array(skeleton, skeleton > 0) skeleton_convolve = ndi.convolve(skeleton_ma, np.ones((3, 3)), mode='constant', cval=0.0) divider_convolve = ndi.convolve(transform_filter, np.ones((3, 3)), mode='constant', cval=0.0) skeleton_convolve[divider_convolve > 0] = skeleton_convolve[divider_convolve > 0] \ / divider_convolve[divider_convolve > 0] new_skeleton = np.zeros_like(skeleton) new_skeleton[skeleton2] = skeleton_convolve[skeleton2] skeleton = new_skeleton return labels, mch_collector, skeleton, transform_filter
def label_particles_edge(im, sigma=2, closing_size=0, **extra_args): """ Segment image using Canny edge-finding filter. parameters ---------- im : image in which to find particles sigma : size of the Canny filter closing_size : size of the closing filter returns ------- labels : an image array of uniquely labeled segments """ from skimage.morphology import square, binary_closing, skeletonize if skimage_version < StrictVersion('0.11'): from skimage.filter import canny else: from skimage.filters import canny edges = canny(im, sigma=sigma) if closing_size > 0: edges = binary_closing(edges, square(closing_size)) edges = skeletonize(edges) labels = sklabel(edges) print "found {} segments".format(labels.max()) # in ma.array mask, False is True, and vice versa labels = np.ma.array(labels, mask=edges == 0) return labels
def bottleneck_distribution(image): """ Count the distribution of bottlenecks :param image: data (binary) :type image: :py:class:`numpy.ndarray` :return: count of bottlenecks of size 4 and size 2 :rtype: tuple(int) """ skel = morphology.skeletonize(image) # get the distances dists = ndimage.distance_transform_edt(image) # ok for all the nonzero in the skeleton, we get the distances x_nz, y_nz = skel.nonzero() # get all the nonzero indices width4 = 0 width2 = 0 for i in range(len(x_nz)): x = x_nz[i] y = y_nz[i] dist = dists[x,y] if dist <= 4: width4 += 1 if dist <= 2: width2 += 1 return width4, width2
def get_descriptor_lvX(self,img): ori = img #img = cv2.bitwise_not(numpy.array(img)) #img = threshold_adaptive(numpy.array(img), 40) #img = cv2.bitwise_not(img*255.) img = skeletonize(numpy.array(img)/255.)*255. '''figure() gray() subplot(221) imshow(ori) subplot(222) imshow(img) show()''' #e = stats.entropy(img.flatten()) #if math.isnan(e) or math.isinf(e): # return 0 #else: # return e descs = hog(numpy.array(img), orientations=4, pixels_per_cell=(10, 10),cells_per_block=(3, 3),visualise=False) '''figure() gray() imshow(img) figure() imshow(hpgimg) show()''' return descs
def sample_points(img, n_points=100): """Sample points along edges in a binary image. Returns an array of shape ``(n_points, 2)`` in image coordinates. If there are several disconnected contours, they are sampled seperately and appended in order of their minimum distance to the origin of ``img`` in NumPy array coordinates. """ # FIXME: what if contour crosses itself? for example: an infinity # symbol? assert img.ndim == 2 assert n_points > 0 boundaries = skeletonize(find_boundaries(img)) # reorder along curves; account for holes and disconnected lines # with connected components. labels, n_labels = ndimage.label(boundaries, structure=np.ones((3, 3))) n_labeled_pixels = labels.sum() all_labels = range(1, n_labels + 1) curve_n_pixels = list((labels == lab).sum() for lab in all_labels) curve_n_points = list(int(np.ceil((n / n_labeled_pixels) * n_points)) for n in curve_n_pixels) # sample a linear subset of each connected curve samples = list(_sample_single_contour(labels == lab, n_points) for lab, n_points in zip(all_labels, curve_n_points)) # append them together. They should be in order, because # ndimage.label() labels in order. points = list(itertools.chain(*samples)) return np.vstack(points)
def main(): c.clear_temp() img = dataset_manager.get_training_image() recognizer = captcha_recognizer.CaptchaRecognizer() mpimg.imsave(c.temp_path('00.origin.png'), img) # 1 img_01 = time_func( 'remove_noise_with_hsv', lambda: recognizer.remove_noise_with_hsv(img) ) mpimg.imsave(c.temp_path('01.hsv.png'), img_01, cmap=cm_greys) # 2 img_02 = time_func( 'remove_noise_with_neighbors', lambda: repeat(recognizer.remove_noise_with_neighbors, 2)(img_01) ) mpimg.imsave(c.temp_path('02.neighbor.png'), img_02, cmap=cm_greys) img_03a = time_func( 'skeletonize', lambda: morph.skeletonize(img_02) ) mpimg.imsave(c.temp_path('03a.skeleton.png'), img_03a, cmap=cm_greys)
def label_image(image): ROI = np.zeros((470,400,3), dtype=np.uint8) for c in range(3): for i in range(50,520): for j in range(240,640): ROI[i-50,j-240,c] = image[i,j,c] gray_ROI = cv2.cvtColor(ROI,cv2.COLOR_BGR2GRAY) ROI_flou = cv2.medianBlur((ROI).astype('uint8'),3) Laser = Detecte_laser.Detect_laser(ROI_flou) open_laser = cv2.morphologyEx(Laser, cv2.MORPH_DILATE, disk(3)) skel = skeletonize(open_laser > 0) tranche = Detecte_laser.tranche(skel,90,30) ret, thresh = cv2.threshold(gray_ROI*tranche.astype('uint8'),0,1,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) thresh01 = thresh<1.0 open_thresh = cv2.morphologyEx(thresh01.astype('uint8'), cv2.MORPH_OPEN, disk(10)) labelised = (label(open_thresh,8,0))+1 return gray_ROI,labelised
def enhance_edges(self): """ GNIRS_edge_detector method to enhance the footprint edges using the Sobel kernel. Generate two binary images, one with the left edges and the other showing the right edges only. This is because the MDF information about the footprints location is not well determined. """ sdata=nd.sobel(self.image,axis=self.axis) std = np.std(sdata) bdata=np.where(sdata>std,1,0) # Make the edges one pixel wide self.left_bin_image = skeletonize(bdata) bdata=np.where(sdata < -std,1,0) self.right_bin_image = skeletonize(bdata)
def thin_image(pix): """Thin ("skeletonize") a binarized image using scikit-image.morphology.skeletonize(). Returns a copy, does not modify array in place.""" # Skeletonize removes layers of the foreground, leaving only a skeleton thinned_pix = skeletonize(pix) return thinned_pix
def postprocess(model_root, iid, *, threshold=.288, largest_only=False, min_length=21, margin=4, vectorize_opt=dict(remove_hair=14), green_weight=0.15, padded_boundary=False): P_wide, stride = get_raster_probability(model_root, iid, green_weight=green_weight) P_wide = np.pad(P_wide, margin, 'edge') img = skeletonize(binary_denoise(P_wide >= threshold)) if margin: img = img[margin:-margin, margin:-margin] img = remove_small_components(img, stride, largest_only, min_length, padded_boundary=padded_boundary) return vectorize_skeleton(img, stride, 1.*stride, **vectorize_opt)
def skeleton(): from skimage.morphology import skeletonize image = io.imread(path + "bibme0.png") gray_image = rgb2gray(image) skeleton = skeletonize(gray_image) toprint(skeleton,"bibme0_skeleton.png")
def test_skeletonize_output(self): im = imread(os.path.join(data_dir, "bw_text.png"), as_grey=True) # make black the foreground im = (im == 0) result = skeletonize(im) expected = np.load(os.path.join(data_dir, "bw_text_skeleton.npy")) numpy.testing.assert_array_equal(result, expected)
def skeletonize(image_origin): # Reverse Color, Need black background image_origin = cv2.bitwise_not(image_origin) image_origin = cv2.cvtColor(image_origin, cv2.COLOR_BGR2GRAY) image_origin = cv2.threshold(image_origin, 0, 255, cv2.THRESH_OTSU)[1] image_skeleton = morphology.skeletonize(image_origin > 0) return image_skeleton
def breakup_region(component): distance = ndi.distance_transform_edt(component) skel = skeletonize(component) skeldist = distance*skel local_maxi = peak_local_max(skeldist, indices=False, footprint=disk(10)) local_maxi=ndi.binary_closing(local_maxi,structure = disk(4),iterations = 2) markers = ndi.label(local_maxi)[0] labels = watershed(-distance, markers, mask=component) return(labels)
def direction(self): edges = skeletonize(self.image) edges = edges.astype(int) edges = edges[1:251, 1:251] zones = self.zoning(edges) for i in zones: self.line_segmentation(i) direction = self.direction_transfer(self.count_common(zones)) return np.append(direction, [float(self.ratio)/10])
def profiling(self): image = resize(self.image, (257, 257)) edges = ff.canny(image) edges = skeletonize(edges) edges = edges.astype(int) edges = edges[1:256, 1:256] lt = self.feature_extraction_profiling(edges, 2, 5) profiling = lt.ravel() return np.append(profiling, [float(self.ratio)/10])
def build_skeleton(frame): """ build a corner tree, skeletonize, dilate """ tree = trees.tree_corners(frame) tree = morphology.skeletonize(tree) # tree = morphology.binary_dilation(tree) morphology.remove_small_objects(tree, min_size=20, connectivity=2, in_place=True) tree = morphology.binary_dilation(tree) return tree
def test_tiny_loop_with_branches(size=(10, 10)): # a loop and a branches coming at end of the cycle frame = np.zeros(size, dtype=np.uint8) frame[2:-2, 2:-2] = 1 frame[4:-4, 4:-4] = 0 frame = skeletonize(frame) frame[1, 5] = 1 frame[7, 5] = 1 sample_image = np.zeros((3, 10, 10), dtype=np.uint8) sample_image[1] = frame _helper_networkx_graph(sample_image, 10, 1)
Mask = cmask.create_circular_mask(im_orig.shape[0], im_orig.shape[1], center=ONH_Center, radius=ONH_Radius * 4.5, radius_small=ONH_Radius * 2) masked_img = np.multiply(im_orig[:, :, 1], Mask) masked_img_vas = np.multiply(im_orig_vas, Mask) ret, labels = cv2.connectedComponents(masked_img_vas) regions = regionprops(labels) for region in regions: blob_img = labels == region.label blob_skeleton = skeletonize(blob_img) blob_img_stack = np.uint8(np.dstack((blob_img, blob_img, blob_img))) * 255 blob_skeleton_stack = np.uint8( np.dstack((blob_skeleton, blob_skeleton, blob_skeleton))) * 255 #dst = cv2.cornerHarris(np.float32(blob_skeleton),2,3,0.1) dst = cv2.cornerHarris(np.float32(blob_skeleton), 2, 3, 0.1) blob_skeleton_bifurc_points = np.zeros(blob_skeleton.shape) skel_pixels = np.where(blob_skeleton) bifurcation_labeling = np.zeros(len(skel_pixels[0])) for k in range(len(skel_pixels[0])): if np.sum(blob_skeleton[skel_pixels[0][k] - 1:skel_pixels[0][k] + 2, skel_pixels[1][k] - 1:skel_pixels[1][k] +
def main(): # INPUT AND OUTPUT FILEPATHS in_path = 'images/input/lowrez/' in_path = 'images/input/mt_bees/' in_path = 'bees/12-00-32/' in_path = 'C:/Users/parkerat2/Desktop/images/' out_path = 'images/output/prepro/' # TESTING IMAGES # some sample images chosen for testing_label/tweaking the file's functionality # in_img = "thresholdedframe525_14-12-57_1.png" # in_img = "thresholdedframe183_14-12-57.png" # in_img = "thresholdedframe750_14-12-57_2.png" # in_img = "thresholdedframe750_14-12-57_1.png" # in_img = "thresholdedframe225_14-12-57_1.png" in_img = 'thresholdedframe1175_14-12-57_2.png' in_img = 'Rotated11/11-20-36-1a.jpg' in_img = 'image2cut.jpg' in_img = '1440_10-00-16.h264.png' # in_img = 'mt_bee1.png' img = cv2.imread(in_path + in_img) cv2.imshow('image', img) # this is for those manually cut/rotated images that had black backgrounds # it will turn a value below 8 into 255, so black becomes white # this is important because the initial thought of this program would that it is easier to determine a white background # from the bees, so the goal is to effectively "find the background" and what is left out is the bee. # make sure to comment this line if your bees have a white background # retval, img = cv2.threshold(img, 8, 255, cv2.THRESH_BINARY_INV) # do not mess with anything you see as .copy() # object = object assignments are just two variables referring to the same object, so copy is used to create new obj img1 = img.copy() # testing_label ranges # moving it to hsv (hue, saturation, value) space # don't remember what this section was for # hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # # lower = np.array([0, 0, 0]) # upper = np.array([160, 160, 160]) # # mask = cv2.inRange(hsv, lower, upper) # res = cv2.bitwise_and(img, img, mask= mask) # mask_inv = cv2.bitwise_not(mask) cv2.imshow('image', img) # cv2.imshow('mask', mask) # cv2.imshow('mask_inv', mask_inv) # cv2.imshow('res', res) # BLURRING SECTION # blurring options, gaussian/median/bilateral # blur - standard cv2 blur # gaussian - good for reducing gaussian noise # median - good for reducing noise such as salt-and-pepper noise # bilateral - good for preserving edges # ksize is kernal size # bordertype tries extrapolate pixels outside the image, 0 is a sentinal value for a bordertype constant grayscaled = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) blur = cv2.blur(img1, ksize=(3, 3), borderType=0) gausblur = cv2.GaussianBlur(img1, (3, 3), 0) medblur = cv2.medianBlur(img1, ksize=3) medblur2 = cv2.medianBlur(medblur, ksize=5) # d is diameter of the pixel neighborhood used for filtering # d > 5 is considered a large filter and 9 is suggested for offline heavy noise filtering d = 9 # sigmacolor is the range of colors that will be mixed together within the neighborhood # large value means colors can mix with nonlike colors (ie: red and green) # small value means colors will only mix with like colors (ie: blue and indigo) color = d * d color = 100 # sigmaspace is used for determining the pixel neighborhood for filtering # space is irrelevant if d (diameter) is > 0, if you specify d it'll use that, if you don't it'll use sigmaspace space = d * d bil1 = cv2.bilateralFilter(medblur, d, color, space) bil2 = cv2.bilateralFilter(bil1, d, color, space) bil3 = cv2.bilateralFilter(bil2, d, color, space) bil4 = cv2.bilateralFilter(bil3, d, color, space) # showing and saving the blurred images # cv2.imshow('blur', blur) cv2.imshow('medblur', medblur) # cv2.imshow('medblur2', medblur2) cv2.imshow('bil', bil1) # cv2.imwrite(out_path + 'medblue' + in_img, medblur) # cv2.imwrite(out_path + 'bilblur' + in_img, bil1) # picking the final blurred image for the rest of the program blurred = bil1 # COLOR SCALING SECTION # 0's out the nondesired color channels # to bluescale for example you zero our red and green # remember color format is bgr blue = blurred.copy() for r in blue: for c in r: c[1] = 0 c[2] = 0 # red = blurred.copy() # for r in red: # for c in r: # c[0] = 0 # c[1] = 0 # green = blurred.copy() # for r in green: # for c in r: # c[0] = 0 # c[2] = 0 # showing the results of scaling # cv2.imshow('img', img) cv2.imshow('blue', blue) # cv2.imshow('green', green) # cv2.imshow('red', red) # THRESHOLDING SECTION # if you want to use the bluescaled image use the blue threshold # note it is considerably lower and much more sensitive than using a grayscaled image for thresholding gray_thresh = 105 thresh = gray_thresh # blue_thresh = 10 # thresh = blue_thresh # blurred = blue # cv2.imwrite(out_path + 'blue' + in_img, blue) # the chosen blue/gray blurred image makes it this section, if grayscaled this line does nothing # but if bluescaled you'll need to grayscale the bluescale for thresholding grayblur = cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY) # cv2.imwrite(out_path + 'gray' + in_img, grayblur) # anything higher than the thresh value is set to 255 (white) # these functions return two objects, a value that indicates the optimal threshold if otsu is used (if not otsu than # it returns the threshold that was passed to it) and the thresholded image. retval, threshold = cv2.threshold(blurred, thresh, 255, cv2.THRESH_BINARY) retval2, threshold2 = cv2.threshold(grayblur, thresh, 255, cv2.THRESH_BINARY) # cv2.imwrite(out_path + 'threshold2' + in_img, threshold2) # guassian and otsu thresholding gaus = cv2.adaptiveThreshold(grayblur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1) retval3, otsu = cv2.threshold(grayblur, thresh, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # showing the thresholded images # cv2.imshow('threshold', threshold) cv2.imshow('threshold2', threshold2) # cv2.imshow('gaus', gaus) # cv2.imshow('otsu', otsu) # MASKING SECTION # since our threshold does a good job of finding backgrounds instead of bees we inverse the mask # you could also also inverse the thresholding section, but this follows the thought process of the initial idea of # finding the background mask_thresh = cv2.bitwise_not(threshold2) # cv2.imwrite(out_path + 'mask_thresh' + in_img, mask_thresh) img_thresh = cv2.bitwise_and(img, img, mask=mask_thresh) cv2.imshow('img_thresh', img_thresh) # SKELETON SECTION # create a binary image and feed into the medial axis or skeletonize functions # ideal output from these is to create a "spine" of the bee with no branches binary = img_as_bool(mask_thresh) med = mp.medial_axis(binary) skele = mp.skeletonize(binary) # skele = mp.skeletonize(med) # compare the skeletons # print(med[0]) # # f, (ax0, ax1) = plt.subplots(1, 2) # ax0.imshow(med, cmap='gray', interpolation='nearest') # ax1.imshow(skele, cmap='gray', interpolation='nearest') # plt.show() # plt.clf() # creates a skeleton over the image # img_copy = grayscaled.copy() # for row in range(len(skele)): # for col in range(len(skele[row])): # if skele[row][col]: # img_copy[row][col] = 255 # # # print(med[0][0] == False)+ # # print(img_copy[0][0]) # cv2.imshow("copy", img_copy) # # # print(img_copy[25]) # arr = [] # # for row in range(len(img_copy)): # for col in range(len(img_copy[row])): # if img_copy[row][col].all() == 0: # arr.append(img[row][col]) # # print(arr) # cv2.imwrite(out_path + in_img, img_thresh) # turns the "binary" bool array to bgr array bw = img.copy() sk = skele for row in range(len(sk)): for col in range(len(sk[row])): if sk[row][col]: bw[row][col] = [255, 255, 255] else: bw[row][col] = [0, 0, 0] cv2.imshow("bw", bw) # cv2.imwrite("skele.png", bw) # get the x and y coords of the skeleton x = [] y = [] for row in range(len(bw)): for col in range(len(bw[row])): if (bw[row][col] != 0).all(): y.append(row) x.append(col) # get the x and y coords of the img cv2.imshow("img", img) x1 = [] y1 = [] for row in range(len(img)): for col in range(len(img[row])): if (img[row][col] != 255).all(): y1.append(row) x1.append(col) # for plt img2 = im.imread(in_path + in_img) # polyfit # attempts to create a line of best fit using the coorinates of the skeleton over the linespace of the images coordinates z = np.polyfit(x, y, 1) f = np.poly1d(z) x_new = np.linspace(np.min(x1), np.max(x1) + 1, 200) y_new = f(x_new) # print(x_new) # print(y_new) # plotting shenanigans # points = [[xn, yn] for xn, yn in zip(x_new, y_new) if (np.min(y1) <= yn <= np.max(y1))] # plt.imshow(threshold2, cmap='Greys') plt.imshow(img2) plt.plot(x_new, y_new) plt.gca().set_aspect('equal', adjustable='box') # plt.savefig(out_path + in_img) plt.xlim(0, len(img2[0]) - 1) plt.ylim(len(img2) - 1, 0) plt.show() plt.clf() # GETTING THE COLOR VALUES OF THE LINE OF BEST FIT # interpolation stuff # coming back to this I think interpolation might be done automatically in getting the right color in python # the whole reason to do this is to get the expected color at a point on our line of best fit # because the line of best fits' points may not be an exact pixel coordinate, we interpolate the color value from # the image at what would be expected at that coordinate # in short if given coordinate (2.34, 19.89) we interpolate the color for that coordinate points = [[xn, yn] for xn, yn in zip(x_new, y_new) if (np.min(y1) <= yn <= np.max(y1))] # print(points) x_points = [round(point[0]) for point in points] y_points = [round(point[1]) for point in points] interpolated_values = [] for point in points: px = point[1] py = point[0] ipx = int(px) ipy = int(py) if px != float(ipx) and py == float(ipy): pxf = math.floor(px) pxc = math.ceil(px) c = np.array(img2[pxc][py]) f = np.array(img2[pxf][py]) fs = f * (1 - (px - pxf)) cs = c * (1 - (1 - (px - pxf))) clr = fs + cs interpolated_values.append(clr) elif px == float(ipx) and py != float(ipy): pyf = math.floor(py) pyc = math.ceil(py) c = np.array(img2[px][pyc]) f = np.array(img2[px][pyf]) fs = f * (1 - (py - pyf)) cs = c * (1 - (1 - (py - pyf))) clr = fs + cs interpolated_values.append(clr) elif px != float(ipx) and py != float(ipy): pxf = math.floor(px) pxc = math.ceil(px) pyf = math.floor(py) pyc = math.ceil(py) c = np.array(img2[pxc][pyf]) f = np.array(img2[pxf][pyf]) fs = f * (1 - (px - pxf)) cs = c * (1 - (1 - (px - pxf))) xyf = fs + cs c = np.array(img2[pxc][pyc]) f = np.array(img2[pxf][pyc]) fs = f * (1 - (px - pxf)) cs = c * (1 - (1 - (px - pxf))) xyc = fs + cs fs = xyf * (1 - (py - pyf)) cs = xyc * (1 - (1 - (py - pyf))) # fs = np.round(xyf * (1 - (py - pyf)) * 255) # cs = np.round(xyc * (1 - (1 - (py - pyf))) * 255) clr = (fs + cs) # clr = [int(it) for it in clr] interpolated_values.append(clr) else: interpolated_values.append(img2[px][py]) # if the threshold values are met add the interpolated values to the list of values # if the pixel on the image is black (the bee part) grab the expected color at that pixel coordinate threshold_values = [] t_px = [] t_py = [] for i in range(len(points)): px = x_points[i] py = y_points[i] if threshold2[py][px] == 0: t_px.append(px) t_py.append(py) # threshold_values.append(img2[py][px]) threshold_values.append(interpolated_values[i]) # print(t_py[0], t_px[0]) # print(img2[t_py[0]][t_px[0]]) print(threshold_values) # PLOTTING STUFF # plots just the pixels grabbed plt.scatter(t_px, t_py, facecolors=threshold_values, marker='s') plt.gca().set_aspect('equal', adjustable='box') plt.gca().invert_yaxis() plt.show() plt.clf() # plots those pixel in an overlay on image, makes a little box around them plt.imshow(img2) plt.scatter(t_px, t_py, facecolors=threshold_values, marker='s', edgecolors='black') plt.gca().set_aspect('equal', adjustable='box') plt.plot(x_new, y_new) plt.xlim(0, len(img2[0]) - 1) plt.ylim(len(img2) - 1, 0) # plt.gca().invert_yaxis() plt.show() plt.clf() # plots the color ratios of those chosen values # pretty sure this ended up being not correct color label wise because plt.show is rbg and # the images worked with are in bgr, so it plots them color inversed plt.plot(np.array(threshold_values)[:, 0], c='b') plt.plot(np.array(threshold_values)[:, 1], c='g') plt.plot(np.array(threshold_values)[:, 2], c='r') plt.show() plt.clf() # OVAL ATTEMPT # bwg = img.copy() # mt = mask_thresh # for row in range(len(mt)): # for col in range(len(mt[row])): # if mt[row][col]: # bwg[row][col] = [255, 255, 255] # else: # bwg[row][col] = [0, 0, 0] # cv2.imshow("bwg", bwg) # # # coords of the oval # x = [] # y = [] # for row in range(len(bwg)): # for col in range(len(bwg[row])): # if (bwg[row][col] != 0).all(): # y.append(row) # x.append(col) # # # for plt # img3 = im.imread(in_path + in_img) # # # polyfit # z = np.polyfit(x, y, 2) # f = np.poly1d(z) # x_new = np.linspace(min(x1), max(x1), 100) # y_new = f(x_new) # plt.imshow(img3) # plt.plot(x_new, y_new) # plt.gca().set_aspect('equal', adjustable='box') # # plt.savefig(out_path + in_img) # plt.show() # plt.clf() # BACKGROUND SUBTRACTOR # vid = '14-12-57' # video = cv2.VideoCapture('video/18-01-33.h264') # fgbg = cv2.createBackgroundSubtractorMOG2() # # while True: # ret, frame = video.read() # fgmask = fgbg.apply(frame) # # # cv2.imshow('orginal', frame) # cv2.imshow('fg', fgmask) # # k = 0xFF & cv2.waitKey(30) # Wait for a second # if k == 27: # break cv2.waitKey(0) cv2.destroyAllWindows()
warnings.filterwarnings("ignore", category=DeprecationWarning) path = tkinter.filedialog.askopenfilename() tkinter.wantobjects color_im = cv2.imread(path) img = cv2.cvtColor(color_im, cv2.COLOR_RGB2GRAY) color_im = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB) clone = color_im.copy() ##thresh = threshold_otsu(img) ##binary = img > thresh inv_img = np.invert(img) binary = binarize(inv_img, threshold=8.0) #binary = np.invert(binary) skel = skeletonize(binary) ##plt.imshow(skel) ##plt.show() cv_skel = img_as_ubyte(skel) lines = probabilistic_hough_line(skel, threshold=1, line_length=2, line_gap=10) ####### HOUGH EXAMPLE ################ from matplotlib import cm h, theta, d = hough_line(skel) fig, axes = plt.subplots(3, 4, figsize=(20, 11), subplot_kw={'adjustable': 'box-forced'}) ax = axes.ravel()
arra = (bt_120_087_anom_m_4444 - bt_120_087_anom_m_1111) + ( bt_120_087_anom_m_4444 - bt_120_087_anom_m_2222) + ( bt_120_087_anom_m_4444 - bt_120_087_anom_m_3333) arrb = (bt_120_108_anom_m_4444 - bt_120_108_anom_m_1111) + ( bt_120_108_anom_m_4444 - bt_120_108_anom_m_2222) + ( bt_120_108_anom_m_4444 - bt_120_108_anom_m_3333) arrc = (bt_108_087_anom_m_4444 - bt_108_087_anom_m_1111) + ( bt_108_087_anom_m_4444 - bt_108_087_anom_m_2222) + ( bt_108_087_anom_m_4444 - bt_108_087_anom_m_3333) arr = (arrc - arrb) + (arra - arrb) #arr = (arra-arrb) #arr = (arrc-arrb) arrm = np.ma.masked_where(np.isnan(arr), arr) arra = np.ma.masked_where(np.isnan(arra), arra) arrb = np.ma.masked_where(np.isnan(arrb), arrb) arrc = np.ma.masked_where(np.isnan(arrc), arrc) date_i = indices[-1] cpo, cpo_p1 = detect_cpo(arrm) plot(cpo, title='CPO_boolean_v3') cposk = skeletonize(cpo) plot(cposk, title='CPO_boolean_skeleton')
def read_image_with_chunks_from_location(directory): path = abspath(__file__ + "/../../") json_path = str(path) + "/configs/settings.json" # get new json values and assign them assign_json_values(json_path) pre_border = 5 list_of_return_images = list() list_of_return_contours = list() img_with_chunks = None data_path = path + "/filtered/" filename = "filtered.png" main_folder = data_path # + "/ImageFilter" + "/" create_folder(main_folder) # read image img_reading = imread(directory, plugin='matplotlib') # rotate image rotation = get_image_rotation_from_location(directory) img_rotated = rotate_image(img_reading, rotation) img_with_chunks = img_rotated h, w, c = img_rotated.shape img_pre_crop = create_cropped_image(img_rotated, pre_border) # create binary image img_binary = create_chromakey_image(img_pre_crop, filter_green_low_factor, filter_green_high_factor, filter_green_saturation, filter_green_brightness) save_image(img_binary, filename + "_borders.png", main_folder) # TODO: Add chunking here with image reading from directory # Returned lists by chunking list_of_work_images, list_of_work_contours, img_with_chunks = create_chunked_image( img_binary, img_reading, filter_contours_length, filter_chunk_border, image_dimension_t_small) save_image(img_with_chunks, filename + "_chunk.png", main_folder) list_wi_length = len(list_of_work_images) list_wc_length = len(list_of_work_contours) if list_wi_length == list_wc_length: for index in range(list_wi_length): index_image = list_of_work_images[index] index_coord = list_of_work_contours[index] chunk_string = "___" + str(index) + "_chunk_" chunk_filename = filename + chunk_string # get binary image img_clamp = clamp_binary_values(index_image) img_fillout = create_fillout_image(img_clamp, filter_fill_out_length) save_image(img_fillout, chunk_filename + "_fillout.png", main_folder) # get black borders inside of image img_borders = create_borders( imread(main_folder + chunk_filename + "_fillout.png", plugin="matplotlib"), image_dimension_small, image_border) save_image(img_borders, chunk_filename + "_borders.png", main_folder) # create filtered images img_skeleton = skeletonize(img_borders) save_image(img_skeleton, chunk_filename + "_skeleton.png", main_folder) # align binary image to center of mass img_com = create_com_image(img_skeleton, image_dimension, image_dimension_t, image_dimension_small, filter_binary_filter_threshold, image_border) save_image(img_com, chunk_filename + "_com.png", main_folder) list_of_return_images.append(img_com) list_of_return_contours.append(index_coord) return list_of_return_images, list_of_return_contours, img_with_chunks
def skeletonizer(img): skeleton = img skeleton.dtype = np.bool skeleton = skeletonize(img) skeleton.dtype = np.uint8 return skeleton
cv2.imshow('video',thresh) writer.writeFrame(thresh) if cv2.waitKey(1) & 0xFF == ord('q'): break ''' frame_nmbr = cap.get(cv2.CAP_PROP_POS_FRAMES) int(frame_nmbr) if numb_cnts < 3: cv2.rectangle(image, (0, 0), (1920, 805), (0, 0, 255), 3) cv2.putText(image, 'Occlusion', (860, 402), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0), 2) occl_frame_nmbr.append(frame_nmbr) cv2.putText(image, "{}".format(frame_nmbr), (860, 620), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) skeleton = skeletonize(roi1) rows = len(skeleton[1]) cols = len(skeleton) for i in range(cols): for j in range(rows): if skeleton[i][j] == 1: cv2.circle(image, (j, i), 0, (0, 255, 0), -2) cv2.imshow('video', image) writer.writeFrame(image) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() writer.close()
def process_frame(settings, Z, mean_brightness, nframes, args=None, return_plot=False): """Locate worms in a given frame.""" i, frameorig = args print(' : Locating in frame %i/%i' % (i + 1 + settings["start_frame"], nframes + settings["start_frame"])) if mean_brightness: frame = frameorig * mean_brightness / np.mean(frameorig) else: frame = np.array(frameorig, dtype=np.float64) frame = np.abs(frame - Z) * settings["all_regions"] if (frame > 1.1).any(): frame /= 255. thresholded = frame > (settings["threshold"] / 255.) opening = settings["opening"] closing = settings["closing"] save_folder = settings["save_as"] if opening > 0: frame_after_open = ndimage.binary_opening( thresholded, structure=np.ones((opening, opening))).astype(np.int) else: frame_after_open = thresholded if closing > 0: frame_after_close = ndimage.binary_closing( frame_after_open, structure=np.ones((closing, closing))).astype(np.int) else: frame_after_close = frame_after_open labeled, _ = mh.label(frame_after_close, np.ones( (3, 3), bool)) sizes = mh.labeled.labeled_size(labeled) remove = np.where(np.logical_or(sizes < settings["min_size"], sizes > settings["max_size"])) labeled_removed = mh.labeled.remove_regions(labeled, remove) labeled_removed, n_left = mh.labeled.relabel(labeled_removed) props = measure.regionprops(labeled_removed, coordinates='xy') prop_list = [{"area": props[j].area, "centroid":props[j].centroid, "eccentricity":props[j].eccentricity, "area_eccentricity":props[j].eccentricity, "minor_axis_length":props[j].minor_axis_length / (props[j].major_axis_length + 0.001)} for j in range(len(props))] if settings["skeletonize"]: skeletonized_frame = morphology.skeletonize(frame_after_close) skeletonized_frame = prune(skeletonized_frame, settings["prune_size"]) skel_labeled = labeled_removed * skeletonized_frame if settings["do_full_prune"]: skel_labeled = prune_fully(skel_labeled) skel_props = measure.regionprops(skel_labeled, coordinates='xy') for j in range(len(skel_props)): prop_list[j]["length"] = skel_props[j].area prop_list[j]["eccentricity"] = skel_props[j].eccentricity prop_list[j]["minor_axis_length"] = \ skel_props[j].minor_axis_length\ / (skel_props[j].major_axis_length + 0.001) if return_plot: return (sizes, save_folder, frameorig, Z, frame, thresholded, frame_after_open, frame_after_close, labeled, labeled_removed, (skel_labeled if settings["skeletonize"] else None)) output_overlayed_images = settings["output_overlayed_images"] if i < output_overlayed_images or output_overlayed_images is None: io.imsave(os.path.join(save_folder, "imgs", '%05d.jpg' % (i)), np.array(255 * (labeled_removed == 0), dtype=np.uint8), check_contrast=False) return prop_list
def show_point(file): global totalpoint img = io.imread(file, as_grey=True) tt = (get_outline(fill_image((get_fileter_image(adjunction_image(np.where(img / 255 > 0.9, 1, 0))))))).astype( np.uint8) img_filter = get_fileter_image(adjunction_image(np.where(img / 255 > 0.9, 1, 0))) fill_img = fill_image((get_fileter_image(adjunction_image(np.where(img / 255 > 0.9, 1, 0))))) skelenton_image = skeletonize(fill_img) end_pointx, end_pointy = end_point(skelenton_image) # plt.subplot(211).imshow(fill_img) # pp = plt.subplot(212) # pp.imshow(skelenton_image) # pp.plot(end_pointy, end_pointx, 'r.') # plt.show() # plt.show() row, col = tt.shape # get_line(tt) horizontal_projection = np.sum(tt[:int(col / 2), :], axis=1) horizontal_projection_t = horizontal_projection[4:-4] index_zero = np.where(horizontal_projection_t < 2) index = np.where(horizontal_projection == np.max(horizontal_projection))[0][0] if (len(index_zero[0]) != 0): print("change index position") index = index_zero[0][-1] + 4 + 2 # print(horizontal_projection) print('基线位置: ', index) pointx, pointy = [], [] vewol_point = [] corners = cv2.goodFeaturesToTrack((tt).astype(np.uint8), 20, 0.2, 7) """ 1.8 skeleton water: 71.97 outline: feature point 20,0.25,7 SVM 0.85 81.33 11859-5461 feature point 20,0.30,7 SVM 0.85 79.72 11180-5353 feature point 20,0.20,7 SVM 0.85 82.44 12751-5535 feature point 20,0.20,7 SVM 0.85 82.23 12151-5521 alter-col 1.4 skeleton water: 67.887 the best result of outline: feature point 20,0.20,7 SVM 0.85 78.41 12151-5265 alter-col """ # corners = np.int0(corners) # for item in corners: # x, y = item.ravel() # # cv2.circle(img, (x, y), 3, [0, 255, 255], -1) # if (x <= int(col / 3 + 0.5 + 2) or x >= int(col / 3 * 2 + 0.5 - 2) and col < 100): # continue # if (x <= int(col / 3 + 0.5 + 2) or x >= int(col / 4 * 3 + 0.5 - 2) and col > 100): # continue # point_flag = True # if (tt[y][x] == 0): # y, x = alter_point(tt, y, x) # vewol = 0 # for i in range(len(end_pointx)): # if ((end_pointy[i] - x) * (end_pointy[i] - x) + (end_pointx[i] - y) * (end_pointx[i] - y) < 25) and ( # abs(y - index) >= 3): # point_flag = False # break; # elif (((end_pointy[i] - x) * (end_pointy[i] - x) + (end_pointx[i] - y) * (end_pointx[i] - y) > 25) and ( # index - y >= 2)): # vewol = vewol + 1 # if (len(end_pointx) == vewol): # vewol_point.append([x, y]) # if (not point_flag): # continue # if (abs(y - index) < 3 and not (total_point(tt, y, x) > 3) or y < index): # continue # # pointx.append(x) # pointy.append(y) # # alter_pointx, alter_pointy = alter_index_points(tt, index) # pointx = pointx + alter_pointx # pointy = pointy + alter_pointy # alter_pointx, alter_pointy = alter_index_points(tt, index + 1) # pointx = pointx + alter_pointx # pointy = pointy + alter_pointy # alter_pointx, alter_pointy = alter_index_points(tt, index + 2) # pointx = pointx + alter_pointx # pointy = pointy + alter_pointy # alter_pointx, alter_pointy = alter_index_points(tt, index + 3) # pointx = pointx + alter_pointx # pointy = pointy + alter_pointy # # pointx, pointy = del_near_point(pointx, pointy) # if (len(pointx) == 0): # print("MDZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ") # for item in corners: # x, y = item.ravel() # # cv2.circle(img, (x, y), 3, [0, 255, 255], -1) # point_flag = True # # if (tt[y][x] == 0): # y, x = alter_point(tt, y, x) # if (abs(y - index) < 3 and not (total_point(tt, y, x) > 3)): # continue # if (x <= int(col / 3 + 0.5 + 1) or x >= int(col / 3 * 2 + 0.5 - 1)): # continue # if (3 < abs(y - index) < 8): # pointx.append(x) # pointy.append(y) # print('vewol: ', vewol_point) # # if (len(vewol_point) > 0): # new_vewol = judge_vowel(img_filter, index, vewol_point) # # if (len(new_vewol) > 0): # print('newwol: ', new_vewol) # for i in range(len(new_vewol)): # pointx.append(new_vewol[i][0]) # pointy.append(new_vewol[i][1]) # position_point = get_position(skelenton_image, pointx, pointy) # if (len(pointx) < 1): # print("can't find feature point!") # return 0 # # result_point = find_segmention_point(adjunction_image(img), index, pointy, pointx, position_point) # # print(pointx) # # print(pointy) # print(position_point) wrfile.write(os.path.basename(file) + ',') # for i in range(len(result_point)): # wrfile.write(str(result_point[i][1] - 3) + ' ' + str(result_point[i][0] - 3) + ' ' # + str(result_point[i][3] - 3) + ' ' + str(result_point[i][2] - 3) + ',') wrfile.write(str(index)) wrfile.write('\n') wrfile.flush() # result_pointx, result_pointy = [], [] # for result in result_point: # result_pointy.append(result[0]) # result_pointy.append(result[2]) # result_pointx.append(result[1]) # result_pointx.append(result[3]) p2 = plt.subplot(211) p2.imshow(fill_image(get_fileter_image(adjunction_image(np.where(img / 255 > 0.9, 1, 0))))) p2.imshow(img) # print(corners) p1 = plt.subplot(212) p1.plot([1, col - 1], [index, index]) p1.plot([int(col / 3 + 0.5), int(col / 3 + 0.5)], [0, row - 1], label[0]) if (col < 100): p1.plot([int(col / 3 * 2 + 0.5), int(col / 3 * 2 + 0.5)], [0, row - 1], label[0]) else: p1.plot([int(col / 4 * 3 + 0.5), int(col / 4 * 3 + 0.5)], [0, row - 1], label[0]) # p2.plot(result_pointx, result_pointy, 'b.') p2.imshow(adjunction_image(img)) p1.imshow(adjunction_image(img)) p1.plot(pointx, pointy, "r.") plt.show()
def read_images_with_chunks(): """ Creates a new folder for the process with the necessary sub folder. Starts the filtering process for each image. Read -> Resize -> Rotate -> Binary -> CenterOfMass -> Canny + Skeleton """ # TODO: add to settings.json pre_border = 5 #create path & filename path = abspath(__file__ + "/../../") data_path = str(path) + "/data/" json_path = str(path) + "/configs/settings.json" filename = "filtered.png" #json values assign_json_values(json_path) #create folder with time stamp main_folder = data_path + "filtered/" + datetime.datetime.now().strftime( "%Y_%m_%d_x_%H_%M_%S") + "/" create_folder(main_folder) #path to readable files dir_name = data_path + "" + "images_green/" # TODO directory_data = listdir(dir_name) #list of all loaded images loaded_images = list() #loads images for file in directory_data: file_ends_with = file.split(".")[-1].lower() if len(loading_possible_filename) > 0: for filename in loading_possible_filename: if file_ends_with == filename: loaded_images.append(file) else: pass # print("Could not find file with: " + filename + " at " + file) list_of_return_images = list() list_of_return_contours = list() img_with_chunks = None for image_name in loaded_images: #assigns name of file to name of current image filename = image_name # read image img_reading = imread(dir_name + "/" + filename, plugin='matplotlib') # rotate image rotation = get_image_rotation(filename, dir_name) img_rotated = rotate_image(img_reading, rotation) h, w, c = img_rotated.shape img_with_chunks = img_rotated # img_rotated_gray = rgb2gray(img_rotated) # img_rotated_pil = Image.fromarray(img_rotated) # img_pre_crop = img_rotated_pil.crop((pre_border, pre_border, w - pre_border, h - pre_border)) # img_np_pre_cropped = np.array(img_pre_crop) img_np_pre_cropped = create_cropped_image(img_rotated, pre_border) # create binary image img_binary = create_chromakey_image(img_np_pre_cropped, filter_green_low_factor, filter_green_high_factor, filter_green_saturation, filter_green_brightness) save_image(img_binary, filename + "_borders.png", main_folder) # Returned lists by chunking list_of_work_images, list_of_work_contours, img_with_chunks = create_chunked_image( img_binary, img_reading, filter_contours_length, filter_chunk_border, image_dimension_t_small) save_image(img_with_chunks, filename + "_chunk.png", main_folder) list_wi_length = len(list_of_work_images) list_wc_length = len(list_of_work_contours) if list_wi_length == list_wc_length: for index in range(list_wi_length): index_image = list_of_work_images[index] index_coord = list_of_work_contours[index] chunk_string = "___" + str(index) + "_chunk_" chunk_filename = filename + chunk_string # get binary image img_clamp = clamp_binary_values(index_image) save_image(img_clamp, chunk_filename + "_binary.png", main_folder) #schmiering img_fillout = create_fillout_image(img_clamp, filter_fill_out_length) save_image(img_fillout, chunk_filename + "_fillout.png", main_folder) # get black borders inside of image img_borders = create_borders( imread(main_folder + chunk_filename + "_fillout.png", plugin="matplotlib"), image_dimension_small, image_border) save_image(img_borders, chunk_filename + "_borders.png", main_folder) # create filtered images img_skeleton = skeletonize(img_borders) save_image(img_skeleton, chunk_filename + "_skeleton.png", main_folder) # align binary image to center of mass img_com = create_com_image(img_skeleton, image_dimension, image_dimension_t, image_dimension_small, filter_binary_filter_threshold, image_border) save_image(img_com, chunk_filename + "_com.png", main_folder) list_of_return_images.append(img_com) list_of_return_contours.append(index_coord) return list_of_return_images, list_of_return_contours, img_with_chunks
# More: http://ex2tron.top import cv2 import matplotlib.pyplot as plt import numpy as np from skimage.morphology import skeletonize # 1.模板匹配 img = cv2.imread('minirealpcb1.jpg') drawing = np.zeros(img.shape[:], dtype=np.uint8) # 创建画板 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = cv2.medianBlur(gray, 5) #中值滤波 ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) thresh[thresh == 255] = 1 edges = skeletonize(thresh) # edges = cv2.Canny(thresh, 50, 150) # 2.统计概率霍夫线变换 drawing = np.zeros(img.shape[:], dtype=np.uint8) edges = edges.astype(np.uint8)*255 print(edges.shape, gray.shape) lines = cv2.HoughLinesP(edges, 5, np.pi / 4, 10, minLineLength=3, maxLineGap=15) # lines = cv2.HoughLines(edges, 0.8, np.pi / 4, 6) fig, (ax1,ax2) = plt.subplots(nrows=1, ncols=2, sharex=True, sharey=True) ax2.axis('image') # 将检测的线画出来 newxs = [] newys = [] for line in lines:
def skeletonize_image(self, img_convert): skeleton = skeletonize(img_convert) return skeleton
from skimage.morphology import skeletonize from skimage import data import matplotlib.pyplot as plt from skimage.util import invert # Invert the horse image image = invert(data.horse()) # perform skeletonization skeleton = skeletonize(image) # display results fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(8, 4), sharex=True, sharey=True) ax = axes.ravel() ax[0].imshow(image, cmap=plt.cm.gray) ax[0].axis('off') ax[0].set_title('original', fontsize=20) ax[1].imshow(skeleton, cmap=plt.cm.gray) ax[1].axis('off') ax[1].set_title('skeleton', fontsize=20) fig.tight_layout() plt.show()
def build(msk): dis = distance_transform_edt(msk) ske = skeletonize(msk>128) graph = sknw.build_sknw(ske, True) rst = build_graph(graph, dis, True) return rst
def gen_line_detections(didx_list, dataset, saa_version, relative_path, line_model_version, model_fcn, re_transform, device, save_line_detections): # for seg_im, seg_idx in dataset: # iterate over segments for didx in tqdm(didx_list, desc=saa_version): # print(didx) seg_im, gt_boxes, gt_labels = dataset[didx] # access meta seg_rec = dataset.get_seg_rec(didx) image_name, scale, seg_bbox, _, view_desc = get_segment_meta(seg_rec) res_name = "{}{}".format(image_name, view_desc) # make seg image is large enough for line detector if seg_im.size[0] > 224 and seg_im.size[1] > 224: # prepare input inputs = preprocess_line_input(seg_im, 1, shift=0) center_im = re_transform(inputs[4]) # to pil image center_im = np.asarray(center_im) # to numpy try: # apply network output = apply_detector(inputs, model_fcn, device) # visualize_net_output(center_im, output, cunei_id=1, num_classes=2) # plt.show() # prepare output outprob = np.mean(output, axis=0) lbl_ind = np.argmax(outprob, axis=0) lbl_ind_x = lbl_ind.copy() lbl_ind_x[np.max(outprob, axis=0) < 0.7] = 0 # 7 lbl_ind_80 = lbl_ind.copy() lbl_ind_80[ np.max(outprob, axis=0) < 0.8] = 0 # remove squeeze() from outprob in order to fix a bug! # save line detections if save_line_detections: # line result folder line_res_path = "{}results/results_line/{}/{}".format( relative_path, line_model_version, saa_version) make_folder(line_res_path) # save lbl_ind_x outfile = "{}/{}_lbl_ind.npy".format( line_res_path, res_name) np.save(outfile, lbl_ind_x.astype(bool)) if False: # compute skeleton skeleton = skeletonize(lbl_ind_x) # save skeleton outfile = "{}/{}_skeleton.npy".format( line_res_path, res_name) np.save(outfile, skeleton.astype(bool)) except Exception as e: # Usually CUDA error: out of memory print res_name, e.message, e.args
count = 0 positions = [] countInts = 0 for i in range(3000): positions.append((0, 0)) while True: ret, frame = vidObj.read() if frame is None: break #Using preProcess to extract greyscale and binary images img, binImg = preProcess(frame) #getting skeleton from the binary image skeleton = skeletonize(binImg) ''' rows = len(skeleton[1]) cols = len(skeleton) for i in range(cols): for j in range(rows): if skeleton[i][j] == 1: cv2.circle(img, (j,i), 0, (0, 255, 0), -2) ''' #finding intersections from the skeleton. Looking #for any valid intersection between two fish spines. intersections = getSkeletonIntersection(skeleton) for h in intersections: print(h[0], h[1]) #append intersection coordinates #together with frame number
def skel_and_thld(img): #thld img img[img > 0] = 1 #skeletonize return morph.skeletonize(img)
def processAlgorithm(self, parameters, context, feedback): try: import networkx as nx from osgeo import gdal as osgdal from skimage.morphology import medial_axis, skeletonize from skimage.util import invert from skimage.io import imread except Exception as e: feedback.reportError( QCoreApplication.translate('Error', '%s' % (e))) feedback.reportError(QCoreApplication.translate('Error', ' ')) feedback.reportError( QCoreApplication.translate( 'Error', 'Error loading modules - please install the necessary dependencies' )) return {} rlayer = self.parameterAsRasterLayer(parameters, self.Raster, context) sMethod = 0 #self.parameterAsInt(parameters, self.SkelMethod, context) distance = parameters[self.distance] sdistance = parameters[self.sdistance] inv = parameters[self.inv] fname = ''.join( random.choice(string.ascii_lowercase) for i in range(10)) outFname = os.path.join(tempfile.gettempdir(), '%s.tif' % (fname)) rect = rlayer.extent() dp = rlayer.dataProvider() raster = dp.dataSourceUri() xres = rlayer.rasterUnitsPerPixelX() yres = rlayer.rasterUnitsPerPixelY() img = imread(raster) stats = dp.bandStatistics(1, QgsRasterBandStats.All, rect, 0) if dp.bandCount() != 1 or stats.maximumValue > 1: feedback.reportError( QCoreApplication.translate( 'Error', 'Tool requires a binary raster input - please run the Thresholding tool.' )) return {} if inv: img = invert(img) nrows, ncols = img.shape if sMethod == 0: skeleton = skeletonize(img, method='lee').astype(float) elif sMethod == 1: skeleton = medial_axis(img).astype(float) driver = osgdal.GetDriverByName('GTiff') dataset = driver.Create( outFname, ncols, nrows, 1, osgdal.GDT_Float32, ) dataset.SetGeoTransform( (rect.xMinimum(), xres, 0, rect.yMaximum(), 0, -yres)) wkt_prj = rlayer.crs().toWkt() dataset.SetProjection(wkt_prj) band = dataset.GetRasterBand(1) band.SetNoDataValue(0) band.WriteArray(skeleton) dataset, band = None, None outSHP = os.path.join(tempfile.gettempdir(), '%s.shp' % (fname)) if distance > 0: #Vectorize - dissolve - simplify - split params = { 'input': outFname, 'type': 0, 'column': 'value', '-s': False, '-v': False, '-z': False, '-b': False, '-t': False, 'output': outSHP, 'GRASS_REGION_PARAMETER': None, 'GRASS_REGION_CELLSIZE_PARAMETER': 0, 'GRASS_OUTPUT_TYPE_PARAMETER': 2, 'GRASS_VECTOR_DSCO': '', 'GRASS_VECTOR_LCO': '', 'GRASS_VECTOR_EXPORT_NOCAT': False } outSkel = st.run("grass7:r.to.vect", params, context=context, feedback=feedback) params = { 'INPUT': outSkel['output'], 'FIELD': [], 'OUTPUT': 'memory:' } outVector = st.run("native:dissolve", params, context=context, feedback=feedback) params = { 'INPUT': outVector['OUTPUT'], 'METHOD': 0, 'TOLERANCE': distance, 'OUTPUT': 'memory:' } templines = st.run("native:simplifygeometries", params, context=context, feedback=feedback) params = { 'INPUT': templines['OUTPUT'], 'LINES': templines['OUTPUT'], 'OUTPUT': 'memory:' } tempOut = st.run('native:splitwithlines', params, context=context, feedback=feedback) else: #Vectorize - split params = { 'input': outFname, 'type': 0, 'column': 'value', '-s': False, '-v': False, '-z': False, '-b': False, '-t': False, 'output': outSHP, 'GRASS_REGION_PARAMETER': None, 'GRASS_REGION_CELLSIZE_PARAMETER': 0, 'GRASS_OUTPUT_TYPE_PARAMETER': 2, 'GRASS_VECTOR_DSCO': '', 'GRASS_VECTOR_LCO': '', 'GRASS_VECTOR_EXPORT_NOCAT': False } templines = st.run("grass7:r.to.vect", params, context=context, feedback=feedback) params = { 'INPUT': templines['output'], 'LINES': templines['output'], 'OUTPUT': 'memory:' } tempOut = st.run('native:splitwithlines', params, context=context, feedback=feedback) params = {'INPUT': tempOut['OUTPUT'], 'OUTPUT': 'memory:'} explodeOut = st.run("native:explodelines", params, context=context, feedback=feedback) G = nx.Graph() for feature in explodeOut['OUTPUT'].getFeatures(QgsFeatureRequest()): try: geom = feature.geometry().asPolyline() start, end = geom[0], geom[-1] startx, starty = start endx, endy = end length = feature.geometry().length() branch = [(startx, starty), (endx, endy)] G.add_edge(branch[0], branch[1], weight=length) except Exception as e: feedback.reportError( QCoreApplication.translate('Node Error', '%s' % (e))) fields = QgsFields() prj = QgsCoordinateReferenceSystem(wkt_prj) (writer, dest_id) = self.parameterAsSink(parameters, self.Network, context, fields, QgsWkbTypes.LineString, prj) fet = QgsFeature() skip_edges = [] minD = xres * 1.1 for circle in nx.cycle_basis(G): #Fix x node intersections start, curDist, end2 = None, None, None cLen = len(circle) if cLen <= 4: skip = [] for enum, end in enumerate(circle): if G.degree(end) != 3: cLen = -1 if start == None: start = end start1 = end continue elif enum == 1: start2 = end elif enum == 2: end1 = end else: end2 = end dx, dy = start[0] - end[0], start[1] - end[1] dist = math.sqrt((dx**2) + (dy**2)) if curDist == None: curDist = dist if dist > minD or dist != curDist: cLen == -1 break curDist = dist skip.extend([(start, end), (end, start)]) start = end if end2: dx, dy = start[0] - start1[0], start[1] - start1[1] dist = math.sqrt((dx**2) + (dy**2)) if dist > minD or dist != curDist: cLen == -1 skip.extend([(start, start1), (start1, start)]) #Close circle if cLen == 4: skip_edges.extend(skip) polylines = [[ QgsPointXY(start1[0], start1[1]), QgsPointXY(end1[0], end1[1]) ], [ QgsPointXY(start2[0], start2[1]), QgsPointXY(end2[0], end2[1]) ]] for points in polylines: outGeom = QgsGeometry.fromPolylineXY(points) fet.setGeometry(outGeom) writer.addFeature(fet, QgsFeatureSink.FastInsert) for edge in G.edges(data=True): if edge not in skip_edges: L = edge[2]['weight'] start = edge[0] end = edge[1] vertices = [G.degree(start), G.degree(end)] if L < sdistance and sum(vertices) == 2: continue points = [ QgsPointXY(start[0], start[1]), QgsPointXY(end[0], end[1]) ] outGeom = QgsGeometry.fromPolylineXY(points) fet.setGeometry(outGeom) writer.addFeature(fet, QgsFeatureSink.FastInsert) return {self.Network: dest_id}
def skeleton_with_erotion(filled_image, erode_iter, dilate_iter): kernel = np.ones((3, 3), np.uint8) dilate = cv2.dilate(filled_image, kernel, iterations=dilate_iter) erosion = cv2.erode(dilate, kernel, iterations=erode_iter) skeleton_image = skeletonize(erosion, method='lee') return skeleton_image
def Thin(self): pix = array(self.__im) pix = pix / 255 pix = morphology.skeletonize(pix) pix = pix.astype(int) * 255 self.__im = fromarray(pix)
def run(self, ips, snap, img, para=None): img[:] = skeletonize(snap > 0) img *= 255
can be useful for feature extraction, and/or representing an object's topology. ``skeletonize`` works by making successive passes of the image. On each pass, border pixels are identified and removed on the condition that they do not break the connectivity of the corresponding object. """ from skimage.morphology import skeletonize from skimage import data import matplotlib.pyplot as plt from skimage.util import invert # Invert the horse image image = invert(data.horse()) # perform skeletonization skeleton = skeletonize(image) # display results fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(8, 4), sharex=True, sharey=True) ax = axes.ravel() ax[0].imshow(image, cmap=plt.cm.gray) ax[0].axis('off') ax[0].set_title('original', fontsize=20) ax[1].imshow(skeleton, cmap=plt.cm.gray)
from matplotlib import pyplot as plt from skimage.morphology import skeletonize img = cv2.imread('/Users/I533569/PycharmProjects/Biometria/Lab3/circles.png', 0) plt.imshow(img) plt.show() kernel1 = np.ones((3, 3), np.uint8) kernel4 = np.ones((9, 9), np.uint8) kernelDiff = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]).astype('uint8') img1 = cv2.erode(img, kernel1) img2 = cv2.erode(img, kernel4) img3 = cv2.erode(img, kernelDiff) plt.imshow(img1) plt.show() plt.imshow(img2) plt.show() plt.imshow(img3) plt.show() skeleton = skeletonize(img.clip(0, 1)) plt.imshow(skeleton) plt.show()
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) labels = label(edges) num_labels = np.max(labels) edge_distance = np.zeros(num_labels + 1) for i in range(num_labels + 1): other_distance = scipy.ndimage.distance_transform_edt(~((labels > 0) & (labels != (i)))) edge_distance[i] = np.median(other_distance[labels == (i)]) regions = regionprops(labels)
def stroke_thickness(in_img): skel, distance = medial_axis(in_img, return_distance=True) skeleton = skeletonize(in_img) # Distance to the background for pixels of the skeleton dist = distance * skeleton return dist[dist > 0]
cv2.createTrackbar("Threshold", "Thresholing", thresholdValue, 250, empty) while True: imgCrop = imgLine.copy() # load new copy every cycle thresholdValue = cv2.getTrackbarPos( "Threshold", "Thresholing") # getting value from tracker ret, imgCrop = cv2.threshold(imgCrop, thresholdValue, 255, 0) # thresholding image cv2.imshow("Thresholing", imgCrop) # show image in the same window as tracker if cv2.waitKey(1) & 0xFF == ord('q'): break imgCrop = cv2.bitwise_not(imgCrop) skeleton_lee = skeletonize(imgCrop, method='lee') (thresh, imgToSave) = cv2.threshold( skeleton_lee, 127, 255, cv2.THRESH_BINARY) # making it black/white cv2.destroyAllWindows() cv2.namedWindow("Colouring") brushColor = (0) brushSize = 10 imgMask = imgToSave cv2.setMouseCallback("Colouring", line_drawing) while True: imgToSave = imgMask cv2.imshow("Colouring", imgToSave)
def skeleton_drawing(in_img): edge_img = skeletonize(in_img, method='lee') return (edge_img > 0).astype(np.uint8)
def skeleton_gray(image): return skeletonize(image)