OpenCV矩阵之一平均值、方差、协方差、特征向量

 在普通的几何空间里,向量是一个带方向和大小的量,但一旦建立了坐标系,向量就与有序数组(x,y,z)对应起来了。这样的3维有序数组(x,y,z)就是一个向量,但也可以说是一个一行三列的矩阵。
 矩阵的每一行(列)都构成行(列)向量。对矩阵施行初等行变换,实质是行向量的线性运算。线性方程组解的结构涉及到解向量的线性组合,而解向量的读取又与矩阵的列向量密切相关。
 注意,协方差矩阵是一个对称矩阵,在计算机处理中,一般协方差矩阵的计算是这样的:先让样本矩阵中心化,即每一维度减去该维度的均值(这样一来,每一维度上的均值为0),然后直接使用新得到的样本矩阵乘以它的转置,最后除以(N-1)。OpenCV正是采用了这种算法。

Scalar类
 scalar的意思是标量

typedef struct Scalar
{
	double val[4];
}Scalar;

scalar是由一个由长度为4的数组作为元素构成的结构体,最多可以存储四个值,没有提供的默认值为0。
常使用的场景如下:

Mat M(7,7,CV_32FC2,Scalar(1,3));

上面的代码表示:创建一个2通道,且每个通道的值都为(1,3),深度为32,7行7列的图像矩阵。CV_32F表示每个元素的值的类型为32位浮点数,C2表示通道数位为2,Scalar(1,3)表示对矩阵每个元素都赋值为(1,3),第一个通道中的值都是1,第二个通道中的值都是3.

cv::mean()

cv::Scalar cv::mean(
 	cv::InputArray src,
	cv::InputArray mask=cv::noArray(),     //Optional,do only where nonzero
	 );

函数cv::mean()计算输入矩阵src中未被屏蔽的所有像素的平均值。如果src是多通道,则以每个通道为基础计算结果。
cv::meanStdDev()

void cv::meanStdDev(
	cv::InputArray src,
	cv::OutputArray mean,
	cv::OutputArray stddev,
	cv::InputArray mask = cv::noArray(), //optional,do only where nonzero
	);

函数cv::meanStdDev()计算输入矩阵src中未被屏蔽的像素的平均值以及它们的标准差。如果src是多通道的,则以每个通道为基础计算平均值和标准差。
cv::calcCovarMatrix()

void cv::calCovarMatrix(
	const cv::Mat* samples,
	int nsamples,
	cv::Mat& covar,
	cv::Mat& mean,
	int flags,
	int ctype=cv::F64
	}
void cv::calCovarMatrix(
	cv::InputArray samples,
	cv::Mat& covar,
	cv::Mat& mean,
	int flags,
	int ctype=cv::F64
	}

给定一些向量,假设这些向量表示的点是近似高斯分布的,cv::calcCovarMatrix()将计算这些点的均值和协方差矩阵。
cv::calcCovarMatrix()有两个基本的调用方法,第一种是指向cv::Mat 对象矩阵的指针和表示矩阵中的矩阵数量的nsamples一起传入函数。这种情况下,矩阵可以是nx1或1xn.第二种是传入一个nxm的矩阵。

特征值与特征向量(eigen value\eigen vector)

bool cv::eigen(
	cv::InputArray src,
	cv::OutputArray eigenvalues,
	cv::OutputArray eigenvectors,
	int lowindex = -1,
	int highindex = -1
	);

给定一个对称矩阵mat,必须为浮点类型之一。特征值矩阵以递减的顺序包含mat的特征值,特征向量则以行的的形式存储在矩阵中。

示例

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
using namespace cv;

int main()
{
	Mat src = imread("E:/image4.jpg");
	imshow("src", src);

	Mat means, stddev;
	meanStdDev(src, means, stddev);

	printf("means rows:%d,means cols:%d\n", means.rows, means.cols);
	printf("stddev rows:%d,stddev cols:%d\n", stddev.rows, stddev.cols);
	for (int row = 0; row < means.rows; row++)
	{
		printf("mean %d =%.3f\n", row,means.at(row));
		printf("stddev %d =%.3f\n", row, stddev.at(row));
	}

	Mat samples = (Mat_(5, 3) <<10,20, 10, 20, 10, 30, 60, 40, 60, 50, 60, 70, 30, 90, 30);

	Mat cov, mu;
	calcCovarMatrix(samples, cov, mu, CV_COVAR_NORMAL | CV_COVAR_ROWS);
	cout << "===========" << endl;
	cout << "cov:" << endl;
	cout << cov << endl;
	cout << "===========" << endl;
	cout << "means:" << endl;
	cout << mu << endl;

	Mat data = (Mat_(2, 2) << 10, 2, 2, 10);
	Mat eigenvalues, eigenvector;
	eigen(data, eigenvalues, eigenvector);
	for (int i = 0; i < eigenvalues.rows; i++)
	{
		printf("eigen value%d:%.3f\n", i, eigenvalues.at(i));
	}
	cout << "egien vector" << endl;
	cout << eigenvector << endl;

	waitKey(0);
	return 0;
}

方差的计算公式是针对一维特征,即针对同一特征不同样本的取值来进行计算得到;
协方差要求至少满足二维特征;

你可能感兴趣的:(Opencv,数据结构与算法,OpenCV,协方差)