opencv —— convexHull 寻找并绘制凸包

凸包的定义:

包含点集 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

 

猜你喜欢

转载自www.cnblogs.com/bjxqmy/p/12344543.html