今天学习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即可,运行结果如图