查找和绘制图像轮廓矩

1、矩的计算

Moments moments(InputArray array,bool binaryImage=false)

参数一:输入矩阵

参数二:若为true所有非零像素为1

返回图像的矩

2、计算轮廓面积

double contourArea(InputArray array,bool oriented = false)

参数一:输入向量二维点(轮廓顶点)

参数二:若为true则返回一个带符号的面积值,其正负表示轮廓的方向是逆时针还是顺时针

3、计算轮廓长度

double arcLength(InputArray curve,bool closed)

参数一:输入二维集点 vector或Mat

参数二:轮廓是否封闭标识符

示例代码:

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

#define WINDOW_NAME1 "【原始窗口】"
#define WINDOW_NAME2 "【轮廓图】"
using namespace std;
using namespace cv;

Mat g_srcImage,g_grayImage;
int g_thresh = 80;
int g_thresh_max = 255;
RNG g_rng(12345);
Mat g_cannyMat_output;
vector< vector<Point> > g_vContours;
vector<Vec4i> g_vHierarchy;

void on_Thresh_Change(int,void *);
int main(int argc,char * argv[])
{
	if(argc!=2)
	{
		cout<<"input error"<<endl;
		return -1;
	}
	g_srcImage = imread(argv[1]);
	if(g_srcImage.empty())
	{
		cout<<"read photo fail"<<endl;
		return -1;
	}
	cvtColor(g_srcImage,g_grayImage,COLOR_BGR2GRAY);
	blur(g_grayImage,g_grayImage,Size(3,3));
	namedWindow(WINDOW_NAME1,WINDOW_AUTOSIZE);
	namedWindow(WINDOW_NAME2);
	imshow(WINDOW_NAME1,g_srcImage);
	
	createTrackbar("canny检测",WINDOW_NAME2,&g_thresh,g_thresh_max,on_Thresh_Change);
	on_Thresh_Change(0,0);
	
	waitKey(0);
	return 0;
}

void on_Thresh_Change(int,void *)
{
	//canny算子检测边缘
	Canny(g_grayImage,g_cannyMat_output,g_thresh,g_thresh*2,3);
	//查找轮廓
	findContours(g_cannyMat_output,g_vContours,g_vHierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point(0,0)
);
	//计算矩
	vector<Moments> mu(g_vContours.size());
	for(unsigned int i=0;i<g_vContours.size();i++)
	{
		mu[i] = moments(g_vContours[i],false);
	}
	//计算中心矩
	vector<Point2f> mc(g_vContours.size());
	for(int i=0;i<g_vContours.size();i++)
	{
		mc[i] = Point2f(static_cast<float>(mu[i].m10/mu[i].m00),static_cast<float>(mu[i].m01/mu[i].m00));
	}
	//绘制轮廓
	Mat drawing = Mat::zeros(g_cannyMat_output.size(),CV_8UC3);
	for(int i=0;i<g_vContours.size();i++)
	{
		Scalar color = Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255));
		drawContours(drawing,g_vContours,i,color,2,8,g_vHierarchy,0,Point());
		circle(drawing,mc[i],4,color,-1,8,0);
	}
	imshow(WINDOW_NAME2,drawing);
	//显示相关信息
	cout<<"输出内容:面积和轮廓长度"<<endl;
	for(int i=0;i<g_vContours.size();i++)
	{
		printf("通过m00计算出轮廓[%d]面积:%.2f,opencv函数计算出的面积:%.2f,长度:%.2f\n\n",i,mu[i].m00,contourArea(g_vContours[i]),arcLength(g_vContours[i],true));
			
	}
}
内容来自:opencv3编程入门 毛星云pdf

猜你喜欢

转载自blog.csdn.net/gg101001/article/details/79608085