代码之家  ›  专栏  ›  技术社区  ›  SinLok

确定凹点

  •  2
  • SinLok  · 技术社区  · 7 年前

    如果我使用 goodFeaturesToTrack

    enter image description here enter image description here

    下图是实际运行的示例: enter image description here

    2 回复  |  直到 7 年前
        1
  •  2
  •   alkasm Anuj Gautam    7 年前

    正如在评论中提到的,这里似乎最容易做的事情是用一个盒子过滤器(或类似的,但椭圆形状)来卷积你的图像,这将给你整个图像的窗口平均值。你可以简单地在你的角点索引这个卷积结果。如果这些点的卷积结果大于50%,那点周围会有更多的白色,因此,这是一个凹点。否则,它是凸的。下面是代码中可能出现的情况。

    import cv2
    import numpy as np
    from itertools import tee
    
    def pairwise(iterable):
        a, b = tee(iterable)
        next(b, None)
        return zip(a, b)
    
    # read image as grayscale
    img = cv2.imread('example.png', 0)
    
    # get corner points, remove duplicate/nearby points
    contours = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1]
    contour = contours[0]
    pts = np.array([contour[0]] + [pt1 for pt0, pt1 in pairwise(contour) if not (abs(pt0 - pt1) <= 1).all()])
    x, y = pts[:, -1, 0], pts[:, -1, 1]
    
    # get the kernel that you will sum around your corner points
    kernel = np.float64(cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (13, 13)))
    kernel /= np.sum(kernel)
    
    # convolve the image with the kernel, and pull out the sums at the corner points
    conv = cv2.filter2D(img/255, cv2.CV_64F, kernel)
    neighborhood_sums = conv[y, x]
    
    # concave indices have more white than black around them, so convolution will be >= 1/2
    concave_indices = neighborhood_sums >= 0.5
    
    # draw markers
    marked = cv2.merge([img, img, img])
    for pt, concave in zip(pts, concave_indices):
        color = (255, 0, 255) if concave else (0, 255, 0)
        marker = cv2.MARKER_TRIANGLE_UP if concave else cv2.MARKER_TRIANGLE_DOWN
        cv2.drawMarker(marked, tuple(pt[0]), color, markerType=marker, markerSize=10, thickness=3)
    

    itertools recipes 用于成对迭代(例如。 s -> (s0, s1), (s1, s2), ... ). 这对问题一点都不重要,但对于我来说,消除从中获取的重复点非常有用 findContours() . 在那之后,其余的按照前面所描述的进行。你可以画你自己的内核或任何你喜欢的,但我只是从 getStructuringElement() 由于您可以使用任意大小的椭圆(尽管注意这会返回一个形状奇怪的内核,但您可以自己更好地定义一个圆)。请注意,内核的大小在这里是以总宽度指定的,而不仅仅是半径,并且它由其中的1个数进行规范化,因此结果总是在0和1之间。

    Marked concave vs convex points

        2
  •  1
  •   Kinght 金    7 年前

    它使用的解决方案之一 HIT_MISS_MORPH 在不同的内核中:

    如果选择此内核:

    [[-1 -1  1]
     [-1 -1  1]
     [ 1  1  1]]
    

    mask = cv2.morphologyEx(threshed, cv2.MORPH_HITMISS, kernel, anchor=(-1,-1))
    

    enter image description here

    在原始图像上绘制:

    enter image description here


    在不同的内核中找到锚(旋转基本内核并|或反转它):

    enter image description here

    在原始图像上以颜色显示:

    enter image description here