opencv学习笔记(三十)凸包

1.凸包概念

在一个多变形边缘或者内部任意两个点的连线都包含在多边形边界或者内部。 包含点集合S中所有点的最小凸多边形称为凸包。 

使用Graham扫描算法。

2.Graham算法

首先选择Y方向最低的点作为起始点p0

p0开始极坐标扫描,依次添加p1….pn(排序顺序是根据极坐标的角度大小,逆时针方向)

对每个点pi来说,如果添加pi点到凸包中导致一个左转向(逆时针方法)则添加该点到凸包, 反之如果导致一个右转向(顺时针方向)删除该点从凸包中。

                                       

3.相关API

convexHull(InputArray point,OutputArray hull,bool clockwise,bool returnPoints

point: 输入候选点,来自findContours

hull:凸包

clockwise:default true, 顺时针方向

returnPoints:true 表示返回点个数,如果第二个参数是  vector<Point>则自动忽略

4.代码实现

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;

Mat src,srcGray, dst;
char inputName[] = "input name";
char outputName[] = "output name";
int threshold_value = 100;
int threshold_max = 255;
RNG rng(12345);
void Convex_Demo(int, void *);
int main()
{
	src = imread("D:/demo.jpg");
	if (src.empty())
	{
		cout << "找不到图像!" << endl;
		return -1;
	}
	namedWindow(inputName, CV_WINDOW_AUTOSIZE);
	namedWindow(outputName, CV_WINDOW_AUTOSIZE);
	imshow(inputName, src);
	//第一步转灰度
	cvtColor(src, srcGray, CV_BGR2GRAY);
	blur(srcGray, srcGray, Size(3, 3), Point(-1, -1));
	createTrackbar("Threshold Value", outputName, &threshold_value, threshold_max, Convex_Demo);
	Convex_Demo(0, 0);

	waitKey(0);
	return 0;
}
void Convex_Demo(int, void *)
{
	Mat threshold_output;
	vector<vector<Point>> points;
	vector<Vec4i> hierachy;

	//第二步二值化获取轮廓
	threshold(srcGray, threshold_output, threshold_value, 255, THRESH_BINARY);
	//第三步寻找轮廓放入points容器
	findContours(threshold_output, points, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
	//第四步调用凸包
	vector<vector<Point>> hull(points.size());
	for (size_t i = 0; i < points.size();i++)
	{
		convexHull(points[i], hull[i], false);
	}
	dst = Mat::zeros(src.size(), CV_8UC3);
	//第五步,绘制
	for (size_t i = 0; i < points.size(); i++)
	{
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		drawContours(dst, hull, i, color, 1, LINE_AA, hierachy, 0, Point(0, 0));
	}
	imshow(outputName, dst);
}

先通过转灰度图像,threshold方法获取二值图像,再寻找轮廓,之后调用凸包API,进行画凸包针对每个轮廓,最后使用轮廓绘制画出凸包。

5.运行结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值