概述
1.图像轮廓
什么是图像轮廓?图像轮廓具有相同的颜色或灰度的连续点的曲线,轮廓在形状分析和物体检测和设别中很有用。为了检测的准确性,需要先对轮廓进行二值化或Canny操作画轮廓时候会改变输入图像。
查找轮廓
findContours(image,mode,method[.contours[,hierchy[,offest]]])
mode:查找轮廓的模式
RETR_EXTERNAL=0表示值检测外围轮廓
RETR_LIST=1检测的轮廓不建立等级关系,检测所有的轮廓
RETR_CCOMP=2每层最多两级,从小到大,从里到外
RETR_TREE=3按照树型存储轮廓,从大到小,从左到右method 轮廓近似方法、也叫作ApproximationMode
CHAIN_APPROX_NONE保存所有轮廓上的点
CHAIN_APPROX_SIMPLE只保存角点返回contours和hierarchy即轮廓和层级
绘制轮廓
drawContours(image,contours,contourldx,color[,thickness[,lineType[,hierarchy[,maxLeve[,offest]]]]])
image要绘制的轮廓图像
contours轮廓点
contourldx要绘制的轮廓的编号,-1表示绘制所有轮廓
color轮廓的颜色,如(0,0,255)表示红色
thickness线宽,-1表示全部填充
代码实现:
import cv2
import numpy as np
img = cv2.imread('./T_J.jpg')
#变成单通道的黑白图片
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#二值化
thresh,binary = cv2.threshold(img2,150,255,cv2.THRESH_BINARY)
#查找轮廓,新版本返回两个东西,分别是轮廓和层级
contours,hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#contours是list,里面放的是ndarray,每个ndarray表示一个contour
#绘制轮廓会直接修改原图
cv2.drawContours(img,contours,-1,(225,235,0),3)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果:
2.多边形逼近与凸包
多边形逼近与凸包
findContours后的轮廓信息contours可能过于复杂不平滑,可以用approxPolyDP对该多边形曲线做适当近似,这就是轮廓的多边形逼近
approxPolyDP采用的是Douglas-Peucker算法
其算法核心就是不到寻找多边形最远点加入形成新的多边形,直到最短距离小于指定距离的精度approxPolyDP(curve,epsilon,closed[,approxCurve])
curve:要近似逼近轮廓
epsilon:即DP算法使用的阈值 越小越好
closed:轮廓是否闭合
代码实现:
import cv2
import numpy as np
img = cv2.imread('./Bear.jpg')
#变成单通道的黑白图片
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#二值化
thresh,binary = cv2.threshold(img2,150,255,cv2.THRESH_BINARY)
img_copy=img.copy()
#查找轮廓,新版本返回两个东西,分别是轮廓和层级
contours,hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#contours是list,里面放的是ndarray,每个ndarray表示一个contour
print(len(contours))
#绘制轮廓会直接修改原图
cv2.drawContours(img,contours,-1,(0,255,255),5)
approx = cv2.approxPolyDP(contours[1],18,closed=True)
print(type(approx))
#画出近似逼近的轮廓
cv2.drawContours(img_copy,[approx],0,(0,255,255),5)
cv2.imshow('img',img_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果:
#凸包
convexHull(points[,hull[,clockwise[,returnPints]]])
points轮廓
clockwise顺时针绘制
代码实现:
#凸包
import cv2
import numpy as np
img = cv2.imread('./Bear.jpg')
#变成单通道的黑白图片
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#二值化
thresh,binary = cv2.threshold(img2,150,255,cv2.THRESH_BINARY)
img_copy=img.copy()
#查找轮廓,新版本返回两个东西,分别是轮廓和层级
contours,hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#contours是list,里面放的是ndarray,每个ndarray表示一个contour
print(len(contours))
#绘制轮廓会直接修改原图
cv2.drawContours(img_copy,contours,-1,(0,255,255),5)
approx = cv2.approxPolyDP(contours[1],18,closed=True)
print(type(approx))
#画出近似逼近的轮廓
cv2.drawContours(img_copy,[approx],0,(0,0,255),5)
#计算凸包
hull = cv2.convexHull(contours[1])
cv2.drawContours(img_copy,[hull],0,(255,0,0),5)
cv2.imshow('img',img_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果:
3.最大外接矩形与最小外接矩形
最小
minAreaRect(points)
points轮廓
返回元组,内容是一个旋转矩阵(RotatedRect)的参数;矩阵的起始坐标x,y,矩阵的宽和高,矩阵的选择角度最大
boundingRect(points)
代码实现:
最小:
import cv2
import numpy as np
img = cv2.imread('./Bear.jpg')
#变成单通道的黑白图片
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#二值化
thresh,binary = cv2.threshold(img2,150,255,cv2.THRESH_BINARY)
img_copy=img.copy()
#查找轮廓,新版本返回两个东西,分别是轮廓和层级
contours,hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#contours是list,里面放的是ndarray,每个ndarray表示一个contour
rect = cv2.minAreaRect(contours[1])
#用这个函数帮你计算出矩形的四个坐标点(必须是整数)
box = cv2.boxPoints(rect)
#舍去小数
box = np.int0(box)
#四舍五入
box = np.round(box).astype('int64')
#绘制矩形
cv2.drawContours(img_copy,[box],0,(0,0,255),5)
cv2.imshow('img',img_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果:
最大:
代码实现:
#最大
import cv2
import numpy as np
img = cv2.imread('./Bear.jpg')
#变成单通道的黑白图片
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#二值化
thresh,binary = cv2.threshold(img2,150,255,cv2.THRESH_BINARY)
img_copy=img.copy()
#查找轮廓,新版本返回两个东西,分别是轮廓和层级
contours,hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#contours是list,里面放的是ndarray,每个ndarray表示一个contour
rect = cv2.minAreaRect(contours[1])
#用这个函数帮你计算出矩形的四个坐标点(必须是整数)
box = cv2.boxPoints(rect)
#舍去小数
box = np.int0(box)
#四舍五入
box = np.round(box).astype('int64')
#绘制矩形
cv2.drawContours(img_copy,[box],0,(0,0,255),5)
#最大外接矩形 返回参数(x,y)(w,h)方方正正的
x,y,w,h=cv2.boundingRect(contours[1])
cv2.rectangle(img_copy,(x,y),(x + w,y + h),(0,255,0),5)#图片,起始点,结束点,颜色,线宽
cv2.imshow('img',img_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果:
最后
以上就是无情乌冬面为你收集整理的OpenCV中图像轮廓的全部内容,希望文章能够帮你解决OpenCV中图像轮廓所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复