計算一個圖像的輪廓,不同閾值下canny函數的輪廓,長度,面積。矩以及中心距。並且比較中心距和opencv函數計算的輪廓面積

在這裏插入圖片描述

在這裏插入圖片描述

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


using namespace cv;
using namespace std;



#define window "【原始圖】"
#define windowx "【結果圖1】"
#define windowy "[結果圖2]"
//計算一個圖像的輪廓,不同閾值下canny函數的輪廓,長度,面積。矩以及中心距。並且比較中心距和opencv函數計算的輪廓面積。

Mat src, dst, tmp;
int thresh = 40;
int thresh_max = 255;
RNG rng = theRNG();

void on_canny(int, void*);
int main()
{
	//1.讀入圖像,轉換灰度。
	//2。建立窗口以及回調函數。
	src = imread("馬車.jpg");
	cvtColor(src, src, CV_BGR2GRAY);
	imshow(window, src);

	namedWindow(windowx);
	imshow(windowx, src);
	
	createTrackbar("thresh", window, &thresh, thresh_max, on_canny);
	

	waitKey(0);
	return 0;


}

void on_canny(int, void*)
{
	//3,找出canny邊界輪廓。
	Canny(src, tmp, thresh, 2 * thresh);
	//4。對二值圖像求輪廓。
	vector<vector<Point>> contours;
	vector<Vec4i> heri;
	findContours(tmp,contours,heri,RETR_TREE,CHAIN_APPROX_SIMPLE);
	
	//5.多各個輪廓求矩。
	vector<Moments> mu(contours.size());
	for (int i = 0; i < contours.size(); ++i)
	{
		mu[i]=moments(contours[i]);//計算每個輪廓的矩。


	}
	//6.利用得到的各個矩,來求中心距。
	vector<Point> mc(contours.size());
	for (int i = 0; i < contours.size(); i++)
	{
		float x = static_cast<float>(mu[i].m10 / mu[i].m00);
		float y = static_cast<float>(mu[i].m01/ mu[i].m00);
		mc.push_back(Point(x, y));
			
	}
	//7。繪製得到的輪廓,並且將中心距在輪廓中標出。
	dst = Mat::zeros(src.size(),CV_8UC3);
	for (int i = 0; i < contours.size(); i++)
	{
		int nx = rng.uniform(0, 255);
		int ny = rng.uniform(0, 255);
		int nz = rng.uniform(0, 255);
		Scalar color = Scalar(nx, ny, nz);//隨機爲當前輪廓取一個顏色。
		drawContours(dst,contours,i,color);
		circle(dst, mc[i], 3, color, -1);//畫出輪廓質心。
	}



	//8.比較由矩和opencv分別計算得到面積,同時輸出輪廓的長度。
	for (int i=0; i < contours.size(); ++i)
	{
		cout << "由矩得到輪廓的面積:" << mu[i].m00 ;
		cout << "由opencv函數得到的輪廓面積:" << contourArea(contours[i]) << endl;
		cout << "輪廓長度:" << arcLength(contours[i], true)<<endl;


	}
	namedWindow(windowx);
	imshow(windowx,dst);

}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章