opencv--轮廓绘制

在这里插入图片描述

轮廓发现

  • 定义
    在这里插入图片描述
  • API
CV_EXPORTS_W void findContours( InputOutputArray image,
                                OutputArrayOfArrays contours,
                                OutputArray hierarchy, 
                                int mode,
                                int method, 
                                Point offset = Point()
                                );
  • 参数说明
    在这里插入图片描述
  1. 8比特单通道的源二值图像。非零像素作为1处理,0像素保存不变。从一个灰度图像得到二值图像的函数有:cvThreshold,cvAdaptiveThreshold和cvCanny。

    如果第四个参数为cv::RETR_CCOMP或cv::RETR_FLOODFILL,输入图像可以是32-bit整型图像(CV_32SC1)

  2. contours:检测到的轮廓,每个轮廓都是以点向量的形式进行存储即使用point类型的vector表示

  3. hierarchy:可选的输出向量(std::vector),包含了图像的拓扑信息,作为轮廓数量的表示hierarchy包含了很多元素,每个轮廓contours[i]对应hierarchy中hierarchy[i][0]~hierarchy[i][3],分别表示后一个轮廓,前一个轮廓,父轮廓,内嵌轮廓的索引,如果没有对应项,则相应的hierarchy[i]设置为负数。

  4. mode轮廓检索模式,可以通过cv::RetrievalModes()查看详细信息

    mode 说明
    RETR_EXTERNAL 表示只检测最外层轮廓,意思是图像中独立的个体只检测最外层轮廓,包含在里面的轮廓不会提取出来。在这里插入图片描述
    RETR_LIST 提取所有轮廓,并放置在list中,不建立等级关系。意思就是提取出来的轮廓之间是没有联系的。在这里插入图片描述
    RETR_CCOMP 提取所有轮廓,并且将其组织为双边结构。意思就是第一层为它的外围轮廓,第二层为内围轮廓,利用这个参数可以筛选出来一个独立边缘只对应一个轮廓在这里插入图片描述
    RETR_TREE 提取所有轮廓,并且重新建立网状轮廓结构。它体现出来的轮廓联系很紧密,比如说一个轮廓在另外一个轮廓的里面,轮廓里面又包含轮廓。
  5. 边缘近似方法(除了CV_RETR_RUNS使用内置的近似,其他模式均使用此设定的近似算法)。可以通过cv::ContourApproximationModes()查看详细信息 .

    method 说明
    CV_CHAIN_CODE 以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)
    CV_CHAIN_APPROX_NONE 获取每个轮廓的每个像素,相邻的两个点的像素位置差不超过1
    CV_CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素,值保留该方向的重点坐标,如果一个矩形轮廓只需4个点来保存轮廓信息
    CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS 使用the flavors of Teh-Chinchain近似算法的一种。
    CV_LINK_RUNS 通过连接水平段的1,使用完全不同的边缘提取算法。使用 CV_RETR_LIST检索模式能使用此方法
  6. 偏移量,用于移动所有轮廓点。当轮廓是从图像的ROI提取的,并且需要在整个图像中分析时,这个参数将很有用。


轮廓绘制

  • 定义
CV_EXPORTS_W 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() );
  • 参数
    在这里插入图片描述
    1. image:输入需要最终输出的图像,Mat类型即可
    2. contours:使用findContours检测到的轮廓数据,每个轮廓以点向量的形式存储,point类型的vector
    3. contourIdx:绘制轮廓的只是变量,如果为负值则绘制所有输入轮廓
    4. color:轮廓颜色
    5. thickness:绘制轮廓所用线条粗细度,如果值为负值,则在轮廓内部绘制
    6. lineTpye:线条类型,有默认值LINE_8。
    7. hierarchy: 关于层级的可选参数,只有绘制部分轮廓时才会用到
    8. maxLevel: 用于绘制轮廓的最大等级 .画轮廓的最大层数。
      如果是0,只绘制contour;
      如果是1,将绘制contour后和contour同层的所有轮廓;
      如果是2,绘制contour后所有同层和低一层的轮廓,
      以此类推;如果值是负值,则函数并不绘制contour后的轮廓,但是将画出其子轮廓,一直到abs(max_level) - 1层。
    9. offset: 可选轮廓便宜参数,用制定偏移量offset=(dx, dy)给出绘制轮廓的偏移量

代码演示

在这里插入图片描述

Mat src, dst1,dst2,dst3;
char winName[] = "contour_dst3";
int track_size = 10;
int max_size = 100;

void onContour(int, void*) {
	Canny(dst1, dst2, track_size, track_size * 2);
	vector<vector<Point>>contours;
	vector<Vec4i>hierachy;
	//寻找轮廓
	findContours(dst2, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
	dst3 = Mat::zeros(src.size(), CV_8UC3);
	RNG rng(12345);
	for (size_t i = 0; i < contours.size(); i++)
	{
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		drawContours(dst3, contours, i, color, 2, 8, hierachy, 0, Point(0, 0));
	}
	imshow(winName, dst3);
}
int main() {
	src = imread("D:\\fish.png");
	imshow("src", src);
	cvtColor(src, dst1, CV_BGR2GRAY);
	imshow("dst1",dst1);

	onContour(0, 0);
	createTrackbar("trackbar_step", winName, &track_size, max_size, onContour);
	//onContour(0, 0);

	waitKey(0);
	return 0;

}

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

分享好文章:
【OpenCV3】图像轮廓查找与绘制——cv::findContours()与cv::drawContours()详解
https://blog.csdn.net/guduruyu/article/details/69220296

猜你喜欢

转载自blog.csdn.net/qq_41498261/article/details/84065381