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

  • 前言
  • 一、Canny边缘检测
  • 二、模板匹配
  • 2.1函数说明
  • 2.2匹配步骤
  • 2.3模板匹配六种模式对比
  • 三、多模板匹配
  • 总结


前言

本文介绍了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')

openCV 人员边界越线 python opencv边缘匹配_opencv

二、模板匹配

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

2.1函数说明

  • 函数res = cv2.matchTemplate(img,template,method):
    参数img:待匹配的图像(原图)
    参数temple:搜索模板,需要和原图一样的数据类型且尺寸不能大于原图像
    参数method:指定匹配方法,有如下几种:






  • 函数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()

openCV 人员边界越线 python opencv边缘匹配_边缘检测_02


openCV 人员边界越线 python opencv边缘匹配_计算机视觉_03

openCV 人员边界越线 python opencv边缘匹配_opencv_04


openCV 人员边界越线 python opencv边缘匹配_python_05


openCV 人员边界越线 python opencv边缘匹配_边缘检测_06


openCV 人员边界越线 python opencv边缘匹配_python_07

三、多模板匹配

多模板匹配使用的是一个阈值,当大于这个阈值时,我们认为已经获得一个模板的匹配值,而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 人员边界越线 python opencv边缘匹配_计算机视觉_08

总结

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