Opencv图像轮廓

一、什么是轮廓

轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。
 

二、如何寻找轮廓

  • 为了更加准确,要使用二值化图像。在寻找轮廓之前,要进行阈值化处理或者 Canny 边界检测。
  •  查找轮廓的函数会修改原始图像。如果你在找到轮廓之后还想使用原始图像的话,你应该将原始图像存储到其他变量中。
  • 在 OpenCV 中,查找轮廓就像在黑色背景中超白色物体。你应该记住,要找的物体应该是白色而背景应该是黑色

findContour函数简介

虽然然canny之类的边缘检测算法可以根据像素间的差异检测出轮廓边界的像素,但是它并没有将轮廓作为一个整体。下一步是要把这些像素组装成轮廓,这个函数就是findcontours()

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

  contours:为获取的轮廓信息,轮廓信息定义务必是vector<vector<Point>> 形式的

  hierarchy:为层级关系,定义为vector<Vec4i>和Mat都可以。每个轮廓有四个层级信息,分别为:上一个轮廓序号、下一个轮廓序号、子轮廓序号、父轮廓序号

  mode :官方是“轮廓检索算法的模式”,可以理解为获取怎样的层级信息

  method:定义轮廓的近似方法

  offset:偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,并且Point还可以是负值

 

三、绘制轮廓

drawContours

主要流程

1、加载源图像

2、转成灰度图并模糊化降噪

3、用Canny算子检测边缘,得到二值图像

4、使用findContours寻找轮廓

5、使用drawContours绘出轮廓图

 

例子

#include <iostream>
#include <vector>    
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;
using std::vector;   

int main()
{
	cv::Mat srcImage;  //原始图像

	srcImage = cv::imread("F:\\4.jpg");
	if (!srcImage.data)
	{
		std::cout << "read image error!" << std::endl;
		return -1;
	}
	cv::imshow("srcImage", srcImage);

	//1.灰度转换
	cv::Mat gray;
	cv::cvtColor(srcImage, gray, CV_RGB2GRAY);
	cv::imshow("gray", gray);

	//2.二值化
	cv::Mat binary;
	cv::threshold(gray, binary, 150, 255, cv::THRESH_BINARY_INV);  //65.255(会导致出错,这里要选择合适的阈值)  220.255
	cv::imshow("binary", binary);

	//3.定义轮廓和层次机构
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;


	//4.轮廓查找
	cv::findContours(binary, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);


	int index = 0;
	for (; index >= 0; index = hierarchy[index][0])
	{

		//cv::Scalar color(rand()&255, rand()&255, rand()&255);
		//5.轮廓绘制
		//cv::drawContours(binary, contours, index, cv::Scalar(255), 2,8,hierarchy,0,Point());
		//cv::drawContours(binary, contours, -1, cv::Scalar(255));  //法1
		cv::Mat dst(srcImage.size(),CV_8U,cv::Scalar(0));   //法2
		cv::drawContours(dst,contours,index,cv::Scalar(255),CV_FILLED);   //法3

	}

	cv::drawContours(binary, contours, -1, cv::Scalar(255));

	waitKey(0);
	return 0;
}

参考:

https://blog.csdn.net/juliarjuliar/article/details/84030500

https://blog.csdn.net/laobai1015/article/details/76400725

https://www.cnblogs.com/peimingzhang/p/13110480.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值