二值图像分析—轮廓发现

轮廓

轮廓即是以某种方式表示图像中的曲线的点的列表。这种表示可以根据实际的情形不同而不同。表示一条曲线的方式有很多种。OpenCV中,轮廓是由STL风格的vector<>模板对象表示的,其中vector中的每个元素都编码了曲线上的下一点的位置信息。

  • 轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法。所以边缘提取的阈值选定会影响最终轮廓发现结果
  • API介绍
    findContours 发现轮廓
    drawContours 绘制轮廓

在这里插入图片描述在这里插入图片描述

OpenCV中的轮廓发现

1. findContours
  • 说明
    用于查找二值图像中的轮廓。
    该函数使用算法@cite Suzuki85从二值图像中检索轮廓。轮廓是用于形状分析以及对象检测和识别的有用工具。

  • 声明

    void findContours(
    	    InputArray image, 
    	    OutputArrayOfArrays contours,
    	    OutputArray hierarchy, 
    	    int mode,
    	    int method, 
    	    Point offset = Point()
        );
    
    
    void findContours(
            InputArray image, 
            OutputArrayOfArrays contours,
            int mode, 
            int method, 
            Point offset = Point()
        );
    
  • 参数

    image原图像,一个8位的单通道图像。非零像素被认为为1,0像素为任然保留为0。所以图像被当做二值图像。您可以使用compare、inRange、threshold、adaptiveThreshold、Canny等来创建灰度或彩色的二值图像。如果mode等于RETR_CCOMP或RETR_FLOODFILL,则输入也可以是32位整数的标签图像(CV_32SC1)。
    contours检测到的轮廓。每个轮廓都存储为点向量(例如std :: vector <std :: vector >)。
    hierarchy可选的输出向量(例如std :: vector ),包含有关图像拓扑的信息。它具有与轮廓数量一样多的元素。对于每个第i个轮廓轮廓[i],元素等级[i] [0],等级[i] [1],等级[i] [2]和等级[i] [3]均设置为0-在相同的层次级别上,基于下一个和上一个轮廓的轮廓的索引,分别是第一个子轮廓和父轮廓。如果对于轮廓i,没有下一个,上一个,父级或嵌套的轮廓,则hierarchy [i]的相应元素将为负。
    mode轮廓检索模式,请参阅RetrievalModes。
    method轮廓近似方法,请参见ContourApproximationModes
    offset每个轮廓点移动的可选偏移量。如果从图像ROI中提取轮廓,然后在整个图像上下文中对其进行分析,这将非常有用。
    RetrievalModes 轮廓检索算法的模式

    ①:RETR_EXTERNAL
    仅检索极端的外部轮廓。它hierarchy[i][2]=hierarchy[i][3]=-1为所有轮廓设置。只检测最外围的轮廓,包含在外围轮廓内的内围轮廓被忽略。
    ②:RETR_LIST
    检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓。
    ③:RETR_CCOMP
    检索所有轮廓并将其组织为两级层次结构。在顶层,组件具有外部边界。在第二层,有孔的边界。如果所连接零部件的孔内还有其他轮廓,则该轮廓仍将放置在顶层。
    ④:RETR_TREE
    检索所有轮廓,并重建嵌套轮廓的完整层次。所有轮廓建立一个等级树结构,外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。

    ContourApproximationModes轮廓的近似方法

    ①:CHAIN_APPROX_NONE
    绝对存储所有轮廓点。也就是说,轮廓的任意两个后续点(x1,y1)和(x2,y2)将是水平,垂直或对角线邻居,即相邻的两个点的像素位置差不超过1,即max (abs (x1 - x2), abs(y2 - y1) =1
    ②:CHAIN_APPROX_SIMPLE
    压缩水平,垂直和对角线段,仅保留其端点。例如,例如一个矩形轮廓只需4个点来保存轮廓信息。
    ③:CHAIN_APPROX_TC89_L1
    使用teh-Chinl chain 近似算法
    ④:CHAIN_APPROX_TC89_KCOS
    应用teh-Chinl chain 近似算法

2. drawContours
  • 说明
    绘制轮廓或者填充轮廓。
  • 声明
    void drawContours( 
           InputOutputArray image,
           InputArrayOfArrays contours,
           int contourIdx, 
           const Scalar& color,
           int thickness = 1, 
           int lineType = LINE_8,
           InputArray hierarchy = noArray(),
           int maxLevel = INT_MAX, 
           Point offset = Point() 
     );
    
  • 参数
    image目标图片
    contours所有输入轮廓,每个轮廓都存储为点向量。
    contourIdx指示要绘制轮廓的参数。若为负,则绘制所有轮廓。
    color轮廓的颜色。
    hickness绘制轮廓的线的粗细。如果为负数,则绘制轮廓内部。
    lineType表示线型。
    hierarchy表示有关层次结构的可选信息。
    maxLevel表示绘制轮廓的最大级别。 如果为0,则仅绘制指定的轮廓。 如果为1,则该函数绘制轮廓和所有嵌套轮廓。 如果为2,则该函数绘制轮廓,所有嵌套轮廓,所有嵌套到嵌套的轮廓,等等。 仅当有可用的层次结构时才考虑此参数。
    offset表示可选的轮廓偏移参数,该参数可按指定的方式移动所有绘制的轮廓。

在这里插入图片描述

在这里插入图片描述

举例应用

步骤:
①:输入图像转为灰度图像cvtColor
②:使用Canny进行边缘提取,得到二值图像
③:使用findContours寻找轮廓
④:使用drawContours绘制轮廓

void findBinaryImgContours(Mat& src) {
	Mat dst, gray, binary;
	GaussianBlur(src, dst, Size(3, 3), 0);
	cvtColor(dst, gray, COLOR_BGR2GRAY);
	//图像值化
	threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
	imshow("src", src);
	imshow("dst", dst);
	imshow("gray", gray);
	imshow("binary", binary);


	//查找轮廓,每个轮廓都存储为点向量
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	//findContours(binary, contours, hierarchy,RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
    //findContours(binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());

	findContours(binary, contours, hierarchy, RETR_LIST, CHAIN_APPROX_NONE, Point());
	//findContours(binary, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE, Point());



	//画出每一个连通区域的轮廓
	for (int i = 0; i < contours.size(); i++)
	{
		//当thickness为正数的时候表示绘制该轮廓 当thickness为 - 1表示填充该轮廓
		drawContours(src, contours, i, Scalar(255,0, 255),-1);
	}
	imshow("contours", src);


}
int main() {
	Mat src = imread("D:/test/dan.png");
	findBinaryImgContours(src);

	waitKey(0);
	return 0;
}

  • RETR_TREE在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

  • RETR_EXTERNA
    在这里插入图片描述

  • RETR_CCOMP
    在这里插入图片描述

  • RETR_LIST
    在这里插入图片描述

  • 当thickness为正数的时候表示绘制该轮廓 当thickness为 - 1表示填充该轮廓
    在这里插入图片描述

学习:

  1. OpenCV-图像处理(28、轮廓发现(find contour in your image))

  2. OpenCV之二值图像分析 – 轮廓发现

  3. Python+OpenCV图像处理(十六)—— 轮廓发现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值