【初识OpenCV】(6) -- 轮廓近似与模板匹配

OpenCV

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,它主要用于实时图像处理和计算机视觉任务。

本篇介绍的是:轮廓近似和模板匹配。

本篇所用图片数据:

链接:训练图片
提取码:dzvx

轮廓近似

轮廓近似是一种在图像处理中常用的技术,用于对图像中物体的轮廓进行逼近或拟合,从而得到近似的轮廓。这种技术通过减少轮廓上的点数,简化轮廓信息,为后续的轮廓特征提取、物体识别等任务提供便利。

尝试简单理解为,用较少的点拟合一个图像的大概轮廓:

比如:下图中就可以明显看出轮廓近似的效果(左边正常轮廓,右边近似轮廓)。

在这里插入图片描述

1. 读取灰度图

import cv2

phone = cv2.imread('GGbond.jpg')
phone = cv2.resize(phone,(400,400))
phone_gray = cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY)

2. 二值化阈值处理

ret,phone_thresh = cv2.threshold(phone_gray,120,255,cv2.THRESH_BINARY)

3. 查找轮廓

image,contours,hierarchy = cv2.findContours(phone_thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

4. 轮廓近似

cv2.approxPolyDP(curve, epsilon, closed[, approxCurve])
参数:
-- curve:输入的轮廓,通常是一个点集,由轮廓检测函数(如 cv2.findContours())返回。
-- epsilon:近似精度,决定了轮廓近似的精细程度。
-- closed:一个布尔值,指定输出轮廓是否为封闭的。如果轮廓是封闭的(如圆形或矩形),则应该设置为 True-- approxCurve:输出参数,用于存储近似后的轮廓。如果不需要返回这个值,可以省略。
# epsilon越大拟合越粗糙,为使效果看的更明显,此处我们乘0.05
epsilon = 0.05*cv2.arcLength(contours[38],True)
# 轮廓近似
approx = cv2.approxPolyDP(contours[38],epsilon,True)

5. 绘画近似图像

GGbond_new = GGbond.copy()
# 绘画正常轮廓图,用以对比效果
image_contours38 = cv2.drawContours(GGbond,contours[38],contourIdx=-1,color=(0,255,0),thickness=3)
# 绘画近似图
image_contours = cv2.drawContours(GGbond_new,[approx],contourIdx=-1,color=(0,255,0),thickness=3)
cv2.imshow('GGbond_38',image_contours38)
cv2.waitKey(0)
cv2.imshow('image_contours',image_contours)
cv2.waitKey(0)

在这里插入图片描述

模板匹配

模板匹配是一种基于图像的技术,主要用于在图像中寻找与给定模板图像相似的部分。这种技术通过比较模板图像与待匹配图像中每个局部区域的相似度,来定位模板图像在待匹配图像中的位置。

为了识别匹配区域,我们必须通过滑动来将模板图像与源图像进行比较,一次移动一个像素(从左到右,从上到下)。在每个位置,都会计算一个度量(度量计算公式),以便它表示该位置的匹配“好”或“坏”程度。

1. 读取图片

import cv2
coco = cv2.imread('coco.png')
coco_part = cv2.imread('coco_part.png')
cv2.imshow('coco',coco)
cv2.imshow('coco_part',coco_part)
cv2.waitKey(0)

在这里插入图片描述

2. 查找与模板图像最匹配的区域

cv2.matchTemplate()函数用于查找与模板图像最匹配的区域:

result = cv2.matchTemplate(image, template, method, mask=None)
参数:
-- image:源图像,即要在其中搜索模板的大图像。
-- template:模板图像,即要在源图像中搜索的小图像。
-- method:指定匹配方法的标志。OpenCV 提供了多种匹配方法,如平方差匹配(cv2.TM_SQDIFF)、归一化平方差匹配						 	   (cv2.TM_SQDIFF_NORMED)、相关系数匹配(cv2.TM_CCORR)、归一化相关系数匹配(cv2.TM_CCOEFF)等。
-- mask:(可选)一个与模板图像同样大小的掩码图像,用于指定模板图像中的哪些区域应该被考虑在匹配过程中。如果掩码中的某个像素值为			  零,则忽略模板中对应位置的像素。

cv2.matchTemplate()函数返回一个矩阵result,其大小取决于源图像和模板图像的大小以及所选的匹配方法。矩阵中的每个元素都表示模板在源图像中对应位置处的匹配程度得分。根据所选的匹配方法,这些得分可能表示相似度(值越大越好)差异度(值越小越好)

res = cv2.matchTemplate(coco,coco_part,cv2.TM_CCOEFF_NORMED)

3. 找到得分的最大值及其位置

一旦有了匹配得分矩阵,你可以使用 cv2.minMaxLoc() 函数来找到得分的最大值(或最小值,取决于匹配方法)及其位置。这个位置通常被认为是模板在源图像中的最佳匹配位置

cv2.minMaxLoc() 函数用于找到得分的最大值及其位置:

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(src, mask=None)
主要参数:
-- src: 输入的数组(一维或多维)。在图像处理中,这通常是处理后的图像或图像的一部分(例如,通过 cv2.matchTemplate() 得到的匹		配得分矩阵)。
返回值:
-- minVal: 数组中的最小值。
-- maxVal: 数组中的最大值。
-- minLoc: 最小值的坐标(对于二维数组,这是一个包含两个元素的元组,分别表示 x 和 y 坐标)。
-- maxLoc: 最大值的坐标(同样,对于二维数组,这是一个包含两个元素的元组)。
min_val,max_val,min_loc,max_loc = cv2.minMaxLoc(res)
top_left = max_loc #接收最大位置的坐标(左上角)
h,w = coco_part.shape[:2] # 取匹配图片的高和宽
bottem_right = (top_left[0] + w,top_left[1] + h) # 获取匹配图片的右下角坐标

4. 绘制匹配区域

cv2.rectangle()函数在 OpenCV 中用于在图像上绘制矩形。它允许你指定矩形的位置(通过其左上角和右下角的坐标)以及矩形的颜色、线宽等属性。

cv2.rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)
参数:
-- img: 要在其上绘制矩形的图像。
-- pt1: 矩形左上角的坐标,为元组形式 (x, y)-- pt2: 矩形右下角的坐标,同样为元组形式 (x, y)-- color: 矩形的颜色,为 BGR 格式(即蓝、绿、红),例如 (255, 0, 0) 表示蓝色。
-- thickness: 可选参数,指定矩形边框的粗细。如果设置为 -1(或 cv2.FILLED),则矩形会被填充。
-- lineType: 可选参数,指定线条的类型。大多数情况下,使用默认值即可。
-- shift: 可选参数,指定点坐标中的小数位数。
coco_template = cv2.rectangle(coco,top_left,bottem_right,(0,255,0),2)
cv2.imshow('coco_template',coco_template)
cv2.waitKey(0)

在这里插入图片描述

这样,我们就匹配到了模板图像在源图像上的位置。

完整代码

import cv2
coco = cv2.imread('coco.png')
coco_part = cv2.imread('coco_part.png')
cv2.imshow('coco',coco)
cv2.imshow('coco_part',coco_part)
cv2.waitKey(0)

# 查找与模板图像最匹配的区域
res = cv2.matchTemplate(coco,coco_part,cv2.TM_CCOEFF_NORMED)

# 找到得分的最大值及其位置
min_val,max_val,min_loc,max_loc = cv2.minMaxLoc(res)
top_left = max_loc
h,w = coco_part.shape[:2]
bottem_right = (top_left[0] + w,top_left[1] + h)

# 绘制匹配区域
coco_template = cv2.rectangle(coco,top_left,bottem_right,(0,255,0),2)
cv2.imshow('coco_template',coco_template)
cv2.waitKey(0)

总结

本篇介绍了:

  1. 轮廓近似:用少量的点,描绘大致的模型。近似精度epsilon越小拟合越精细,越大拟合越粗糙。
  2. 模板匹配:先用cv2.matchTemplate()函数查找与模板图像最匹配的区域,再用cv2.minMaxLoc() 函数找到得分的最大值及其位置,然后使用cv2.rectangle()函数绘制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值