轮廓检测方法
cv2.cvtColor() 函数完成图像颜色空间转换
cv2.cvtColor(src, code)
- src:输入图像
- code: 颜色空间代码,例如cv2.COLOR_BGR2GRAY
cv2.threshold()函数实现阈值处理
ret, dst = cv2.threshold(img, threshold, maxval, type)
- ret:返回的阈值
- dst:输出图像
- img:输入图像
- threshold:设定的阈值
- maxval:最大值
- type:阈值分割类型
cv2.THRESH_BINARY | 超过threshold部分设置为maxval,其余清0 |
cv2.THRESH_BINARY_INV | 取反,超过threshold部分设置为0,其余设置为maxval |
cv2.THRESH_TRUNC | 超过阈值的部分均设置与阈值相同,其余不变 |
cv2.THRESH_TOZERO | 超过阈值部分不变,其余清0 |
cv2.THRESH_TOZERO_INV | 超过阈值部分清0,其余不变 |
type 类型
cv2.findContours()函数用来查找检测物体的轮廓
binary,contours, hierarchy = cv2.findContours(image,mode,method)
- binary:二值图像结果
- contours:轮廓数据,向量内每个元素保存一组由连续的Point点构成的点的集合的向量 ,每一组Point点集合就是一个轮廓。有多少轮廓contours就有多少元素
- hierarchy:层级结构,向量内每一个元素包含了4个int型变量:[后一个轮廓,前一个轮廓,父轮廓,内嵌轮廓]
- image:输入图像
- mode:轮廓的模式
- method :轮廓逼近方法
mode类型
cv2.RETR_EXTERNAL | 只检索最外侧轮廓 |
cv2.RETR_LIST | 检索所有外侧轮廓并保存在一条链表里 |
cv2.RETR_CCOMP | 检索所有轮廓,顶层为外部边界次层为空洞边界 |
cv2.RETR_TREE | 检索所有轮廓并重构嵌套轮廓层次 |
method类型
cv2.CHAIN_APPROX_NONE | 保留所有轮廓点,相邻两个点位置差不超过1个像素则会保留 |
cv2.CHAIN_APPROX_SIMPLE | 记录轮廓的每个点的水平和垂直的值,相邻两个点的差值如果不超过1则只保留一个点 |
cv2.drawContours()函数完成绘图
cv2.drawContours(image, contours, contourIdx, color, thickness, lineType, hierarchy, maxLevel, offset)
- image:绘制轮廓的目标图像,一个多通道或单通道图像,通常是彩色图像(BGR)
- contours:轮廓数据
- contourIdx: 指定要绘制的轮廓的索引。若是负值(例如-1),则绘制所有轮廓
- color:轮廓线条的颜色。对于彩色图像,使用 (B, G, R) 格式,例如(0,255,0)
- thickness: 轮廓线条的宽度。如果为负值(如 cv2.FILLED),则填充轮廓内部
- 剩余四个可选lineType,hierarchy,maxLevel,offset
使用二值图像以获取更高的准确率
img=cv2.imread('car.png')
gray=cv2.cvtColor(img.cv2.COLOR_BGR2GRAY)#RGB图像转为灰度图
ret,thresh=cv2.threshold(gray,127,255,cv2.THRESH_BINARY)#阈值处理
cv_show(thresh,'thresh')
binary,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)#获取轮廓
绘制轮廓
draw_img=img.copy()#由于绘图操作会改变img格式,使用copy的img可以避免图片被污染
res=cv2.drawContours(draw_img,contours,-1,(0,0,255),2)
cv_shouw(res,'res')
轮廓特征与近似
cv2.approxPolyDP()函数完成逼近多边形曲线
cv2.approxPolyDP(curve, epsilon, True)#True或者closed
- curve:输入的轮廓,一个Numpy数组包含轮廓上的点集
- epsilon:逼近精度,即两个轮廓之间最大的欧式距离,是一个浮点数,一般取周长的百分比
轮廓特征
cv2.contours()函数求得轮廓面积
cv2.arcLength() 函数求得轮廓周长
#直传contours[0]会报错
cnt=contours[0]
#面积
cv2.contourArea(cnt)
#周长
cv2.arcLength(cnt,True)#True表示闭合
cv2.boundingRect()函数完成使用最小矩形包裹找到的图形
retval=cv2.boundingRect( array) #x,y,w,h=cv2.boundingRect( array)
- array:灰度图的轮廓,cnt或者通过findContours 函数得到
- retval :表示返回矩形边界左上角顶点的坐标值及矩形边界的宽和高 , 也可以是4个返回值形式 x,y,w,h
cv2.minEnclosingCircle()函数完成最小圆形包围曲线轮廓
center, radius = cv2.minEnclosingCircle(points)
- points:输入轮廓数据,例如cnt
- center:圆形的圆心
- radius:圆形的半径
cv2.rectangle()函数完成图像上绘制矩形
cv2.rectangle(img, pt1, pt2, color, thickness)
- img:输入图像,一般是一个numpy数组
- pt1:矩形左上角的坐标,坐标以元组形式给出,例如 (x1, y1)
- pt2:矩形右下角的坐标,坐标以元组形式给出,例如 (x2, y2)
- color:矩形颜色, BGR数据,一个元组例如(255, 0, 0)
- thickness:矩形边框的厚度,若是-1将被填充
cv2.Circle()函数完成图像上绘制矩形
cv2.circle(img, center, radius, color, thickness)
- img:输入图像,数组形式
- center:圆的中心点坐标,以元组形式给出,例如 (x, y)#需要转化为int型数据
- radius:圆的半径,表示从圆心到圆上任意一点的距离#需要转换为int型数据
- color:圆的颜色,BGR颜色
- thickness: 圆的线条宽度。如果传递 -1,则圆将被填充。
轮廓近似求取
img=cv2.imread('contours2.png')
gray=cv2.cvtColor(img,cv2COLOR_BGR2GRAY)#颜色空间转换
ret, thresh = cv2.threshold(gray,127, 255, cv2.THRESH_BINARY)
binary,contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_
APPROX_NONE)#轮廓检测
cnt=contours[0]
draw_img=img.copy()
res=cv2.drawContours(draw_img, contours, -1, (0,0,255), 2)#绘制轮廓
cv_show(res,'res')
绘制多边形曲线的轮廓
epsilon=0.1*cv2.arcLength(cnt)
approx=cv2.approxPolyDP(cnt, epsilon, True)#逼近多边形曲线轮廓的值
draw_img=img.copy()
res=cv2.drawContours(draw_img, [approx], -1, (0,0,255), 2)
cv_show(res,'res')
图像的目标矩形求取
img=cv2.imread('contours.png')
gray=cv2.cvtcolor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 155, cv2.THRESH_BINARY)
binary,contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_
APPROX_NONE)
cnt=contours[0]
x,y,w,h=boudingrect(cnt)
img=cv2.rectangle(thresh, (x,y), (x+w,y+h), (0,0,255), 2)
cv_show(img,'img')
求取外界矩形与轮廓面积比
area=cv2.counterArea(cnt)
x,y,w,h=boundingRect(cnt,True)
rect_area=w*h
extent=float(area)/rect_area
print(extent)
求外接圆
(x,y),radius= cv2.minEnclosingCircle(cnt)
center=(int(x),int(y))
radius=int(radius)
img=cv2.circle(img, center, radius, (0,0,255), -1)
cv_show(img,'img')