首页 > 解决方案 > 如何检测低分辨率形状的角落?

问题描述

我有一个低分辨率的凹四边形光标。我的目标是找到他指出的点。所以我想找到4个角,然后找到彼此最远的角。通常工作正常,但并不总是准确地检测角落。使用模糊效果不大,但我不确定这是否足够。你会建议我做些什么来改善我的结果?

cursor = cv.bitwise_and(captureHSV, captureHSV, mask=mask)

#resizeCurs = cv.resize(cursor, (0, 0), fx=0.60, fy=0.60)
#blurCurs = blur = cv.blur(cursor, (3,3))
grayCurs = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)

corners = cv.goodFeaturesToTrack(grayCurs, 4, 0.01, 1)
corners = np.int0(corners)

coordList = []
for corner in corners:
    x, y = corner.ravel()
    cv.circle(cursor, (x, y), 1, (255, 0, 0), 1)
    coordList.append([x, y])

在此处输入图像描述 在此处输入图像描述

标签: pythonopencv

解决方案


在检测到图像的精巧边缘之后,当然可以预先转换为灰度和模糊,您可以扩大和侵蚀边缘以消除嘈杂的凹凸并填充小间隙。

但这不足以将结果平滑到 4 个点,您需要使用该cv2.approxPolyDP方法来近似生成的轮廓。

以下是可能的情况:

import cv2
import numpy as np

def process(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img_blur = cv2.GaussianBlur(img_gray, (7, 7), 0)
    img_canny = cv2.Canny(img_blur, 50, 50)
    kernel = np.ones((0, 0))
    img_dilate = cv2.dilate(img_canny, kernel, iterations=1)
    img_erode = cv2.erode(img_dilate, kernel, iterations=1)
    return img_erode

def get_contours(img):
    contours, hierarchies = cv2.findContours(process(img), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    for cnt in contours:
        if cv2.contourArea(cnt) > 10:
            peri = cv2.arcLength(cnt, True)
            approx = cv2.approxPolyDP(cnt, peri * 0.04, True)
            cv2.drawContours(img, approx, -1, (0, 0, 255), 8) 

img1 = cv2.imread("cursor1.png")
img2 = cv2.imread("cursor2.png")

get_contours(img1)
get_contours(img2)

cv2.imshow("Image 1", img1)
cv2.imshow("Image 2", img2)

cv2.waitKey(0)

输出:

在此处输入图像描述

红点是程序绘制的部分。


推荐阅读