机器学习:opencv--图像轮廓检测

目录

一、图像轮廓检测

1.什么是图像轮廓检测

2.轮廓检测的作用

二、轮廓检测和轮廓绘制

1.轮廓检测

2.轮廓绘制

三、轮廓特征

1.轮廓的周长

2.轮廓的面积

1.求面积

2.面积的用法

3.轮廓的外接圆

4.轮廓的外接矩形

四、轮廓近似

1.轮廓近似是什么

2.轮廓近似的作用

3.代码实现

五、模版匹配

1.模版匹配是什么

2.模版匹配的作用

3.代码实现


一、图像轮廓检测

1.什么是图像轮廓检测

        图像轮廓检测是一种计算机视觉技术,用于识别和提取图像中物体的边界。通过轮廓检测,我们可以找到图像中不同物体的形状和结构,这对于许多应用场景非常重要

 

2.轮廓检测的作用

        轮廓检测的作用主要是提取和分析图像中物体的边界,帮助识别和定位物体。它用于图像分割、形状分析、物体识别、目标跟踪等应用,通过找到物体的轮廓线,能够更准确地理解和处理图像数据。

 

二、轮廓检测和轮廓绘制

1.轮廓检测

  1. 读取图像,转换成灰度图
  2. 进行阈值处理 ,变成二值图像,更容易找到轮廓
  3. 使用findContours方法寻找轮廓
  4. 将寻找到的轮廓储存在ndarray数据里
import cv2

iphone = 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.轮廓的周长

  1. 先查找到轮廓
  2. 选择其中的一个轮廓使用arcLength方法求该轮廓的周长
import cv2

iphone = 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.轮廓近似的作用

  1. 减少复杂度:通过简化轮廓,使其变得更简单,减少计算量和存储需求。
  2. 提高效率:使得后续处理,如物体识别和分析,更快速、更高效。
  3. 减少噪声:去除轮廓中的细小噪声和不必要的细节,使其更加平滑和稳定。
  4. 方便分析:使得形状分析和目标跟踪变得更容易,因为简化的轮廓更清晰明了。

 

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.模版匹配的作用

  1. 目标检测:帮助识别和定位图像中的特定物体或图案。例如,识别图像中的标志、物体或字符。

  2. 图像对比:用于比较图像中是否存在已知的图像区域或模式,例如在监控系统中检测异常行为。

  3. 形状识别:在图像中寻找特定形状或符号,如文字识别中的字符检测。

  4. 图像检索:在数据库中查找与查询图像相似的图像,例如在图片搜索引擎中找到匹配的图像。

  5. 自动化检查:在生产线中用于自动化检测产品是否符合标准,比如检测零件的位置和形状。

 

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 cv2

kele = 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)

输出:

左边是原图,中间是匹配使用的模版,右边是模版匹配到的矩形区域

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃什么芹菜卷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值