计算一个图像的轮廓,不同阈值下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);

}



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