opencv学习笔记二十二:凸包

凸包:一组平面上的点,求一个包含所有点的最小的 凸多边形,这就是凸包问题。这可以形象地想成这样:在地上放置一些不可移动的木桩,用一根绳子把他们尽量紧地圈起来,并且为凸边形,这就是凸包了。

Graham扫描法

 步骤:

1、bgr转灰度;

2、canny边缘检测;

3、寻找轮廓;

4、轮廓转凸包;

5、画出轮廓和凸包。

#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;

void callback(int, void*);
Mat src, dst1,dst2, canny_img;;
int value = 80;
RNG rng(1);
int main(int arc, char** argv)
{   	
	src = imread("1.jpg");
	namedWindow("src",CV_WINDOW_AUTOSIZE);
	imshow("src", src);
	cvtColor(src, src, CV_BGR2GRAY);
	blur(src, src, Size(3, 3));

	namedWindow("output", CV_WINDOW_AUTOSIZE);
	createTrackbar("threshold", "output", &value,255, callback);
	callback(0, 0);
	waitKey(0);
	return 0;
}
void callback(int, void*){
        //canny边缘检测
	Canny(src, canny_img, value, 2 * value);

	//寻找轮廓
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(canny_img, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE,Point(0,0));
	
	//将轮廓转化为凸包
	vector<vector<Point>> convexs(contours.size());
	for (int i = 0; i < contours.size(); i++) {
		convexHull(contours[i], convexs[i], false, true);
	}

	//画轮廓和凸包
	dst1 = Mat::zeros(src.size(), CV_8UC3);
	dst2 = Mat::zeros(src.size(), CV_8UC3);
	for (int j = 0; j < contours.size(); j++) {
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		drawContours(dst1, contours, j, color, 2);
		drawContours(dst2, convexs, j, color, 2);
	}

	imshow("output",canny_img);
	imshow("contours", dst1);
	imshow("convexs", dst2);

}

运行结果如下:

猜你喜欢

转载自blog.csdn.net/qq_24946843/article/details/82528914