轮廓检测
1、轮廓检测
findContours()函数
输入参数:
- 要处理的图像。这个函数会修改原来的图像,建议copy一下,img.copy()
- 层次类型。cv2.RETR_TREE会得到图像中轮廓的整体层次结构,cv2.RETR_EXTERNAL只得到图像最外面的轮廓
- 轮廓逼近的方法。常用cv2.CHAIN_APPROX_SIMPLE
返回值:
- 修改后的图像
- 图像的轮廓
- 轮廓的层次
2、边界框、最小矩形区域。最小闭圆的轮廓
轮廓的边界框:
x,y,w,h = cv2.boundingRect(contour)
最小矩形区域:
rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rect)
box =np.int0(box) # 计算出来的坐标是浮点型的,转换为整数
cv2.drawContours(img, [box], 0, (0,255,255), 3) # 第三个参数表示货值轮廓数组的索引,-1表示绘制所有的轮廓,否则只绘制指定索引的轮廓
最小闭合圆:
cv.minEnclosingCircle(contour) # 返回圆心坐标的元组 和 半径
代码如下:
import cv2
import numpy as np
img = cv2.imread("../images/05.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
image,contours,hie = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
max = 1
for i in contours:
if cv2.arcLength(i,True) > max:
c = i
max = cv2.arcLength(i,True)
# 找出边界框,蓝色画出
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# 找出最小面积的矩形,绿色画出
rect = cv2.minAreaRect(c)
# 算出最小面积的坐标
box = cv2.boxPoints(rect)
# 转换坐标值为整数
box = np.int0(box)
cv2.drawContours(img,[box],0,(0,255,0),2)
# 找出最小闭合圆,红色画出
(x,y),radias = cv2.minEnclosingCircle(c)
# 转换为整形
center = (int(x),int(y))
radias = int(radias)
cv2.circle(img,center,radias,(0,0,255),2)
# 黄色画出轮廓
cv2.drawContours(img,c,-1,(0,255,255),1)
cv2.imshow("bunding",img)
cv2.waitKey()
cv2.destroyAllWindows()
3、凸轮廓
approx = cv2.approxPolyDP() 可以绘制近似的多边形框,该函数有三个参数:
- 轮廓
- epsilon,表示元轮廓和近似多边形的最大差值(差值越小,近似多边形越接近轮廓)
- 布尔标记,表示该多边形是否闭合
其中epsilpn,可以用cv2.arcLength(contour,True) 来获取轮廓的周长,来定义
凸包:
可以用hull = cv2.convexHull(轮廓),来得到凸包的信息。
实例代码如下:
import cv2
import numpy as np
img = cv2.imread("../images/05.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
image,contours,hie = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
max = 1
for i in contours:
if cv2.arcLength(i,True) > max:
c = i
max = cv2.arcLength(i,True)
# 凸包,绿色
hull = cv2.convexHull(c)
# 画出多边形的方法 hull要用【】抱起来
cv2.drawContours(img,[hull],-1,(0,255,0),2)
# 多边形,红色
# epsilon是近似多边形和轮廓的最大差值
epsilon = 0.008 * cv2.arcLength(c,True)
approx = cv2.approxPolyDP(c,epsilon,True)
cv2.drawContours(img,[approx],-1,(0,0,255),2)
# 轮廓 黄色
cv2.drawContours(img,c,-1,(0,255,255),2)
cv2.imshow("bunding",img)
cv2.waitKey()
cv2.destroyAllWindows()