algorithm - 确定凹点

标签 algorithm opencv image-processing

如果我使用 goodFeaturesToTrack,我可以获得所有角点(红色、蓝色)。但是,我只想保留凹点(蓝色)。我不知道如何实现。我该怎么做?

enter image description here enter image description here

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

最佳答案

正如评论中所提到的,这里似乎很容易做的事情就是将您的图像与盒式滤波器(或类似但具有椭圆形状的滤波器)进行卷积,这将为您提供整个图像的窗口平均值。您可以简单地将此卷积结果索引到您的角点。如果那些点的卷积结果超过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

关于algorithm - 确定凹点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52453040/

相关文章:

c - 为什么在将反向排序数组作为输入时出现段错误?

algorithm - 如何在给定运行时间的情况下编写算法

algorithm - 子数组求和解

opencv - OpenCV中脚的边缘检测

python - 在Python中根据 channel 条件替换图像像素颜色

javascript - 如何从随机 uint8array 渲染图像

3D多边形链相交算法

python - 如何使用openCV删除图像中的行

iphone - 如何在 IOS sdk 中屏蔽图像?

opencv - 显示直方图图openCV