1. 程式人生 > >OpenCv-C++-下的輪廓周圍繪製矩形框和圓形框

OpenCv-C++-下的輪廓周圍繪製矩形框和圓形框

目前我正在學習OpenCv下的輪廓周圍繪製矩形框和圓形框,將個人學習記錄放到這裡。

下面介紹幾個相關函式: findContours():不用說了,找到影象的輪廓點 approxPolyDP():減少輪廓點集裡的個數 boundingRect():得到包覆此輪廓的最小正矩形 minEnclosingCircle():最小包圍圓形 minAreaRect():帶旋轉的矩形

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>

using namespace cv;
using namespace std;

Mat src, dst, gray_src;
void polyPD(int, void*);

int threshold_value = 100;
int threshold_max = 255;

int main(int argc, char** argv)
{
	src = imread("D:/test/hot-ball.png");
	if (!src.data)
	{
		cout << "圖片未找到" << endl;
		return -1;
	}
	cvtColor(src, gray_src, CV_BGR2GRAY);
	namedWindow("output title", CV_WINDOW_AUTOSIZE);
	createTrackbar("Move", "output title", &threshold_value, threshold_max, polyPD);
	polyPD(0, 0);
	imshow("input title", src);
	waitKey(0);
	return 0;

}

void polyPD(int, void *)
{
	Mat bin_out;
	vector<vector<Point>> contours;//定義影象輪廓點集
	vector<Vec4i> hieracy;

	//二值化操作
	threshold(gray_src, bin_out, threshold_value, threshold_max, THRESH_BINARY);
	//找到影象輪廓點
	findContours(bin_out, contours, hieracy, RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(-1, -1));

	vector<vector<Point>> contours_ploy(contours.size());//定義影象輸出的多邊形點集
	vector<Rect> ploy_rects(contours.size());
	vector<Point2f> ccs(contours.size());//定義圓心座標
	vector<float> radius(contours.size());//定義圓的半徑

	vector<RotatedRect> minRects(contours.size());
	vector<RotatedRect> myellipse(contours.size());
	dst = Mat::zeros(src.size(), src.type());
	RNG rng(12345);
	for (size_t i = 0; i < contours.size(); i++)
	{//對影象輪廓點進行多邊形擬合
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		//繪製熱氣球輪廓
		//drawContours(dst, contours,(int)i, color,1,8,hieracy,0,Point(-1,-1));
		approxPolyDP(contours[i], contours_ploy[i], 3, true); //減少點集裡的個數
		ploy_rects[i] = boundingRect(contours_ploy[i]);
		minEnclosingCircle(contours_ploy[i], ccs[i], radius[i]);
		if (contours_ploy[i].size() > 5) {
			myellipse[i] = fitEllipse(contours_ploy[i]);//將點擬合成橢圓
			minRects[i] = minAreaRect(contours_ploy[i]);
		}
		
	}
	

	Point2f pts[4]; //畫直線需要4個點
	for (size_t k = 0; k < contours.size(); k++)
	{
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		//rectangle(drawImg, ploy_rects[t], color, 2, 8);
		//circle(drawImg, ccs[t], radius[t], color, 2, 8);
		if (contours_ploy[k].size() > 5) {

			ellipse(dst,myellipse[k], color, 1, 8);//繪製橢圓
			minRects[k].points(pts);
			for (int r = 0; r < 4; r++) {
				line(dst,pts[r], pts[(r + 1) % 4], color, 1, 8);
			}
		}
	}

	imshow("output title", dst);
	return;

}
/*
approxPolyDP():
InputArray curve:一般是由影象的輪廓點組成的點集
OutputArray approxCurve:表示輸出的多邊形點集
double epsilon:主要表示輸出的精度,就是兩個輪廓點之間的最大距離數,5,6,7...
bool closed:表示輸出的多邊形是否封閉

*/
/*THRESH_TRIANGLE,THRESH_OTSU,自動尋找閾值
不清楚閾值使用哪些數字時,可以THRESH_OTSU||THRESH_BINARY這樣寫;
vector<Point2f>  圓心;
*/
/*
當得到物件的輪廓後,可用boundingRect()得到包覆此輪廓的最小正矩形boundingRect();
帶旋轉的矩形minAreaRect();
最小包圍圓形 minEnclosingCircle()

*/