技术支持网站,做百度网站需不需要备案,培训网站视频不能拖动怎么办,下载京东正版官网定义
给定二维平面上的点集#xff0c;凸包就是将最外层的点连接起来构成的凸多边型。 理解物体形状或轮廓的一 种比较有用的方法便是计算一个物体的凸包#xff0c;然后计算其凸缺陷(convexity defects)。
检测凸包
opencv自带函数#xff1a;convexHull()
参数解释凸包就是将最外层的点连接起来构成的凸多边型。 理解物体形状或轮廓的一 种比较有用的方法便是计算一个物体的凸包然后计算其凸缺陷(convexity defects)。
检测凸包
opencv自带函数convexHull()
参数解释
示例1检测随机点群的凸包只有一个凸包
代码以及注释
#include opencv2/opencv.hpp
#include iostream
#include windows.h
#include stdio.h
#include time.husing namespace cv;
using namespace std;//凸包检测基础
//先随机生成3~103个坐标值随机的彩色点然后利用convexHull对链接起来的图形求凸包
int main()
{Mat image(600, 600, CV_8UC3);//RNG rng theRNG(); //返回一个当前线程的随机数生成器 RNG类可以产生多种类型的随机数故使用时需要指定是哪种类型的RNG rng((unsigned)time(NULL)); //这样每次重新运行会产生不一样的随机数while (1){//参数初始化char key;int count (unsigned)rng % 100 3; //随机生成点的数量vectorPoint points; //点值//随机生成点坐标for (int i 0;i count;i){Point point;point.x rng.uniform(image.cols / 4, image.cols * 3 / 4);point.y rng.uniform(image.rows / 4, image.rows * 3 / 4);points.push_back(point); //将此时生成的点数据送入 points数组的最后一个}//检测凸包这里认为凸包只有一个vectorint hull; //存储一个凸包的边的一维数组 convexHull(Mat(points),hull,true);//输入二维点集输出找到的凸包//绘制出随机颜色的点image Scalar::all(0); //背景for (int i 0;i count;i){circle(image,points[i],3,Scalar(rng.uniform(0,255), rng.uniform(0, 255), rng.uniform(0, 255)),FILLED,LINE_AA);}//准备参数int hullcount (int)hull.size(); //凸包的边数(因为只有一个凸包而凸包是由边构成的序列所以返回序列长度应该返回的是边的个数)Point point0 points[hull[hullcount - 1]]; //连接凸包边的坐标点 最后一条边的坐标点//绘制凸包的边for (int i 0;i hullcount;i){Point point points[hull[i]]; //points[hull[i]]表示构成凸包边的某点因为凸包是一个点集合最外面的点连接起来的区域line(image, point0, point, Scalar(255, 255, 255), 2, LINE_AA);point0 point;}//显示效果图imshow(凸包检测示例,image);//按下ESC程序退出//key (char)waitKey();//if (key 27) break;waitKey(1000); //每秒显示一次}return 0;
}演示效果
示例2动态检测并绘制轮廓和凸包一个轮廓对应一个凸包
//动态检测绘制图形的轮廓和凸包//全局变量声明
Mat g_srcImage;
Mat g_grayImage;
int g_nThresh 50;
int g_nThresh_max 255;
RNG g_rng(12345);
Mat srcImage_copy g_srcImage.clone();
Mat g_thresholdMat_output;
vectorvectorPoint g_vContours;
vectorVec4i g_vHierarchy;//全局函数声明
void on_ThreshChange(int,void*);
int main()
{// Read image 读取图像SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN); //字体为绿色//载入原图g_srcImage imread(D:\\opencv_picture_test\\lena.jpg,1);//Mat srcImage imread(D:\\opencv_picture_test\\形态学操作\\孔洞.png, 0); //读取灰度图//转换成灰度并且模糊化降噪cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);blur(g_grayImage, g_grayImage, Size(3, 3));//创建窗口namedWindow(原始图窗口, WINDOW_AUTOSIZE);imshow(原始图窗口, g_srcImage);//创建滑动条并初始化createTrackbar(阈值, 原始图窗口, g_nThresh,g_nThresh_max, on_ThreshChange);on_ThreshChange(0,0);waitKey(0);return 0;
}
void on_ThreshChange(int, void*)
{//用Canny算子检测边缘Canny(g_grayImage, g_thresholdMat_output, g_nThresh, g_nThresh * 2, 3);//寻找轮廓.findContours(g_thresholdMat_output, g_vContours, g_vHierarchy,RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));//遍历每个轮廓寻找其凸包vectorvectorPoint hull( g_vContours.size()); //轮廓、凸包、点构成三维数组 凸包的数组的大小等于轮廓的大小for (unsigned int i 0;ig_vContours.size();i){convexHull(Mat (g_vContours[i]), hull[i],false); //在轮廓数组中寻找凸包存入对应的hull中}//绘出轮廓及其凸包Mat drawing Mat::zeros(g_thresholdMat_output.size(), CV_8UC3);for (int i 0; i g_vContours.size(); i){Scalar color Scalar(g_rng.uniform(0, 255),g_rng.uniform(0, 255), g_rng.uniform(0, 255));//任意值//绘制轮廓drawContours(drawing, g_vContours, i, color, 1, 8, g_vHierarchy,0, Point());//绘制凸包drawContours(drawing, hull, i, color, 1, 8, g_vHierarchy,0, Point());}//显示效果图imshow(效果图,drawing);
}演示效果 1、仅绘制凸包 2、仅绘制轮廓 3、既绘制轮廓也绘制凸包 更加凸显出轮廓与凸包的关系。 总结 学到的凸包知识点检测并绘制凸包轮廓、凸包、凸包连接点的结构关系。 学到的c语法知识点随机数生成器RNG的用法vector的push_back()操作。
参考链接 CRNG类与毛星云寻找凸包例程的理解 C push方法与push_back方法