opencv-轮廓检测

轮廓检测方法

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')
  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值