opencv中凸包运算函数convexHull()的使用

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

1.功能描述

该函数cv::convexHull用于寻找一组二维点集的凸包,采用的是Sklansky算法[242],当前实现中具有O(N logN)的时间复杂度。

1.1什么是凸包?

让我们先从术语的两部分来理解——“凸”和“包”。

一个“凸”对象是指没有内角大于180度的对象。非凸的对象称为非凸的或凹的,下图展示了凸对象和非凸对象的例子。

包指的是物体的外部或轮廓。

因此,一组点或形状的凸包是一个紧贴着这些点或形状的最紧凑的凸边界。如图2所示,两个黑色形状的凸包用红色线条描绘。对于凸对象,其凸包就是其边界本身;而对于凹形状,凸包则是一个最紧致地包围它的凸边界。

2.函数原型


void cv::convexHull	(	
	InputArray 	points,
	OutputArray 	hull,
	bool 	clockwise = false,
	bool 	returnPoints = true 
)		

3.参数

  • 参数 points 输入的二维点集,存储在std::vector或Mat中.
  • 参数 hull 输出的凸包。它可以是一个索引的整数向量或点的向量。在第一种情况下,凸包元素是原数组中凸包点的基于0的索引(因为凸 包点的集合是原点集的子集)。在第二种情况下,凸包元素即凸包点本身.
  • 参数 clockwise 方向标志。如果该标志为真,输出的凸包按顺时针方向排列。否则,它按照逆时针方向排列。所采用的坐标系统其X轴指向右侧,Y轴指向上方。.
  • 参数 returnPoints 操作标志。当输入为矩阵且该标志为真时,函数返回凸包的点坐标。否则,它返回凸包点在原点集中的索引。如果输出数组是std::vector,该标志将被忽略,输出类型依据vector的实际类型而定:std::vector意味着returnPoints=false(返回索引),std::vector意味着returnPoints=true(返回点坐标)。

注意
points(输入点集)和hull(输出凸包)应该是不同的数组,不支持原地处理。这意味着cv::convexHull函数不会直接修改输入的点集数 组来存储结果,你需要提供一个独立的变量来接收计算出的凸包信息。

4.代码示例

#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
    Mat img( 500, 500, CV_8UC3 );
    RNG& rng = theRNG();
    for ( ;; )
    {
        int i, count = ( unsigned )rng % 100 + 1;
        vector< Point > points;
        for ( i = 0; i < count; i++ )
        {
            Point pt;
            pt.x = rng.uniform( img.cols / 4, img.cols * 3 / 4 );
            pt.y = rng.uniform( img.rows / 4, img.rows * 3 / 4 );
            points.push_back( pt );
        }
        vector< Point > hull;
        convexHull( points, hull, true );
        img = Scalar::all( 0 );
        for ( i = 0; i < count; i++ )
            circle( img, points[ i ], 3, Scalar( 0, 0, 255 ), FILLED, LINE_AA );
        imshow( "original", img );
        polylines( img, hull, true, Scalar( 0, 255, 0 ), 1, LINE_AA );
        imshow( "hull", img );
        char key = ( char )waitKey();
        if ( key == 27 || key == 'q' || key == 'Q' )  // 'ESC'
            break;
    }
    return 0;
}

5.运行结果

根据随机生成的点,然后根据这些点去进行运算,再把这些凸包点连接起来,如下图所示:

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值