目录
一、图像轮廓检测
1.什么是图像轮廓检测
2.轮廓检测的作用
二、轮廓检测和轮廓绘制
1.轮廓检测
2.轮廓绘制
三、轮廓特征
1.轮廓的周长
2.轮廓的面积
1.求面积
2.面积的用法
3.轮廓的外接圆
4.轮廓的外接矩形
四、轮廓近似
1.轮廓近似是什么
2.轮廓近似的作用
3.代码实现
五、模版匹配
1.模版匹配是什么
2.模版匹配的作用
3.代码实现
一、图像轮廓检测
1.什么是图像轮廓检测
图像轮廓检测是一种计算机视觉技术,用于识别和提取图像中物体的边界。通过轮廓检测,我们可以找到图像中不同物体的形状和结构,这对于许多应用场景非常重要
2.轮廓检测的作用
轮廓检测的作用主要是提取和分析图像中物体的边界,帮助识别和定位物体。它用于图像分割、形状分析、物体识别、目标跟踪等应用,通过找到物体的轮廓线,能够更准确地理解和处理图像数据。
二、轮廓检测和轮廓绘制
1.轮廓检测
- 读取图像,转换成灰度图
- 进行阈值处理 ,变成二值图像,更容易找到轮廓
- 使用findContours方法寻找轮廓
- 将寻找到的轮廓储存在ndarray数据里
import cv2iphone = cv2.imread('iphone.png')
# iphone_gray = cv2.imread('iphone.png', cv2.IMREAD_GRAYSCALE)
iphone_gray = cv2.cvtColor(iphone, cv2.COLOR_BGR2GRAY) # 转换成灰度图
cv2.imshow('iphone_gray', iphone_gray)
cv2.waitKey(0)# 阈值处理
# 这样做的主要目的是简化图像数据,使得轮廓检测算法能够更容易地识别和提取出物体的边缘
ret, iphone_binary = cv2.threshold(iphone_gray, 120, 255, cv2.THRESH_BINARY)
cv2.imshow('iphone_binary', iphone_binary)
cv2.waitKey(0)'''查找轮廓'''
_, contours, hierarchy = cv2.findContours(iphone_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
print(hierarchy)
print(len(contours))
2.轮廓绘制
- 使用drawContours方法绘制轮廓:
- 传入底层图像,要绘制的轮廓图像,选择要绘制的轮廓的索引(-1为全选),轮廓的颜色,线条的粗细
'''绘制轮廓'''
image_copy = iphone.copy() # 创建图像的副本
image_copy = cv2.drawContours(image=image_copy, contours=contours, contourIdx=-1, color=(255, 0, 0), thickness=3)
cv2.imshow('Contours_show', image_copy)
cv2.waitKey(0)
输出:
三、轮廓特征
轮廓的一些数据,轮廓的周长,面积,外接圆,外接矩形等特征
1.轮廓的周长
- 先查找到轮廓
- 选择其中的一个轮廓使用arcLength方法求该轮廓的周长
import cv2iphone = cv2.imread('iphone.png')
iphone_gray = cv2.cvtColor(iphone, cv2.COLOR_BGR2GRAY) # 转换成灰度图
ret, iphone_binary = cv2.threshold(iphone_gray, 120, 255, cv2.THRESH_BINARY)'''查找轮廓'''
_, contours, hierarchy = cv2.findContours(iphone_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
print(hierarchy)"""轮廓特征"""
'''周长'''
# arcLength(InputArray curve, bool closed)
# curve,输入的二维点集(轮廓顶点),可以是 vector 或 Mat 类型。
# closed,用于指示曲线是否封闭。
length = cv2.arcLength(contours[0], closed=True)
print(length)
输出:
952.437722325325
2.轮廓的面积
1.求面积
- 使用contoursArea方法求某个轮廓的面积
'''面积'''
# cv2.contourArea(contourl,oriented]) -> retval 面积
# contour:顶点构成的二维向量组(如轮廓列表contours中的一个轮廓)
# oriented:定向区域标志,默认值为 False,返回面积的绝对值,Ture 则根据轮廓方向返回带符号的数值area_0 = cv2.contourArea(contours[0])
area_1 = cv2.contourArea(contours[1])
print(area_0, area_1)
输出:
50716.5 255.5
2.面积的用法
- 通过面积筛选符合条件的轮廓
- 这里是轮廓面积大于10000的
# 根据面积显示特定轮廓
a_list = []
for i in range(len(contours)):if cv2.contourArea(contours[i]) > 10000:a_list.append(contours[i])
image_copy = iphone.copy()
image_copy = cv2.drawContours(image=image_copy, contours=a_list, contourIdx=-1, color=(255, 0, 0), thickness=4)
cv2.imshow('Contours_10000', image_copy)
cv2.waitKey(0)
输出:
3.轮廓的外接圆
- minEnclosingCircle方法返回该轮廓外接圆的圆心坐标和圆的半径
- 再通过circle方法绘制外接圆
'''外接圆'''
cnt = contours[6]
(x, y), r = cv2.minEnclosingCircle(cnt)
iphone_circle = cv2.circle(iphone, (int(x), int(y)), int(r), (255, 0, 0), thickness=4)
cv2.imshow('circle', iphone_circle)
cv2.waitKey(0)
输出:
这里选取的是笔杆的那个轮廓
4.轮廓的外接矩形
- 使用boundingRect方法获取轮廓的最小外接矩形的数据
- x,y表示外接矩形左上角点的坐标,
- w,h表示该外接矩形的宽高
- 再使用rectangle方法绘制该外接矩形
'''外接矩形'''
x, y, w, h = cv2.boundingRect(cnt) # 计算轮廓的最小外接矩形
iphone_rectangle = cv2.rectangle(iphone, (x, y), (x + w, y + h), (255, 0, 0), thickness=4)
cv2.imshow('rectangle', iphone_rectangle)
cv2.waitKey(0)
输出:
这里外接圆和外接矩形是放在一张图片上绘制的
四、轮廓近似
1.轮廓近似是什么
轮廓近似是指对轮廓进行逼近或拟合,得到近似的轮廓。在图像处理中,轮廓表示了图像中物体的边界,因此轮廓近似可以用来描述和识别物体的形状。
2.轮廓近似的作用
- 减少复杂度:通过简化轮廓,使其变得更简单,减少计算量和存储需求。
- 提高效率:使得后续处理,如物体识别和分析,更快速、更高效。
- 减少噪声:去除轮廓中的细小噪声和不必要的细节,使其更加平滑和稳定。
- 方便分析:使得形状分析和目标跟踪变得更容易,因为简化的轮廓更清晰明了。
3.代码实现
- 轮廓近似使用的是approxPolyDP方法
- 返回的是一个储存了轮廓数据的ndarray数据
- epsilon参数越小,表示近似出来的轮廓越精细,反之越粗糙
"""轮廓的近似"""
import cv2# approx=cv2.approxPolyDP(curve,epsilon, closed)
# 参数说明:
# curve:输入轮廓。
# epsilon:近似精度,即两个轮廓之间最大的欧式距离。该参数越小,得到的近似结果越接近实际轮廓;反之,得到的近似结果会更加粗略。
# closed:布尔类型的参数,表示是否封闭轮廓。如果是 True,表示输入轮廓是封闭的,近似结果也会是封闭的;否则表示输入轮廊不是封闭的,近似结果也是不封闭的
# 返回值:
# approx:近似结果,是一个ndarray数组,为1个近似后的轮廓,包含了被近似出来的轮席上的点的坐标 被当做轮廓使用时需要[]lk = cv2.imread('lk1.jpg')
lk = cv2.resize(lk, (500, 600))
lk_new = lk.copy() # 创建副本
lk_gray = cv2.cvtColor(lk, cv2.COLOR_BGR2GRAY) # 转换成灰度图
ret, lk_binary = cv2.threshold(lk_gray, 120, 255, cv2.THRESH_BINARY) # 进行二值化image, contours, hierarchy = cv2.findContours(lk_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # 获取轮廓
i = cv2.drawContours(lk, contours=contours[2], contourIdx=-1, color=(255, 0, 0), thickness=3)
cv2.imshow('i', i)
cv2.waitKey(0)'''轮廓近似'''
epsilon = 0.01 * cv2.arcLength(contours[2], True) # 设置近似精度
approx = cv2.approxPolyDP(contours[2], epsilon, True) # 对轮廓进行近似image_contours = cv2.drawContours(lk_new, contours=[approx], contourIdx=-1, color=(255, 0, 0), thickness=3)
cv2.imshow('image_contours', image_contours)
cv2.waitKey(0)
输出:
- 左边是查找出来的轮廓,右边是对左边近似出来的轮廓
五、模版匹配
1.模版匹配是什么
模板匹配是一种图像处理技术,用于在一张大图像中找到与小模板图像匹配的区域。其基本思路是将模板图像在目标图像上滑动,通过比较模板图像和目标图像每一部分的相似度,找到最佳匹配的位置。
2.模版匹配的作用
-
目标检测:帮助识别和定位图像中的特定物体或图案。例如,识别图像中的标志、物体或字符。
-
图像对比:用于比较图像中是否存在已知的图像区域或模式,例如在监控系统中检测异常行为。
-
形状识别:在图像中寻找特定形状或符号,如文字识别中的字符检测。
-
图像检索:在数据库中查找与查询图像相似的图像,例如在图片搜索引擎中找到匹配的图像。
-
自动化检查:在生产线中用于自动化检测产品是否符合标准,比如检测零件的位置和形状。
3.代码实现
- 使用matchTemplate方法进行模版匹配
- 返回一个矩阵,其中每个元素表示像素点的匹配程度
- 使用minMaxLoc方法找到矩阵中的最大值以及最大值位置
- 使用该最大值位置确定模版匹配到的图形的左上角位置
- 再使用rectangle绘制出匹配到的矩形
"""模版匹配"""# cv2.matchTemplate(image, templ, method, result=None, mask=None)
# image:待搜索图像
# templ:模板图像
# method:计算匹配程度的方法,可以有:
# TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;匹配越好,值越小;匹配越差,值越大。
# TM_CCORR 相关匹配法:该方法采用乘法作;数值越大表明匹配程度越好。
# TM_CCOEFF 相关系数匹配法:数值越大表明匹配程度越好。
# TM_SQDIFF_NORMED 归一化平方差匹配法,匹配越好,值越小;匹配越差,值越大。
# TM_CCORR_NORMED 归一化相关匹配法,数值越大表明匹配程度越好。
# TM_CCOEFF_NORMED 归一化相关系数匹配法,数值越大表明匹配程度越好。import cv2kele = cv2.imread('kele.png')
moban = cv2.imread('moban.png')
cv2.imshow('kele', kele)
cv2.imshow('moban', moban)
cv2.waitKey(0)h, w = moban.shape[:2] # 获取模版图片的高宽
res = cv2.matchTemplate(kele, moban, cv2.TM_CCOEFF_NORMED) # 返回一个矩阵,其中每个元素表示该位置与模板的匹配程度
# cv2.minMaxLoc可以获取矩阵中的最小值和最大值,以及最小值的索引号和最大值的索引号
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 最小值、最大值、最小值位置、最大值位置
top_left = max_loc # 最大值为匹配到的模板的左上角
bottom_right = (top_left[0] + w, top_left[1] + h) # 主图片中用模版匹配到的位置
kele_template = cv2.rectangle(kele, top_left, bottom_right, (255, 0, 0), thickness=3)cv2.imshow('kele_template', kele_template)
cv2.waitKey(0)
输出:
左边是原图,中间是匹配使用的模版,右边是模版匹配到的矩形区域