OpenCV中图像轮廓

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()

效果:

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_嘉木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值