凸包的定义:
包含点集 S 所有点的最小凸多边形称为凸包。
凸包绘制原理:Graham 扫描法
- 首先选择 y 方向上最低的点作为起始点 p0。
- 然后以 p0 为原点,建立极坐标系,做逆时针极坐标扫描,依次添加凸包点 p1,p2 ...pn(排序顺序根据极坐标角度大小)
- 若当前扫描点与下一个点构成的直线为逆时针转向,则将该点添加到凸包点集合,否则忽略。
寻找凸包:convexHull 函数
void convexHull(InputArray points, OutputArray hull, bool clockwise = false, bool returnPoints = true);
- points,输入的二维点集,可以填 Mat 类型或者 vector。
- hull,输出参数,函数调用后找到的凸包。
- clockwise,操作方向标识符。当此标识符为 true 时,输出凸包为顺时针方向,否则为逆时针方向,默认为 false。并且假设坐标系的 x 轴指右,y 轴指上。
- returnPoints,当标志为真时,函数返回各凸包的各个点。否则返回凸包个点的指数。
代码示例:
#include<opencv.hpp> #include<iostream> using namespace cv; using namespace std; int main(){ Mat src = imread("C:/Users/齐明洋/Desktop/1.jpg"); imshow("src", src); Mat gray, bin_img; cvtColor(src, gray, COLOR_BGR2GRAY); medianBlur(gray, gray, 3);//中值滤波,去除椒盐噪声 imshow("gray", gray); //获得二值图像,canny 和 threshold 两种方法都可以 //Canny(gray, bin_img, 20, 40, 3); threshold(gray, bin_img, 80, 255, THRESH_BINARY); imshow("bin_img", bin_img); //获取轮廓 vector<vector<Point> >contours; findContours(bin_img, contours, RETR_TREE, CHAIN_APPROX_NONE); //获取凸包 vector<vector<Point> >hull(contours.size()); Mat dst = Mat(src.size(), src.type()); for (int i = 0; i < contours.size(); i++) { convexHull(contours[i], hull[i]); drawContours(dst, hull, i, Scalar(0, 0, 255), 1); } imshow("dst", dst); waitKey(0); }
效果演示:
借鉴博客:https://blog.csdn.net/just_tree/article/details/89296985
原文地址:https://www.cnblogs.com/bjxqmy/p/12344543.html
时间: 2024-10-14 20:11:09