OpenCV
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,它主要用于实时图像处理和计算机视觉任务。
本篇介绍的是:轮廓检测和轮廓特征。
本篇所用图片数据:
链接:训练图片
https://pan.baidu.com/s/1-C6sxtw-S3vL1I5SwaStlQ?pwd=dzvx
提取码:dzvx
轮廓检测
轮廓检测是计算机视觉和图像处理中的一个重要任务,它涉及从图像中识别和提取出对象的边界。这些边界通常对应于图像中亮度或颜色发生显著变化的位置。轮廓检测对于形状分析、物体识别、图像分割等多种应用至关重要。
1. 读取图片(灰度图)
首先,使用opencv库方法读取需要处理的图片,读取时将其转化为灰度图。
import cv2
import numpy
phone = cv2.imread('phone.png')
phone_gray = cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY)
cv2.imshow('phone_b',phone_gray)
cv2.waitKey(0)
2. 二值化阈值处理
先进行二值化阈值处理:灰度图像转换只有0和255,增强轮廓明显。
ret,phone_binary = cv2.threshold(phone_gray,120,255,cv2.THRESH_BINARY)
cv2.imshow('phone_binary',phone_binary)
cv2.waitKey(0)
3. 查找轮廓
注意:查找轮廓时,每个轮廓是分开的,查找时会返回每个轮廓的列表。
查找轮廓函数:img,contours,hierarchy = cv2.findContours(原图img,检索模式mode,轮廓近似方法method)
函数返回三个值:
# -->mode:cv2.RETR_TREE返回所有的轮廓,建立一个完整的组织结构的轮廓
# -->contours:包含图像中所有轮廓的list对象,其中每一个独立的轮廓信息以边界点为坐标,储存在numpy数组中
# -->hierarchy:轮廓的层次结构
image,contours,hierarchy = cv2.findContours(GGbond_binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
print(len(contours)) #查看一共找到了多少个轮廓
------------
9
4. 画轮廓
轮廓的绘制:cv2.drawContours(image,contours,contourIdx,color,thickness)
-- image:需要绘制的原始图像;
-- contours:轮廓的列表,通常是通过cv2.findContours()函数获得的;
-- contourIdx:指定了要绘制轮廓列表中的哪个轮廓。如果其值为负数(如-1),则绘制所有轮廓。如果你只想绘制特定索引的轮廓,可以传递 该轮廓的索引(注意索引从0开始);
-- color:绘制轮廓时所使用的颜色;
-- thickness:这是轮廓线的粗细。如果其值为负数,则轮廓内部将被填充。如果你想要一个带有特定粗细的轮廓线,就传递一个正整数。
这里,为了保护原始图像,我们通常复制一个相同的图像,用复制的图像绘画:
"""-----轮廓绘制-----"""
image_copy = phone.copy()
image_copy = cv2.drawContours(image=image_copy,contours=contours,contourIdx=-1,color=(0,255,0),thickness=3)
cv2.imshow('Contours_show',image_copy)
cv2.waitKey(0)
这样就画出了图片中的轮廓。
轮廓特征
获取轮廓后,通常基于轮廓的特征进行筛选、识别和处理。例如,基于轮廓的周长和面积对轮廓进行筛选,然后绘制筛选的目标轮廓或其最小外接矩形。
1. 轮廓面积
计算轮廓的面积cv2.contourArea(contours)
参数:传入要求的轮廓
上面提到了,查找轮廓时,每个轮廓是分开的,查找时会返回每个轮廓的列表。我们可以在列表中切片取到目标轮廓。例如,下面试例中求第0个和第1个轮廓的面积:
# cv2.contourArea()计算轮廓的面积
area_0 = cv2.contourArea(contours[0])
area_1 = cv2.contourArea(contours[1])
print(area_0,area_1)
-----------------------
50716.5 255.5
2. 轮廓周长
计算一个轮廓的周长或弧长cv2.arcLength(contours)
参数:传入要求的轮廓
length = cv2.arcLength(contours[0],closed=True)
print(length)
-------------
952.437722325325
3. 外接圆
计算轮廓外接圆:(x,y),r = cv2.minEnclosingCircle(contours)
-- 参数:传入轮廓,返回该轮廓外接圆的圆心(x,y),以及半径r
绘制外接圆函数:cv2.circle(img,(x,y),r,color,thickness)
-- 参数:img:需要绘制的图片
(x,y):圆心
r:半径
color:线条颜色
thickness:线条粗细
cnt = contours[6]
(x,y),r = cv2.minEnclosingCircle(cnt)
phone_circel = cv2.circle(phone,(int(x),int(y)),int(r),(0,255,0),2)
cv2.imshow('phone_circle',phone_circel)
cv2.waitKey(0)
4. 外接矩形
计算轮廓的最小外接矩形:x,y,w,h = cv2.boundingRect()
-- 参数:传入轮廓,返回w,h为长宽,x,y为矩形左上角的坐标点
绘制外接矩形:cv2.rectangle(img, pt1, pt2, color, thickness)
-- 参数:img:需要绘制的图片
pt1:矩形左上角的坐标(x,y)
pt2:矩形长宽范围(x+w,y+h)
color:线条颜色
thickness:线条粗细
x,y,w,h = cv2.boundingRect(cnt)
phone_rectangle = cv2.rectangle(phone,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('phone_rectangle',phone_rectangle)
cv2.waitKey(0)
总结
本篇介绍了:
- 轮廓检测:其中注意的是,每个轮廓都以列表的形式返回。可以切片获取每个轮廓。
- 轮廓特征:轮廓面积、轮廓周长、外接圆以及外界矩形。