如何使用 canny 管理图像比较中的 MIN_MATCH_COUNT?

Posted

技术标签:

【中文标题】如何使用 canny 管理图像比较中的 MIN_MATCH_COUNT?【英文标题】:How to manage MIN_MATCH_COUNT in image comparison using canny? 【发布时间】:2021-05-19 06:53:50 【问题描述】:

我正在使用 canny 进行图像比较。在使用精明的图像边缘进行比较后,我得到了匹配和不匹配对象的正确结果。有时它没有给出正确的结果,为此我需要不断更改 MIN_MATCH_COUNT。 任何保留 MIN_MATCH_COUNT 和 canny 的解决方案都应该比较图像的每个边缘。

MIN_MATCH_COUNT = 20

img1 = canny.copy()
img2 = canny1.copy()


# Initiate SIFT detector
sift = cv.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks = 50)
flann = cv.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1,des2,k=2)
# store all the good matches as per Lowe's ratio test.
good = []
for m,n in matches:
    if m.distance < 0.7*n.distance:
        good.append(m)
if len(good)>MIN_MATCH_COUNT:
    src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
    dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
    M, mask = cv.findHomography(src_pts, dst_pts, cv.RANSAC,5.0)
    matchesMask = mask.ravel().tolist()
    h,w = img1.shape
    pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
    dst = cv.perspectiveTransform(pts,M)
    img2 = cv.polylines(img2,[np.int32(dst)],True,255,3, cv.LINE_AA)
    print ("Both the images are matching")
else:
    print( "Not enough matches are found and hence images are not same - / and hence both the images are not matching".format(len(good), MIN_MATCH_COUNT) )
    matchesMask = None
draw_params = dict(matchColor = (0,255,0), # draw matches in green color 
                   singlePointColor = None,
                   matchesMask = matchesMask, # draw only inliers
                   flags = 2)
img3 = cv.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)
plt.imshow(img3, 'gray'),plt.show()   

下面是当 MIN_MATCH_COUNT 为 20 时我得到的结果不匹配的图像,如果我将其更改为 9,那么它会说图像匹配。

类似地,在下图中,实际的键脊不匹配,但它仍然在不考虑匹配点的情况下给出图像匹配。

【问题讨论】:

【参考方案1】:

您可以使用相对标准,因此您可以使用匹配关键点占模型关键点总数的百分比,而不是使用 MIN_MATCH_COUNT 的绝对值。通过这种方式,您可以根据您的具体测试设置一个阈值,比如说..30%(IDK,只是一个例子)。这就是我在类似问题中所做的。 比如:

matching = len(good)/len(kp1)*100

这样0

min_threshold = 40

if matching > min_threshold:
...

【讨论】:

你能分享一些例子吗? 已编辑,基本上你从绝对值变为阈值的相对值。您仍然需要进行试验才能找到适合您的值。 好的...谢谢...下面的代码对我来说效果更好,但无法识别打印图像匹配或不匹配的 if 条件。 img1 = cv.imread('Key1.png',cv.IMREAD_GRAYSCALE) # queryImage img2 = cv.imread('Key2.png',cv.IMREAD_GRAYSCALE) # trainImage # 启动 SIFT 检测器 sift = cv.SIFT_create() # 找到SIFT 的关键点和描述符 kp1, des1 = sift.detectAndCompute(img1,None) kp2, des2 = sift.detectAndCompute(img2,None) # FLANN 参数 FLANN_INDEX_KDTREE = 1 index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5) search_params = dict(checks=50) # 或者传递空字典 flann = cv.FlannBasedMatcher(index_params,search_params) 匹配= flann.knnMatch(des1,des2,k=2) # 只需要绘制好的匹配,所以创建一个掩码 matchesMask = [[0,0] for i in range(len(matches))] # 根据 Lowe 的论文 for i 进行比率测试,( m,n) in enumerate(matches): if m.distance

以上是关于如何使用 canny 管理图像比较中的 MIN_MATCH_COUNT?的主要内容,如果未能解决你的问题,请参考以下文章

应用 Canny 边缘检测后如何计算边缘数?

OpenCV中的图像处理 —— 图像梯度+Canny边缘检测+图像金字塔

身份证号码图像提取--基于canny边缘检测的连通域检测算法

如何访问 cv::canny 阈值的梯度幅度图像

MATLAB中的Canny算子矩阵:如何实现/获取? (只是过滤器,没有边缘检测器)

Python 2.7:Canny Edge detection TypeError(“图像数据无法转换为浮点数”)中的错误