OpenCVの画像モーメント(空間モーメント、中心モーメント、正規化された中心モーメント、のHuモーメント)

厳密に言えば瞬間を確率と統計の概念され、数値的な特性は確率変数です。Xは確率変数セットは、Cは、E [(X-C)^量定数である k]は点CについてX kを次モーメントと呼ばれています 次のように2例より重要なのは、次のとおりです。

Xの原点モーメントKの順と呼ば1.C = 0、この場合a_k = E(X ^ K);

k個の順序中心モーメント2.C = E(X)、この時間μ_k= E [(X-EX)^ k]はXと呼ばれ

原点モーメントが所望の順序、μ_1= 0一次中心モーメントであり、Xは、分散Var(X)のμ_2第2の中心モーメントです。まれ偏りかどうかを測定することが可能μ_3、使用されない4次モーメントよりも統計的に高く、μ_4は、平均剛性急の分布(密度)の程度を測定することができます。
数学のために

モーメント、中心モーメント、重心、方向パッチ

一次起源モーメントが望まれています。第二の中心モーメントは、確率変数の分散である。ほとんど使われない4次モーメントよりも統計的に高いです。中心部から3次分布をバイアスすることができるかどうかを測定します。四次中心モーメントは、平均測定を中心に分布する方法を急の範囲に行くことができます。

我々は画素の座標を有するように、2次元確率変数(X、Y)は、画像のために、2つの次元のグレースケール画像のグレースケール密度関数を表すことができ、グレーモーメントを説明するために使用することができます画像の特徴の。 

 

空間モーメントは、エリアや品質の本質です。これは、重力により重心/一次モーメントを計算することができます。

 重心(センターセンター):

 

胡モーメント

 

class Moments{
 public:
    Moments();
    Moments(double m00, double m10, double m01, double m20, double m11,
            double m02, double m30, double m21, double m12, double m03 );
    Moments( const CvMoments& moments );
    operator CvMoments() const;
     // spatial moments 空间矩
    double  m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
    // central moments 中心矩
    double  mu20, mu11, mu02, mu30, mu21, mu12, mu03;
    // central normalized moments 中心归一化矩
    double  nu20, nu11, nu02, nu30, nu21, nu12, nu03;
   }

 

 

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

using namespace cv;
using namespace std;


//定义窗口名字的宏
#define WINDOW_NAME1 "【原始图】"
#define WINDOW_NAME2 "【图像轮廓】"

//全局变量的声明

Mat g_srcImage, g_grayImage;
int g_nThresh = 100;
int g_nMaxThresh = 255;
RNG g_rng(12345);
Mat g_cannyMat_output;
vector<vector<Point> > g_vContours;
vector<Vec4i>g_vHierarchy;

//全局函数声明
void on_ThreshChange(int, void*);

//main()函数
int main()
{
	//改变console字体颜色
	system("color 1E");
	//读入原图,返回3通道图像数据
	g_srcImage = imread("E:\\VS2015Opencv\\vs2015\\project\\picture\\01.jpg", 1);
	//源图像转化为灰度图像并平滑
	cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
	blur(g_grayImage, g_grayImage, Size(3, 3));

	//创建新窗口
	namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
	imshow(WINDOW_NAME1, g_srcImage);

	//创建滚动条并进行初始化
	createTrackbar("阈值:", WINDOW_NAME1, &g_nThresh, g_nMaxThresh, on_ThreshChange);
	on_ThreshChange(0, 0);
	waitKey(0);
	return 0;

}

void on_ThreshChange(int, void *)
{
	//使用canny检测边缘
	Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh * 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 (unsigned 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 (unsigned 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);
	}
	//显示到窗口中
	namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
	imshow(WINDOW_NAME2, drawing);
	//通过m00计算轮廓面积和Opencv函数比较
	printf("\t输出内容:面积和轮廓长度\n");
	for (unsigned int i = 0; i < g_vContours.size(); i++)
	{
		printf(">通过m00计算出轮廓[%d]的面积:(M_00) = %.2f \n Opencv函数计算出面积 = %.2f,长度:%.2f \n\n", i, mu[i].m00, contourArea(g_vContours[i]), arcLength(g_vContours[i], true));
		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);
	}
}

  

本文参考:图像的形状特征——图像的矩

おすすめ

転載: www.cnblogs.com/fcfc940503/p/11319251.html