OpenCV笔记(二十七)轮廓发现

文章目录

  • 一、阈值发现
  • 二、相关API
    • 1. findContours
    • 2.drawContours
  • 三、处理步骤
  • 四、综合例程

一、阈值发现

find contour

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

二、相关API

1. findContours

轮廓发现

InputOutputArray  binImg, // 输入图像,非0的像素被看成1,0的像素值保持不变,8-bit
 OutputArrayOfArrays  contours,//  全部发现的轮廓对象
OutputArray,  hierachy /*图该的拓扑结构,可选,该轮廓发现算法正是基于图像拓扑结构实现。 
						一个向量,其内每个元素保存了一个包含4个int整型的数组。hiararchy内的元素						  和轮廓向量contours内的元素是一一对应的。hierarchy向量内每一个元素的4个						  int型变量——hierarchy[i][0] ~hierarchy[i][3],分别表示第i个轮廓的后                         一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果当前轮廓没有对应的后                         一个轮廓、前一个轮廓、父轮廓或内嵌轮廓的话,则hierarchy[i][0] 							~hierarchy[i][3]的相应位被设置为默认值-1。*/
int mode, /*轮廓返回的模式
		  取值一:CV_RETR_EXTERNAL 只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略
		  取值二:CV_RETR_LIST 检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建			      			 立等级关系,彼此之间独立,没有等级关系.
		  取值三:CV_RETR_CCOMP  检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外				围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层
 		  取值四:CV_RETR_TREE, 检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮             		   廓,内层轮廓还可以继续包含内嵌轮廓。*/
int method,/*发现方法
			取值一:CV_CHAIN_APPROX_NONE 保存物体边界上所有连续的轮廓点到contours向量内
			取值二:CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入					  contours向量内,拐点与拐点之间直线段上的信息点不予保留
			取值三和四:CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl 					chain近似算法*/
Point offset=Point()//  轮廓像素的位移,默认(0, 0)没有位移
)

2.drawContours

轮廓绘制

在二值图像上发现轮廓使用API cv::findContours之后对发现的轮廓数据进行绘制显示

drawContours(
InputOutputArray  binImg, // 输出图像
 OutputArrayOfArrays  contours,//  全部发现的轮廓对象
Int contourIdx// 轮廓索引号
const Scalar & color,// 绘制时候颜色
int  thickness,// 绘制线宽
int  lineType ,// 线的类型LINE_8
InputArray hierarchy,// 拓扑结构图
int maxlevel,// 最大层数, 0只绘制当前的,1表示绘制绘制当前及其内嵌的轮廓
Point offset=Point()// 轮廓位移,可选

三、处理步骤

  1. 输入图像转为灰度图像cvtColor
  2. 使用Canny进行边缘提取,得到二值图像
  3. 使用findContours寻找轮廓
  4. 使用drawContours绘制轮廓

四、综合例程

#include 
#include 
#include 

using namespace std;
using namespace cv;

Mat src, dst;
const char* output_win = "findcontours-demo";
int threshold_value = 100;
int threshold_max = 255;
RNG rng;
void Demo_Contours(int, void*);
int main(int argc, char** argv) {
	src = imread("D:/vcprojects/images/happyfish.png");
	if (src.empty()) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input-image", CV_WINDOW_AUTOSIZE);
	namedWindow(output_win, CV_WINDOW_AUTOSIZE);
	imshow("input-image", src);
	cvtColor(src, src, CV_BGR2GRAY);

	const char* trackbar_title = "Threshold Value:";
	createTrackbar(trackbar_title, output_win, &threshold_value, threshold_max, Demo_Contours);
	Demo_Contours(0, 0);

	waitKey(0);
	return 0;
}

void Demo_Contours(int, void*) {
	Mat canny_output;
	vector> contours;
	vector hierachy;
	Canny(src, canny_output, threshold_value, threshold_value * 2, 3, false);
	findContours(canny_output, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));

	dst = 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(dst, contours, i, color, 2, 8, hierachy, 0, Point(0, 0));
	}
	imshow(output_win, dst);
}

你可能感兴趣的:(#,OpenCV图像处理)