Opencv学习笔记(三)-----Canny边缘检测和模板匹配

前言

本文介绍了Canny检测和模板匹配的方法以及代码示例和效果图对比

一、Canny边缘检测

  • Canny函数常用用法:edge = cv2.Canny(image, threshold1, threshold2)

    参数image:是需要处理的原图像,该图像必须为单通道的灰度图;

    参数threshold1:阈值1;

    参数threshold2:阈值2;

其中较大的阈值2用于检测图像中明显的边缘,但一般情况下检测的效果不会那么完美,边缘检测出来是断断续续的。所以这时候用较小的第一个阈值用于将这些间断的边缘连接起来。

四组不同的边界阈值的对比效果图,代码如下:

# -*- coding: utf-8 -*-
import numpy as np
import cv2
def cv_show(img,name,writename):
    cv2.imshow(name,img)
    cv2.imwrite(writename,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
img = cv2.imread('lena.jpg',0)
# 指定的边界越小检测得越详细
v1 = cv2.Canny(img,100,200)
v2 = cv2.Canny(img,40,200)
v3 = cv2.Canny(img,40,100)
v4 = cv2.Canny(img,20,50)
# 对比四组不同的边界阈值的处理效果
res = np.hstack((v1,v2,v3,v4))
cv_show(res,'res','res.jpg')

在这里插入图片描述

二、模板匹配

使用模板在图像中查找目标,找到原图中模板的坐标,根据模板的大小可以框出原图中模板位置;

2.1函数说明

  • 函数res = cv2.matchTemplate(img,template,method):

    参数img:待匹配的图像(原图)

    参数temple:搜索模板,需要和原图一样的数据类型且尺寸不能大于原图像

    参数method:指定匹配方法,有如下几种:

    • ​ CV_TM_CCOEFF:计算相关系数,计算的值越大,越相关;

    • ​ CV_TM_CCOEFF_NORMED:归一化相关系数匹配法,计算的值越接近1,越相关;

    • ​ CV_TM_CCORR:计算相关性,计算的值越大,越相关;

    • ​ CV_TM_CCORR_NORMED:计算归一化相关性,计算的值越接近1,越相关;

    • ​ CV_TM_SQDIFF:计算平方差,计算的值越小,越相关;

    • ​ CV_TM_SQDIFF_NORMED:计算归一化平方差,计算的值越接近0,越相关;

  • 函数min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res):

    参数res为cv2.matchTemplate处理后得到的矩阵;

    返回值为图像中模板的最小值和最大值和对应位置;

2.2匹配步骤

第一步:读入原图片和模板图片的灰度图;

第二步:使用cv2.matchtemplate(img, template, method) 设置匹配方法进行模板匹配,获得大量的结果;

第三步:使用min_val, max_val, min_loc, max_loc = cv2.minMaxLoc() 找出最大值数所在的位置;

第四步:使用cv2.rectangle() 画框操作;

2.3模板匹配六种模式对比

# -*- coding: utf-8 -*-
import numpy as np
import cv2
from matplotlib import pyplot as plt

def cv_show(img, name, writename):  
    cv2.imshow(name, img)
    cv2.imwrite(writename, img)
    cv2.waitKey()
    cv2.destroyAllWindows()

# 读取原始图像
img = cv2.imread('lena.jpg ',0)
# 读取模板图像
template = cv2.imread('modle.png',0)
# 获取模板高h和长w
h = template.shape[0]
w = template.shape[1]
methods =['cv2.TM_CCOEFF','cv2.TM_CCOEFF_NORMED','cv2.TM_CCORR','cv2.TM_CCORR_NORMED','cv2.TM_SQDIFF','cv2.TM_SQDIFF_NORMED']
png = '.png'
for meth in methods:
    #复制原图,因为在做处理时会修改原图
    img2 = img.copy()
    #匹配方法的真值
    method = eval(meth)
    #模板匹配方法设置
    res = cv2.matchTemplate(img, template, method)
    # 获取图像中最小值和最大值的位置
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    #如果是平方差匹配cv2.TM_SQDIFF或归一化平方差匹配到cv2.TM_SQDIFF_NORMED,取最小值
    if method in [cv2.TM_SQDIFF,cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc
    bottom_right = (top_left[0] +w,top_left[1]+h)
    # 在原图中画模板位置矩形
    cv2.rectangle(img2,top_left,bottom_right,255,2)
	#每张图的保存名称
    endname = meth + png
    plt.subplot(121),plt.imshow(res,cmap='gray')
    plt.xticks([]),plt.yticks([])
    plt.subplot(122),plt.imshow(img2, cmap='gray')
    plt.xticks([]),plt.yticks([])
    plt.suptitle(meth)
    #保存每张图
    plt.savefig(endname)
    plt.show()

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、多模板匹配

多模板匹配使用的是一个阈值,当大于这个阈值时,我们认为已经获得一个模板的匹配值,而cv2.matchTemplate匹配出的res是不同匹配方法得到的矩阵;

第一步:读入图片原图片和模板并进行灰度化;

第二步:匹配模板,获得res;

第三步:使用np.where(res>0.8) 筛选合适的位置;

第四步:使用loc[::-1]将位置进行调换,使用*loc[::-1]使得矩阵发生拆分,使用zip进行两两组合;

第五步:使用cv2.rectangle画多个矩阵并展示;

# -*- coding: utf-8 -*-
import numpy as np
import cv2
from matplotlib import pyplot as plt

# 读取原始图像
img = cv2.imread('mario.jpg')
# 对图像进行二值化
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 读取模板图像
template = cv2.imread('mario_coin.jpg',0)
# 获取模板高h和长w的范围
h,w = template.shape[:2]
# 设定匹配方法
res = cv2.matchTemplate(img_gray, template, cv2.TM_CCORR_NORMED)  #
threshold = 0.8
# 获取匹配程序大于0.8的坐标
loc = np.where(res >=threshold)
# 开始匹配
for pt in zip(*loc[::-1]):#*表示可选参数
    bottom_right = (pt[0] + w,pt[1]+ h )
    cv2.rectangle(img,pt,bottom_right,(0,0,255),2)
cv2.imshow('img', img)
cv2.waitKey()
cv2.imwrite('mario_end.png', img)
cv2.destroyAllWindows()

在这里插入图片描述

总结

小白在学习OpenCV过程中的学习笔记,可能理解的不到位,若有不对之处请指正。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值