カムコンベックスホールを探しています。


今日はOpenCV 2のCovecHull関数を勉強します。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を直接呼び出してもいいです。実行結果は図のようになります。