1. 程式人生 > >查詢和繪製圖像輪廓矩

查詢和繪製圖像輪廓矩

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