在进行图像轮廓提取时,有的情况下不需要我们提取出精确的轮廓,只要提取出一个接近于轮廓的近似多边形,就可以满足后续的操作。
本期我们来学习如何通过设置参数来找出图像的近似多边形。
完成本期内容,你可以:
- 了解图像轮廓的基本特性
- 学会提取图像的轮廓近似多边形
若要运行案例代码,你需要有:
-
操作系统:Ubuntu 16 以上 或者 Windows10
-
工具软件:VScode 或者其他源码编辑器
-
硬件环境:无特殊要求
-
核心库:python 3.6.13, opencv-contrib-python 3.4.11.39,opencv-python 3.4.2.16
点击下载源码
绘制多边形轮廓
OpenCV中提供了cv2.approxPolyDP()函数来绘制多边形轮廓。
函数原型:approxCurve = cv2.approxPolyDP( curve, epsilon, closed )
approxCurve为逼近多边形点集;
参数描述如下:
- curve:是轮廓。
- epsilon:精度,原始轮廓的边界点与逼近多边形边界之间的最大距离。
- closed:逻辑值。该值为真时,逼近多边形是封闭的;否则,逼近曲线是不封闭的。
计算轮廓面积
OpenCV中提供了cv2.contourArea()函数可以用来计算轮廓面积。
函数原型:cv2. contourArea(contour, oriented=None):
参数描述如下:
- contour:输入的点,一般是图像的轮廓点;
- oriented: 表示某一个方向上轮廓的的面积值,顺时针或者逆时针,一般选择默认false。
计算轮廓周长
OpenCV中提供了cv2.arcLength()函数来计算轮廓周长。
函数原型:cv2. arcLength(curve, closed)
参数描述如下:
- curve :输入的点,一般是图像的轮廓点;
- closed :用来指定对象的形状是闭合的(True),还是打开的一条曲线(False)。
轮廓拟合
边界函数
-
贴合轮廓(近似多边形):cv2.approxPolyDP()
-
包含轮廓点集中的最小矩形:cv2.boundingRect()
-
表示计算二维点集形成封闭、倾斜及最小面积的矩形:cv2. minAreaRect()
-
完全包围已有轮廓的最小圆:cv2.minEnclosingCircle()
-
椭圆拟合cv2. fitEllipse()
-
直线拟合cv2.fitLine()等
OpenCV中提供了cv2.approxPolyDP ()
函数来绘制多边形轮廓。
函数原型: approxCurve = cv2.approxPolyDP( curve, epsilon, closed )
参数说明:
-
approxCurve:逼近多边形点集;
-
curve:是轮廓;
-
epsilon:精度,原始轮廓的边界点与逼近多边形边界之间的最大距离;
-
closed:逻辑值。该值为真时,逼近多边形是封闭的;否则,逼近曲线是不封闭的。
具体步骤
使用图像轮廓技术获取图像轮廓的近似多边形。
步骤一:创建项目工具
创建项目名为使用多边形近似图像轮廓
,项目根目录下新建code
文件夹储存代码,新建dataset
文件夹储存数据,项目结构如下:
使用多边形近似图像轮廓 # 项目名称
├── code # 储存代码文件
├── dataset # 储存数据文件
注:如项目结构已存在,无需再创建。
步骤二:获取轮廓并绘制
- 导入所需模块:OpenCV;
- 读取
dataset
文件夹下的clouds.png
图片; - 将原图像复制,用于绘制图像轮廓;
- 将图像转换为二值图像;
- 获取图像轮廓并绘制;
代码实现
# 导入OpenCV
import cv2
#读取并显示原始图像
o = cv2.imread('../dataset/clouds.png')
cv2.imshow("original",o)
#获取轮廓
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
_,contours, hierarchy = cv2.findContours(binary,
cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)
#直接绘制边缘
adp = o.copy()
adp=cv2.drawContours(adp,contours,-1,(0,0,255),2)
cv2.imshow("result",adp)
步骤三:绘制精度为0.1倍周长的近似多边形轮廓
- 复制图像;
- 设置原始轮廓的边界点与逼近多边形边界之间的最大距离为轮廓的0.1 倍;
- 绘制多边形;
- 在图像上绘制轮廓,颜色为红色,线宽为2并展示;
代码实现
#epsilon=0.1*周长
adp = o.copy()# 复制图像
#原始轮廓的边界点与逼近多边形边界之间的最大距离为轮廓的0.1 倍
epsilon = 0.1*cv2.arcLength(contours[0],True)
#绘制多边形
approx = cv2.approxPolyDP(contours[0],epsilon,True)
# 在图像上绘制轮廓,颜色为红色,线宽为2
adp=cv2.drawContours(adp,[approx],0,(0,0,255),2)
cv2.imshow("result0.1",adp)
步骤四:绘制精度为0.05倍周长的近似多边形轮廓
- 复制图像;
- 设置原始轮廓的边界点与逼近多边形边界之间的最大距离为轮廓的0.05倍;
- 绘制多边形;
- 在图像上绘制轮廓,颜色为红色,线宽为2并展示;
代码实现
#epsilon=0.05*周长
adp = o.copy()
epsilon = 0.05*cv2.arcLength(contours[0],True)
approx = cv2.approxPolyDP(contours[0],epsilon,True)
adp=cv2.drawContours(adp,[approx],0,(0,0,255),2)
cv2.imshow("result0.05",adp)
步骤五:绘制精度为0.02倍周长的近似多边形轮廓
- 复制图像;
- 设置原始轮廓的边界点与逼近多边形边界之间的最大距离为轮廓的0.02倍;
- 绘制多边形;
- 在图像上绘制轮廓,颜色为红色,线宽为2并展示;
- 等待释放窗口。
代码实现
#epsilon=0.02*周长
adp = o.copy()
epsilon = 0.02*cv2.arcLength(contours[0],True)
approx = cv2.approxPolyDP(contours[0],epsilon,True)
adp=cv2.drawContours(adp,[approx],0,(0,0,255),2)
cv2.imshow("result0.02",adp)
#等待释放窗口
cv2.waitKey()
cv2.destroyAllWindows()
使用近似多边形的方法cv2.approxPolyDP()来获得图像的近似轮廓的过程中,可以通过控制参数epsilon来选取合适的近似多边形,方便后续的图像处理操作。
点击下载源码