目录
2 代码实现 matchTemplate()与minMaxLoc()
1 概念
左边这张脸我们称之为模板,我们使用模板匹配右边的图像,获取模板是图像的哪一部分
我们的方法先把目标图像(右侧)分成与模板图像大小相同的若干块,然后使用模板中的对应像素点对比若干块中的一块的对应像素点,比哪块更像模板
判定相似度有以下6个方法
我们下面进行使用,模板我们选用猫的脸部,目标图像我们选用整只猫
2 代码实现 matchTemplate()与minMaxLoc()
2.1 一张图只匹配最合适的一块
导入库后读取两张图片,然后把他们转换为灰度图,上面一个是目标图片,template是模板
获取模板的宽与高
然后查看一下两个图像的shape
之后我们使用第一种方法TM_SQDIFF进行匹配,得到结果后查看结果的shape
我们验证一下上面提到的输出结果形状对不对
A = 456 B = 823 a = 146 b = 198
输出结果
- 第一个值为 456-146+1 = 311
- 第二个值为 823-198+1 = 626
发现符合咱们上面说的结果
之后我们可以使用minMaxLoc()对结果进行操作,这样会返回四个值,分别的意思是
- min_val 最小值
- max_val 最大值
- min_loc 最小值坐标位置
- max_loc 最大值坐标位置
获取的值根据匹配方法的不同,值与相似度的关系也不同,我们当前使用TM_SQDIFF中
- 获取的值越小,模板与原图像的对应坐标位置的图像就越像
- 获取的值越大,模板与原图像的对应坐标位置的图像就越不像
所有方法中获取的坐标位置是区域的左上角点
我们接下来把六种方法都看一下,先把六种方法放到一个列表中,一会儿好遍历
我们遍历每一种方法,循环中的命令含义如下
- 将图复制到另一个变量上
- 使用eval函数,访问到cv2.TM_SQDIFF,method变量的值为在cv2中对应的遍历值,然后打印出来
- 模板匹配,然后获取最小值,最大值,最小值点,最大值点
- 如果方法是cv2.TM_SQDIFF或cv2.TM_SQDIFF_NORMED,我们让左上角点为最小值点,如果不是这两个方法我们让左上角点位最大值点
- 定义终止点bottom_right
- 在img2上绘制矩形
- 生成1行两列的图形展示窗口,在1的位置放置灰度res,省略横坐标与纵坐标
- 在2的位置放置灰度img2
- 将总标题定义为meth
- 展示出来
我们每关闭一个窗口就会弹出另一个窗口,一共有六个窗口,我分别展示一下
- 0
- 2
- 4
- 1
- 3
- 5
我们左侧的res结果可能看不懂,不知道画的是个什么东西,它这个是根据不同的方法计算出来的值,计算出来除最大值,最小值其实是没有意义的,但我们能将值的大小在图上看出来,我们先说左上角点取最大值的四个算法
比如说TM_CCOEFF_NORMED,最大值就是图上最亮的点,这个最亮的点就是左上角点,而res我们可以隐约的看出大概是一个猫的样子
这张的res大概就能看出猫的轮廓来
最大值是最亮的点,最小值就是最暗的点
我们可以看到上面的CCORR是没有将模板匹配正确的,在实际应用中,未经过归一化的方法'cv2.TM_SQDIFF','cv2.TM_CCORR','cv2.TM_CCOEFF'准确度不如归一化后的方法'cv2.TM_SQDIFF_NORMED','cv2.TM_CCORR_NORMED','cv2.TM_CCOEFF_NORMED'高
2.2 一张图匹配合适的多个位置
我们现在使用这个猫的头作为模板
寻找这张图上相似的地方
首先把图和模板以灰度图的形式读进来,然后获取模板宽高
匹配模板并定义置信度,此处我是60%以上就画出来,此时我们TM_CCOEFF_NORMED算法是越大越好,如果是越小越好阈值就应该反过来(0.4)
寻找大于置信度的点在哪
变量loc是一个元组,元组中包含两个数组,第一个数组中的值是相似区域的纵坐标,第二个数组中的值是相似区域的横坐标
将两个坐标值的集压成一个集合,然后遍历,遍历后获取右下角点,然后画出来
loc[::-1}这个让元组逆序,zip(*)是匹配压缩,我在这里举个例子
a = ((1,2,3,4),(5,6,7,8))
for i in zip(*a[::-1]):
print(i)
先把原本a中的两个元组的位置逆序,然后匹配压缩,这个i对应我们项目中的pt,也就是说pt是图片中的坐标点
这里要提一下,当前只是模板匹配,如果我要做目标检测的话我们应该使用机器学习算法,也就是说我们如果拿刚刚那个白猫的脸是不能匹配上面这张图中橘猫与灰猫的脸的
我们可以增大置信,使图像中只画出更少的框子