轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。
findContour函数简介
虽然然canny之类的边缘检测算法可以根据像素间的差异检测出轮廓边界的像素,但是它并没有将轮廓作为一个整体。下一步是要把这些像素组装成轮廓,这个函数就是findcontours()
void findContours( InputArray image, OutputArrayOfArrays contours,
OutputArray hierarchy, int mode,
int method, Point offset = Point());
contours:为获取的轮廓信息,轮廓信息定义务必是vector
hierarchy:为层级关系,定义为vector
mode :官方是“轮廓检索算法的模式”,可以理解为获取怎样的层级信息
method:定义轮廓的近似方法
offset:偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,并且Point还可以是负值
drawContours
主要流程
1、加载源图像
2、转成灰度图并模糊化降噪
3、用Canny算子检测边缘,得到二值图像
4、使用findContours寻找轮廓
5、使用drawContours绘出轮廓图
例子
#include
#include
#include
#include
#include
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> contours;
vector 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