opencv學習之路(38)、Mat像素統計基礎——均值,標準差,協方差;特徵值,特徵向量

本文部份內容轉自  https://www.cnblogs.com/chaosimple/p/3182157.htmlhtml

1、統計學概念

2、爲何須要協方差

3、協方差矩陣

注:上述協方差矩陣還須要除以除以(n-1)。MATLAB使用cov函數計算協方差時自動除以了(n-1),opencv使用calcCovarMatrix函數計算後還須要手動除以(n-1)ios

協方差具體計算

以學生成績舉例:有5名學生,參加數學、英語、美術考試,得分如圖函數

1.計算均值矩陣Mspa

均值是對每一列求平均值:means=【66,60,60】3d

則均值矩陣M爲code

2.原矩陣A-均值矩陣M=Yhtm

Y=A-M=blog

3.Y轉置×Y
圖片

 

4.最後將結果除以(n-1)get

4、代碼運行

1.MATLAB代碼

2.opencv計算數字矩陣的協方差

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

void main()
{
    Mat data = (Mat_<float>(5, 3) << 90, 60, 90, 90, 90, 30, 60, 60, 60, 60, 60, 90, 30, 30, 30);
    cout << "data:" << endl << data << endl;
    Mat covar1, means1;//協方差,均值
    calcCovarMatrix(data, covar1, means1, CV_COVAR_NORMAL | CV_COVAR_ROWS);
    cout << "---------------------------" << endl;
    cout << "means:" << endl << means1 << endl;
    cout << "covar:" << endl << covar1/4 << endl;
    getchar();
    waitKey(0);//暫停按鍵等待
}    

3.opencv計算圖片的均值、標準差、協方差

 (1)均值和標準差

#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

void main()
{
    Mat src = imread("E://1.jpg");
    imshow("img", src);

    Mat means, stddev, covar;
    meanStdDev(src, means, stddev);//計算src圖片的均值和標準差
    printf("means rows:%d,means cols %d\n", means.rows, means.cols);//RGB三通道,因此均值結果是3行一列
    printf("stddev rows:%d,means cols %d\n", stddev.rows, stddev.cols);

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

(2)均值和協方差

#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;


void show(Mat a,int i){
    Mat covar, means;
    calcCovarMatrix(a, covar, means, CV_COVAR_NORMAL | CV_COVAR_ROWS);//計算協方差,均值
    cout << "mean " << i << " = " << means;
    cout << "covar " << i << " = " << covar;
}

void main()
{
    Mat src = imread("E://1.png");
    imshow("img", src);

    //通道分離
    vector<Mat>channels;//定義Mat類型的向量
    split(src, channels);//通道分離
    //計算圖片的協方差
    show(channels.at(0), 0);
    show(channels.at(1), 1);
    show(channels.at(2), 2);

    waitKey(0);//暫停按鍵等待
}      

 之因此沒用前面那張大圖,是由於圖片的協方差矩陣太大了,我隨手畫了個小圖,輸出都特別多

5、特徵值和特徵向量

#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;

void main()
{
    Mat data = (Mat_<double>(2, 2) <<
        1, 2,
        2, 1); //opencv求特徵值和特徵向量,輸入矩陣必須是對稱矩陣
    Mat eigenvalue, eigenvector;
    eigen(data, eigenvalue, eigenvector);
    for (int i = 0; i < eigenvalue.rows; i++)
        cout << "eigen value " << i << " =" << eigenvalue.at<double>(i)<<endl;
    cout << "eigen vector: "<< endl;
    cout <<eigenvector<< endl;

    getchar();
}      

當矩陣×2時,特徵值翻倍,特徵向量不變

相關文章
相關標籤/搜索