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