如何在OpenCV中过滤关键点匹配?

问题描述

我最近开始处理OpenCV,现在我正在尝试对另一张图片中的图案图片进行检查。
现在的问题是,匹配器可以找到关键点的良好匹配项,但没有考虑它们之间的相对位置。

例如:

pattern was found correctly

the pattern is not in the picture,but it's still found

在这两种情况下,匹配器都找到了关键点的匹配项并正确地进行了匹配,但是在第二种情况下,匹配项是在图片的不同位置发现的。我想将这种情况处理为“找不到模式”,最好使用内置的OpenCV函数。

比较关键点的功能:

def keypoint_match(pic,pattern,pic_desc,pattern_desc,drawDebug=False):
    bf = cv2.BFMatcher()
    matches = bf.knnMatch(pattern_desc[1],pic_desc[1],k=2)

    good = []
    for m,n in matches:
        if (m.distance < 0.75 * n.distance):
            good.append(m)

    print('Good matches:',len(good))
    find = True if len(good) > 10 else False

    if drawDebug or find:
        image = cv2.drawMatches(np.uint8(pattern),pattern_desc[0],np.uint8(pic),pic_desc[0],good,flags=0,matchColor=(0,255,0),singlePointColor=(255,0))
        plt.figure(figsize=(20,20))
        plt.axis('off')
        plt.imshow(image.astype(np.uint8))
        plt.show()
    return good,find

结果:

test1.png
Good matches: 32
Pattern found: 'smile.png'
Result: pattern found

test2.png
Good matches: 25
Pattern found: 'smile.png'
Result: pattern found

测试图片和我上传的here的完整源代码。

UPD:
据我所知,有3种方法可以在图像中找到对象:

  • 模板匹配
  • 关键点检测
  • 轮廓检测

我的任务是找出图片中是否有特定标志。图片中的标志可能会略微倾斜或具有不同的比例。图像的背景色也可能不同,例如,如果是照片。通常,标志具有困难的结构,但它们的轮廓大致相同。
这就是为什么我选择“关键点检测”方法的原因。
我为测试添加了2张照片。
问题是存在部分匹配项,我想排除它们,但我不知道如何。图片仅用于演示部分匹配的问题。

pattern was found correctly on photo

the pattern is not in the photo,but it's still found

解决方法

免责声明:

如果我的理解是正确的,那是臭名昭著的XY-Problem的情况,并且您实际上想在随后的两个测试图像中找到微笑图像,而不管使用哪种精确技术,那么我想介绍以下内容:

解决方案:template_matching.py

import cv2
import numpy as np
from matplotlib import pyplot as plt
import sys

img_rgb = cv2.imread(sys.argv[1])
img_gray = cv2.cvtColor(img_rgb,cv2.COLOR_BGR2GRAY)
template = cv2.imread('smile.png',0)
w,h = template.shape[::-1]

res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
    cv2.rectangle(img_rgb,pt,(pt[0] + w,pt[1] + h),(0,255),2)

cv2.imwrite('res.png',img_rgb)

您可以这样运行:

结果:

python3 template_matching.py test1.png

它会给您这样的结果:

smiley detected

另一张测试图像

python3 template_matching.py test2.png

给出这样的结果:

Nothing found

说明:

我可能并不完全熟悉SIFT(所谓的最佳特征检测算法),但是它通常用于检测角点,提取特征等等。仅凭这一点还不够(至少在我看来)。您需要将这些功能放在一起以定义对象。然后您可以尝试在测试图像集中找到该对象。

我想到的另一种方法可能涉及更多,并且不使用内置的黑盒opencv函数,而是使用霍夫线变换来获取两条垂直线。然后,霍夫圆变换以得到由微笑形成的半圆。他们在一起将定义您的“笑脸”。但无论如何,您确实要在问题中说:

最好具有内置的OpenCV函数。

然后上述解决方案对于我认为的问题是最快,最简洁的。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...