图像的模板匹配,Python OpenCV 取经之旅第 29 天

Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。

基础知识铺垫

今天的 1 个小时,我们要交给模板匹配了,而且学习起来比较轻松,因为我看到一句话,模板匹配是最没用的匹配方式,应用场景很少。

就喜欢这样的技术,学起来的摩擦力小,不容易掉头发。

模板匹配

模板匹配大意就是在整个图像区域寻找已有的小图像,在寻找之前,你需要准备一个待寻找的图像,以及一个小图

寻找的形式是从左到右,从上到下,这个找法很形象了,一行一行的找。

在寻找的过程中,通过 OpenCV 封装好的算法,计算小图与大图的匹配度,这个匹配度越大,两张图片相同的可能性越大。

模板匹配函数原型

在 Python 中,通过 help 函数,可以查看任意函数的说明。

matchTemplate(image, templ, method[, result[, mask]]) -> result

参数说明如下:

  • <kbd>image</kbd>:待检索的图像;
  • <kbd>templ</kbd>:小图,要求不大于待搜索图像;
  • <kbd>method</kbd>:匹配方法,下表提供,算法不需要掌握,知道用法即可;
  • <kbd>result</kbd>:结果图像;
  • <kbd>mask</kbd>:掩膜,需要与 <kbd>templ</kbd> 有相同的数据类型和大小,默认不设置,仅支持 <kbd>method</kbd> 参数值为 <kbd>TM_SQDIFF</kbd> 和 <kbd>TM_CCORR_NORMED</kbd>

关于 <kbd>method</kbd> 参数的值有以下几种情况:

  • <kbd>TM_SQDIFF</kbd>:平方差匹配;
  • <kbd>TM_SQDIFF_NORMED</kbd>:标准平方差匹配,利用平方差来进行匹配,最好匹配为 0,匹配越差,匹配值越大;
  • <kbd>TM_CCORR</kbd>:相关性匹配;
  • <kbd>TM_CCORR_NORMED</kbd>:标准相关性匹配,采用模板和图像间的乘法操作,数越大表示匹配程度较高, 0 表示最坏的匹配效果;
  • <kbd>TM_CCOEFF</kbd>:相关性系数匹配;
  • <kbd>TM_CCOEFF_NORMED</kbd>:标准相关性系数匹配,将模版对其均值的相对值与图像对其均值的相关值进行匹配,1 表示完美匹配,-1 表示糟糕的匹配,0 表示没有任何相关性(随机序列)。

以上内容整理自网络

接下来编写测试代码:

import cv2 as cv

# 读取目标图片,小图
target = cv.imread("./target.jpg")

# 读取模板图片,待查找的图片
template = cv.imread("./template.jpg")

# 获取模板图片的宽高尺寸,用于后面画矩形框
th, tw = template.shape[:2]

# 执行匹配模板,匹配方式选择标准平方差匹配
result = cv.matchTemplate(target, template, cv.TM_SQDIFF_NORMED)

# 输出匹配结果
print(type(result))
cv.imshow("image", result)
cv.waitKey()

注意下图中,最终匹配到的区域颜色最深。

20210130214156690[1].png

下面我们将其标记出来,需要用到一个新的函数,具体如下。

minMaxLoc 函数

该函数是在给定的矩阵中寻找最大值和最小值,并给出它们的位置。

特别说明是如果需要在所有的通道中查找最小或者最大元素,要先将矩阵重新解释为单通道,好吧,引出归一化的概念了。

那我们先把这个函数学到收,之后在把归一化的函数补充上。

函数原型如下:

minMaxLoc(src[, mask]) -> minVal, maxVal, minLoc, maxLoc

原型比较简单,输入一个图像之后,可以返回 4 个值。

这 4 个值分别是,最大值,最小值以及最大值与最小值的位置。

上文我们使用的是 <kbd>cv.TM_SQDIFF_NORMED</kbd> 方法,按照上面的叙述,匹配值最小越好,所以需要获取一下图像的最小值位置。

修改上文代码如下:

import cv2 as cv

# 读取目标图片,小图
target = cv.imread("./target.jpg")
# cv.imshow("target", target)

# 读取模板图片,待查找的图片
template = cv.imread("./template.jpg")
# cv.imshow("template", template)

# 获取模板图片的宽高尺寸,用于后面画矩形框
th, tw = template.shape[:2]

# 执行匹配模板,匹配方式选择标准平方差匹配
result = cv.matchTemplate(target, template, cv.TM_SQDIFF_NORMED)

# 获取最小值位置
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
tl = min_loc
print(tl)
# 通过模板的宽和高,找到匹配最好的右下角地方
# tl[0],tl[1]分别代表最佳匹配值地方的 x 和 y
br = (tl[0]+tw, tl[1]+th)
cv.rectangle(target, tl, br, (0,0,255),2)
# 输出匹配结果

cv.imshow("image", target)
cv.waitKey()

最终运行效果如下,匹配成功。


20210130215837373[1].png

其他的 <kbd>method</kbd>你自行测试吧。

补一个 cv2.normalize

学习新的函数,先把概念通读,尝试理解,理解不要在降格到应用。

归一化就是把待处理的数据进行处理,这里的处理就是某种算法了,然后将数据限制在一个范围内(范围由我们自己定义)

归一化之后,数据会变得更加有可比性,具体原因还未找到可靠资料。

函数原型如下:

dst = cv2.normalize(src[, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]]])

参数说明:

  • <kbd>src</kbd>:输入数组;
  • <kbd>dst</kbd>:与 src 大小相同的输出数组;
  • <kbd>alpha</kbd>:如果 norm_type 为 NORM_MINMAX ,则 alpha 为最小值或最大值,如果 norm_type 为其他类型,则为归一化要乘的系数;
  • <kbd>beta</kbd>:如果 norm_type 为 NORM_MINMAX ,则 beta 为最小值或最大值,如果 norm_type 为其他类型,beta 被忽略,此处不会被用到,一般传入 0;
  • <kbd>norm_type</kbd>:归一化类型,常见的有 NORM_L1, NORM_L2, NORM_INF, NORM_MINMAX;
  • <kbd>dtype</kbd>:如果取负值时,dst 与 src 同样的类型,否则,dst 和 src 有同样的通道数,且此时图像深度为 CV_MAT_DEPTH(dtype);
  • <kbd>mask</kbd>:掩膜。

应用起来比较简单,例如本篇博客中的案例,只需要增加如下代码即可。

# 归一化处理
cv.normalize(result, result, 0, 1, cv.NORM_MINMAX, -1)

橡皮擦的小节

希望今天的 1 个小时,你有所收获,我们下篇博客见~

相关阅读


技术专栏

  1. Python 爬虫 100 例教程,超棒的爬虫教程,立即订阅吧
  2. Python 爬虫小课,精彩 9 讲

逗趣程序员

  1. 曝光,程序员的 10 个摸鱼神器
  2. 5 个无聊 Python 程序,用 Python 整蛊你的朋友们吧
  3. 10 年老程序员教你甩锅必杀技,论【如何优雅的甩锅】
  4. 你想被开除吗?来看看程序员【离职小技巧】吧

今天是持续写作的第 <font color="red">70</font> / 100 天。
如果你有想要交流的想法、技术,欢迎在评论区留言。


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,063评论 6 510
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,805评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,403评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,110评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,130评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,877评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,533评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,429评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,947评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,078评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,204评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,894评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,546评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,086评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,195评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,519评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,198评论 2 357

推荐阅读更多精彩内容