如何使用 Python OpenCV 检测正方形的角点?
在下图中,我使用 OpenCV harris 角点检测器仅检测正方形的角点(以及外部正方形内的较小正方形)。但是,我还检测到图像侧面数字的角点。我怎样才能让它只关注正方形而不是数字?我需要一种在执行 OpenCV 角点检测时忽略数字的方法。代码、输入图像和输出图像如下:
import cv2 as cv
img = cv.imread(filename)
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv.cornerHarris(gray, 2, 3, 0.04)
dst = cv.dilate(dst,None)
# Threshold for an optimal value, it may vary depending on the image.
img[dst>0.01*dst.max()]=[0,0,255]
cv.imshow('dst', img)
输入图像
Harris 角点检测器的输出
In the image below, I am using OpenCV harris corner detector to detect only the corners for the squares (and the smaller squares within the outer squares). However, I am also getting corners detected for the numbers on the side of the image. How do I get this to focus only on the squares and not the numbers? I need a method to ignore the numbers when performing OpenCV corner detection. The code, input image and output image are below:
import cv2 as cv
img = cv.imread(filename)
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv.cornerHarris(gray, 2, 3, 0.04)
dst = cv.dilate(dst,None)
# Threshold for an optimal value, it may vary depending on the image.
img[dst>0.01*dst.max()]=[0,0,255]
cv.imshow('dst', img)
Input image
Output from Harris corner detector
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是使用传统图像处理的潜在方法:
获取二进制图像。我们加载图片,转换为灰度, 高斯模糊,然后<一href="https://opencv24-python-tutorials.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html#adaptive-thresholding" rel="nofollow noreferrer">自适应阈值获取黑白二值图像。然后,我们使用轮廓区域过滤去除小噪声。在此阶段,我们还创建两个空白蒙版。
检测水平线和垂直线。现在我们通过创建水平形状来隔离水平线内核 并执行 形态操作。为了检测垂直线,我们执行相同的操作,但使用垂直形状的内核。我们将检测到的线绘制到单独的掩模上。
找到交点。这个想法是,如果我们将水平和垂直蒙版结合起来,交点将是角点。我们可以执行按位与运算在两个面具上。最后我们找到每个交点的质心并通过绘制突出显示角点一个圆圈。
这是管道的可视化
输入图像
->
二进制图像检测到水平线
->
水平掩码检测到垂直线
->
垂直掩码按位和两个掩码
->
检测到交叉点->
角->
清理角<一href="https://i.sstatic.net/E5L35.png" rel="nofollow noreferrer">
结果并不完美,但非常接近。问题来自于倾斜图像导致的垂直掩模上的噪声。如果图像居中且没有角度,则结果将是理想的。您也许可以微调内核大小或迭代以获得更好的结果。
代码
Here's a potential approach using traditional image processing:
Obtain binary image. We load the image, convert to grayscale, Gaussian blur, then adaptive threshold to obtain a black/white binary image. We then remove small noise using contour area filtering. At this stage we also create two blank masks.
Detect horizontal and vertical lines. Now we isolate horizontal lines by creating a horizontal shaped kernel and perform morphological operations. To detect vertical lines, we do the same but with a vertical shaped kernel. We draw the detected lines onto separate masks.
Find intersection points. The idea is that if we combine the horizontal and vertical masks, the intersection points will be the corners. We can perform a bitwise-and operation on the two masks. Finally we find the centroid of each intersection point and highlight corners by drawing a circle.
Here's a visualization of the pipeline
Input image
->
binary imageDetected horizontal lines
->
horizontal maskDetected vertical lines
->
vertical maskBitwise-and both masks
->
detected intersection points->
corners->
cleaned up cornersThe results aren't perfect but it's pretty close. The problem comes from the noise on the vertical mask due to the slanted image. If the image was centered without an angle, the results would be ideal. You can probably fine tune the kernel sizes or iterations to get better results.
Code