在普通的几何空间里,向量是一个带方向和大小的量,但一旦建立了坐标系,向量就与有序数组(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;
}
方差的计算公式是针对一维特征,即针对同一特征不同样本的取值来进行计算得到;
协方差要求至少满足二维特征;