OpenCV入门笔记(六) 轮廓检测(Detect Contours)

轮廓(Contours),指的是有相同颜色或者密度,连接所有连续点的一条曲线。检测轮廓的工作对形状分析和物体检测与识别都非常有用。

在轮廓检测之前,首先要对图片进行二值化或者Canny边缘检测。在OpenCV中,寻找的物体是白色的,而背景必须是黑色的,因此图片预处理时必须保证这一点。


cv2.findContours函数

Python版示例如下,也可以参考【OpenCV-Python教程(11、轮廓检测)】【Contours : Getting Started

contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

完整例子:

import cv2

#读入图片
img = cv2.imread("1.png")

# 必须先转化成灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 二值化
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINAEY)

# 寻找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 画出轮廓,-1,表示所有轮廓,画笔颜色为(0, 255, 0),即Green,粗细为3
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)

# 显示图片
cv2.namedWindow("Contours", cv2.NORMAL_WINDOW)
cv2.imshow("Contours", img)

# 等待键盘输入
cv2.waitKey(0)
cv2.destroyAllWindows()


这里的findContours函数,有三个参数

  • thresh -> 要寻找轮廓的图片,注意这里的轮廓会直接改变在thresh上,记得备份
  • cv2.RETR_TREE -> 表示轮廓检索模式(Contour retrieval mode)为,检索所有的轮廓,且重组为一个有层次的嵌套轮廓。层次信息返回在hierarchy中。
  • cv2.CHAIN_APPROX_SIMPLE -> 表示轮廓近似方法(Contour approximation method)。SIMPLE可以这样理解,假如一个矩形有1000个点,但是现在只用四个角的点表示就行了,即去掉冗余信息。


返回值也有两个,contourshierarchy

对contours的理解如下

print "找到 %d 个轮廓" %(len(contours))
print "第 0 个轮廓有 %d 个点" %(len(contours[0]))

# 画出第0个轮廓
cv2.drawContours(img, contours, 0, (0, 255, 0), 3)
cv2.imshow("first contours", img)

# 画出第1个轮廓
cv2.drawContours(img, contours, 1, (0, 255, 0), 3)
cv2.imshow("second contours", img)

# 画出所有的轮廓
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)
cv2.imshow("all contours", img)

对 hierarchy 的深究,可以参考这里:【Contours Hierarchy


轮廓特征(Contour Features)

查找到轮廓以后,我们可以得出轮廓的一些特征信息,也可以在轮廓上做一些简单的操作,参考Python教程:【Contour Features

1. 面积和周长示例

# 寻找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 取第 0 个轮廓
cnt = contours[0]

# 轮廓面积
area = cv2.contourArea(cnt)

# 周长,或者说,弧长;第二个参数的True表示该轮廓是否封闭
perimeter = cv2.arcLength(cnt, True)


2. 轮廓近似

轮廓近似(Contour Approximation),要理解概念,先来看下面的三张图。第一张是找到的轮廓;第二张近似的幅度很大,忽略了很多的细节;第三细节多一点.



OpenCV中是用 cv2.approxPolyDP()函数来进行轮廓的近似的。见代码:

# 假设取第30个轮廓为例
cnt = contours[30]

# 10%,即0.1的精确度
epsilon = 0.1 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)

# 这里是第二张,10%的精确度
cv2.imshow("10% approximation", approx)

同理,第三张可以用1%的精确度来得到。



3. 计算凸包

涉及凸多面体和凹多面体的概念,不多解释。如下图,本来是一个手掌的形状,现在用最小的凸多面体把它包起来。其中,凸进去(Bulge Inside)的部分,称为凸包缺陷(Convexity Defects),即箭头处,即偏导的局部最大值处。

函数调用,以后用到再来细究吧!

hull = cv2.convexHull(cnt)
cv2.imshow("hull", hull)


4. 矩形边框

矩形边框(Bounding Rectangle)是说,用一个最小的矩形,把找到的形状包起来。还有一个带旋转的矩形,面积会更小,效果见下图

上代码

# 用绿色(0, 255, 0)来画出最小的矩形框架
x, y, w, h = cv2.boundingRect(cnt)
img = cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)

# 用红色表示有旋转角度的矩形框架
rect = cv2.minAreaRect(cnt)
box = cv2.cv.boxPoints(rect)
box = np.int0(box)
img = cv2.drawContours(img, [box], 0, (0, 0, 255), 2)


PS其他的形状,如 封闭的圆形椭圆直线 等,例子见这里【Contour Features】,原理差不多,不再赘述。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-31 01:38:23

OpenCV入门笔记(六) 轮廓检测(Detect Contours)的相关文章

OpenCV入门笔记(六) 形态学变换

形态学变换(Morphological Transformations),其实是数学上的一个分支,是基于形状的一些列图像处理操作.OpenCV提供了很多方便而有用的操作函数. 一.腐蚀和膨胀(erosion & dilation) 腐蚀(erosion)和膨胀(dilation)是形态学中两个最基本的操作.他们结合后又会衍生出其他很多种复杂的过程.其基本思想很简单,就是用一个核函数,扫过原图像,用覆盖的区域中最值代替锚点(锚点即核函数当前的中心点,即扫描的中心点).下面是苏东坡<水调歌头·明

【opencv入门】角点检测之Harris角点检测

一.引言:关于兴趣点(interest points) 在图像处理和与计算机视觉领域,兴趣点(interest points),或称作关键点(keypoints).特征点(feature points) 被大量用于解决物体识别,图像识别.图像匹配.视觉跟踪.三维重建等一系列的问题.我们不再观察整幅图,而是选择某些特殊的点,然后对他们进行局部有的放矢的分析.如果能检测到足够多的这种点,同时他们的区分度很高,并且可以精确定位稳定的特征,那么这个方法就有使用价值. 图像特征类型可以被分为如下三种: <

33、【opencv入门】角点检测之Harris角点检测

一.引言:关于兴趣点(interest points) 在图像处理和与计算机视觉领域,兴趣点(interest points),或称作关键点(keypoints).特征点(feature points) 被大量用于解决物体识别,图像识别.图像匹配.视觉跟踪.三维重建等一系列的问题.我们不再观察整幅图,而是选择某些特殊的点,然后对他们进行局部有的放矢的分析.如果能检测到足够多的这种点,同时他们的区分度很高,并且可以精确定位稳定的特征,那么这个方法就有使用价值. 图像特征类型可以被分为如下三种: <

OpenCV入门笔记(二) 图片的文件操作

以下介绍一下重要的几个,设计基本 图片处理 的函数,依次来了解OpenCV的入门知识.具体的具体使用方法还是以官方的API[Official Tutorials][Python-OpenCV]为准. imread 图片读取函数.使用方法例如以下 # read image with color img = cv2.imread("./lena.jpg") # OR read gray image imgGray = cv2.imread("./lena.jpg", 0

OpenCV入门:(六:基础画图函数)

有时程序中需要画一些基础的图形,例如直线,矩形,椭圆以及多边形.OpenCV中当然有此类函数. 1.函数介绍 直线line: void line(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0) img – 图像 pt1 – 直线起点 pt2 – 直线终点 color – 颜色 thickness – 粗细 lineType – 直线类型,可以

opencv学习笔记霍夫变换——直线检测

参考大佬博文:blog.csdn.net/jia20003/article/details/7724530 lps-683.iteye.com/blog/2254368 openCV里有两个函数(比较常用)处理霍夫变换直线检测,有什么区别呢. CvHoughLine:是用于标准的霍夫变换方法 CvHoughLine2:可以使用三种霍夫变换的方法,分别是标准霍夫变换(SHT).多尺度标准霍夫变换(MSHT).累计概率霍夫变换(PPHT). 函数原型: CvSeq* cvHoughLines2( C

OpenCV入门笔记(五) 边缘检测

这里介绍三种边缘检测的方法, Sobel算子(索贝尔算子), Laplacian算子(拉普拉斯算子) 和 Canny算子 的边缘检测. 一.Sobel算子 Sobel算子在一阶偏导上检测边缘,且能在水平(x 方向)和竖直(y 方向)分别作用.直观上,Sobel寻找这样的边缘:中间灰度值特别大,两边很小,即像素值出现跳跃的现象.我们可以通过求梯度值来确定. x 和 y 两个方向的核函数如下: ????1?2?1000+1+2+1???(Gx) ???+10?1+20?2+10?1???(Gy) 若

OpenCV入门笔记(四) 形态学变换

形态学变换(Morphological Transformations),其实是数学上的一个分支,是基于形状的一系列图像处理操作.OpenCV提供了很多方便而有用的操作函数. 一.腐蚀和膨胀(erosion & dilation) 腐蚀和膨胀 是形态学中两个最基本的操作.他们结合后又会衍生出其他很多种复杂的过程.其基本思想很简单,就是用一个 核函数,扫过原图像,用覆盖的区域中最值代替锚点(核函数当前的中心点,即扫描的中心点).下面是苏东坡<水调歌头·明月几时有>的楷体图片,我们来看看腐

OpenCV入门笔记(一) Linux下的安装

关于OpenCV,有中文的官方网站,里面翻译了官网的教程和API等.中文官方Tutorials见这里:[Tutorials] 一.Ubuntu下的安装 可以选择直接从库里安装,或者手动编译安装,请参考这里:[Installation in Linux] 1. 从repository(库)中安装 sudo apt-get install libopencv-dev python-opencv 2. 手动编译安装 首先要解决OpenCV的依赖问题,直接在终端下执行 sudo apt-get inst