说明:
第一个参数:输入的图像是经过边缘提取处理后的二值化图像;conturs向量是用来存储轮廓点的,可以这样理解:一个轮廓的所有点用一个小容器vector,所有小容器再用一个大容器vector装起来,所以像下面这样定义第二个参数:vector<vector<Point>> contours;,相当于是一个二维向量吧,如下: 第三个参数是轮廓的索引值;第四个参数:轮廓检索模式,有四种,如下:第一种:cv::RETR_EXTERNAL(仅检索最外层的轮廓) 第二种:cv::RETR_LIST(检索所有轮廓并将它们放入列表中)
第三种:cv::RETR_CCOMP(检索所有轮廓,将它们组织为两级层次结构,其中顶层边界是组件的外部边界,第二级边界是孔的边界) 第四种:cv::RETR_CCOMP(检索所有轮廓并建立树形的嵌套层次结构)
5.第六个参数是轮廓逼近算法,有以下四种:
CHAIN_APPROX_NONE CHAIN_APPROX_SIMPLE CHAIN_APPROX_TC89_L1 CHAIN_APPROX_TC89_KCOS1.图像灰度化处理 2.滤波去噪 3.二值化 4.形态学操作 5.寻找轮廓 6.绘制轮廓
主函数:
int main() { img = imread("E:/coin.jpg"); cvtColor(img, img_gray, CV_BGR2GRAY);//图像灰度化 medianBlur(img_gray, img_gray, 3);//进行中值滤波,去除一些噪声点 createTrackbar("Threshold", str_OutputWindowTitle, &threshold_value, threshold_max, Find_Contours); Find_Contours(0, 0); waitKey(0); return 0; }寻找轮廓函数:
void Find_Contours(int, void*) { //二值化 threshold(img_gray, img_bin, threshold_value, threshold_max, THRESH_BINARY); //根据实际二值化的效果进行相应的形态学操作 Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); morphologyEx(img_bin, img_bin, MORPH_CLOSE, element);//闭操作 imshow("bin+morphologyEx", img_bin); //轮廓发现,轮廓绘制 vector<vector<Point>> contours;//双层,意思是有很多个轮廓,每个轮廓有很多个点 vector<Vec4i> hierachy;//4个元素分别存储该轮廓的【后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓】的索引编号 findContours(img_bin, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); dst = Mat::zeros(img.size(), CV_8UC3);//新建一个图像用来绘制寻找到的轮廓 //绘制所有轮廓像素点 for (auto 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, 1, 8, hierachy, 0, Point(0, 0));//重新绘制轮廓 } imshow(str_OutputWindowTitle, dst); }适当调整阈值使其达到最好的效果: 根据提取到的轮廓点绘制找到的轮廓:
是一个计算几何(图形学)中的概念,凸包是一个过某些点作一个多边形,使这个多边形能把所有点都“包”起来。当这个多边形是凸多边形的时候,我们就叫它“凸包”。
举个形象的栗子:木板上定了十几个钉子,把一根橡皮筋撑大,套住所有钉子,然后让橡皮筋自然收缩,并繃紧,则橡皮筋形成的闭曲线就是凸包。
更多关于“凸包”的理论知识参考下面的几篇文章:
1.什么是“凸包”
2.凸包问题——概述
3.数学:凸包算法详解
1.寻找轮廓 2.发现凸包 3.绘制凸包
第一组:
对照组1:
对照组2:
API功能:使用多边形简化轮廓;
注:epsilon参数的意义是,这是原始多边形和最终近似多边形之间允许的最大偏差,取值越大得到的多边形越简单。
为了验证一下,取下图其中的一个轮廓做测试,直接执行findContours之后,该轮廓的总点数为85,如下图: 当执行approxPolyDP()之后,epsilon值取3的时候,简化后的轮廓有9个点,绘制出来的多边形是9个边,如下图: epsilon值取7的时候,简化后的轮廓有6个点,绘制出来的多边形是6个边,如下图:
API功能:获取简化后多边形轮廓的外接矩形;
API功能:获取简化后多边形轮廓外接圆的“圆心坐标”和“半径”,注意数据类型;
API功能:获取简化后多边形轮廓的“最适合”椭圆;
1.灰度化、滤波 2.二值化、相关形态学操作 3.寻找轮廓 4.轮廓简化 5.依次获取轮廓外接矩形、外接圆、最小矩形、最小椭圆; 6.绘制需要的形状
参考文章: 1.https://blog.csdn.net/weixin_41695564/article/details/80085012 2.https://blog.csdn.net/qq_26907755/article/details/81740206 3.https://www.cnblogs.com/little-monkey/p/7429381.html
