OpenCV(python)一键入门--十六篇(图像匹配)

举报
拓佑豪 发表于 2021/08/03 16:27:43 2021/08/03
【摘要】 简单介绍了轮廓匹配和Hu矩轮廓匹配的函数使用

本系列OpenCV博客旨在以最简单的方式分享OpenCV知识,欢迎大家交流和提出指导意见


1:模板匹配

案例需要的图像以及模板如下:

ma.jpg     ma-1.png

我们需要从一个图片中,找到这个“模板” ,然后把它从图中标记出来,像这样:

示例代码如下:

import cv2 as cv
import numpy as np

#图像模板匹配
src = cv.imread("ma.jpg")  #待测图片
tpl = cv.imread("ma-1.png")  #模板
cv.imshow("input", src)
cv.imshow("tpl", tpl)

th, tw = tpl.shape[:2]
result = cv.matchTemplate(src, tpl, cv.TM_CCORR_NORMED)
cv.imshow("result", result)
t = 0.98
loc = np.where(result > t)

for pt in zip(*loc[::-1]):
    cv.rectangle(src, pt, (pt[0] + tw, pt[1] + th), (0, 0, 255), 1, 8, 0)
cv.imshow("demo", src)

cv.waitKey(0)
cv.destroyAllWindows()

1):matchTemplate模板匹配

cv.matchTemplate(图像,模板,匹配方法)

其中,匹配方法常见如下:

0:差值平方和匹配 CV_TM_SQDIFF

1:标准化差值平方和匹配 CV_TM_SQDIFF_NORMED

2:相关匹配 CV_TM_CCORR

3:标准相关匹配 CV_TM_CCORR_NORMED

4:相关匹配 CV_TM_CCOEFF

5:标准相关匹配 CV_TM_CCOEFF_NORMED

2):np.where

属于numpy的范畴,感兴趣的小伙伴可以去AI Gallery学习

链接:https://marketplace.huaweicloud.com/markets/ai/gallery_course.html

np.where用于选择查找,其操作对象必须是ndarray,他会返回对应的索引。

>>> import numpy as np
>>> a = np.array([2,4,6,8,10])
>>> a_where = np.where(a>5)  #声明查找条件为 a>5
>>> print(a_where)   #打印返回值,也就是np.where给出的索引 
(array([2, 3, 4], dtype=int64),)
>>> print(a[np.where(a>5)])   #打印 列表中 对应的索引 的值
[ 6  8 10]

模板匹配是很简单也是很基础的算法,不过也有不足。

这里给出下图,来直观的感受一下:任何形变,背景修改,都难以检测


2:Hu矩轮廓匹配

import cv2 as cv
import numpy as np

def contours_info(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    return contours
    #转灰度,二值化,寻找轮廓,返回轮廓信息

src = cv.imread("abc.png")
src2 = cv.imread("abc-b.png")
cv.imshow("input1", src)
cv.imshow("input2", src2)

# 从函数那获取轮廓信息
contours1 = contours_info(src)
contours2 = contours_info(src2)

# 几何矩计算后进行hu矩计算
mm2 = cv.moments(contours2[0])
hum2 = cv.HuMoments(mm2)

# 轮廓匹配
for c in range(len(contours1)):
    mm = cv.moments(contours1[c])
    hum = cv.HuMoments(mm)
    dist = cv.matchShapes(hum, hum2, cv.CONTOURS_MATCH_I1, 0)  #轮廓匹配

    if dist < 1:
        cv.drawContours(src, contours1, c, (0, 0, 255), 2, 8)  # 绘制轮廓
    print("dist %f"%(dist))

cv.imshow("contours_analysis", src)

cv.waitKey(0)
cv.destroyAllWindows()

cv.moment输入轮廓即可得出结果。我在这篇博客简单介绍过:OpenCV(python)一键入门--十五篇(矩形弧长面积计算,轮廓逼近及其横纵比过滤)

这里稍微补充一下,opencv中提供了moments()来计算图像中的中心矩(最高到三阶),可以计算轮廓集合矩。根据几何矩可以计算图像的中心位置,得到中心位置可以计算中心距,然后可以得到hu矩。

所以,我们可以使用:

1):cv.HuMoment

输入cv.moment过后的值,即可输出一个含有七个元素的数组。

2):cv.matchShapes

可以看成:cv.matchShapes(轮廓1,轮廓2,两个轮廓比较的方法,应用于method的特定参数--我们使用0就可以了

具体比较方式参考下图

效果如下:

附上原图素材:

abc.png

abc-b.png


资料补充:

几何矩是由Hu在1962年提出的,具有平移、旋转和尺度不变性。 定义如下

图像转自:https://www.cnblogs.com/sddai/p/11430732.html

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。