寻找凸包 convex hull(一)

      今天学习OpenCV2中的ConvecHull函数连接如下:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/shapedescriptors/hull/hull.html#hull

网上看了看有好多种方法来实现凸包的寻找,我自己也尝试一下暴力搜索解决这个问题

搜索的思路就是:凸包上的每条边都会是所有点在该直线的同一侧

思路是非常简单的,下面是代码

#ifndef CONVEX_HULL_MM
#define CONVEX_HULL_MM
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

#define Width 640
#define Height 480
#define PointNum 18
//typedef struct myPoint
//{
//	int x;
//	int y;
//	bool operator == (const myPoint &point)
//	{
//		return ((this->x == point.x)&&(this->y == point.y));
//	}
//}_Point;
void drawPoint();
bool reverseYAxis(vector<Point> &input);
void getPoint(vector<Point> &input);
#endif

源文件

/*
	2013/12/23
	寻找凸包的暴力方法
*/

#include "stdafx.h"
#include "convexhull.h"
#include <cmath>
#include <cstdlib>

static Mat img;
static vector<Point> input(PointNum);

//opencv窗口的坐标系与笛卡尔坐标系的Y轴刚好相反
bool reverseYAxis(vector<Point> &input)
{
	for (int i=0; i<input.size(); i++)
	{
		input[i].x = input[i].x;
		input[i].y = Height - input[i].y;
	}
	return true;
}
//使用随机数产生需要的点
void getPoint(vector<Point> &input)
{
	RNG rng(1111);
	for (int i=0; i<PointNum; i++)
	{
		input[i].x = rng.uniform(100, 540);
		input[i].y = rng.uniform(10, 400);
	}
}

//寻找并绘制边界--暴力的方法
//思路是凸包的边界一定可以让剩余点都在该边界的一侧
bool findBorder(const vector<Point> &input)
{
	int A, B, C, D;
	int counter = 0;
	Point p0, p1, temp;
	for (int i=0; i<input.size(); i++)
	{
		for (int j=i+1; j<input.size(); j++)//遍历得到每条直线的两个点
		{
			p0 = input[i];
			p1 = input[j];
			A = p0.y - p1.y; B = p1.x - p0.x;//A,B,C根据直线的两点式得到
			C = p0.x*p1.y - p0.y*p1.x;
			for (int k=0; k<input.size(); k++)
			{
				if(input[k]==p0 || input[k]==p1)//对直线外的所有点遍历
					continue;
				D = A*input[k].x + B*input[k].y + C;
				if(D>0)
					counter++;
				else 
					counter--;
			}
			if(abs(counter) == PointNum-2) //统计,找到符合条件者
			{
				line(img, input[i], input[j], Scalar(255,0,0));
			}
			counter = 0;
		}
	}
	return true;
}

void drawPoint()
{
	getPoint(input);
	reverseYAxis(input);
	img.create(Size(640, 480), CV_8UC3);
	
	for(int i=0; i<input.size(); i++)
	{
		circle(img, input[i], 10, Scalar(0,0,255), 3, 8);
	}
	findBorder(input);
	imshow("wmd", img);
}
在main函数中直接调用drawPoint即可,运行结果如图




你可能感兴趣的:(opencv,convexhull)