opencv矩陣運算(一)


圖像主要是基於矩陣格式排列的,因此OpenCV中矩陣操作非常重要;

本文總結了:

矩陣的創建;

矩陣初始化;

矩陣運算;

矩陣乘法;

矩陣轉置;

矩陣的逆;等操作;

 

1.OpenCV矩陣的創建:

創建矩陣需要知道矩陣的尺寸大小和數據類型;

矩陣尺寸大小:就是m行n列;Size(5,5);

矩陣數據類型:深度8/32位,類型uchar/float,通道數1/3/4;

CV_8UC1// 8位無符號單通道 

CV_8UC3// 8位無符號3通道 

CV_8UC4// 8位無符號4通道 

CV_32FC1// 32位浮點型單通道 

CV_32FC3// 32位浮點型3通道 

CV_32FC4// 32位浮點型4通道 

一般,采用Mat類創建矩陣:

void main()

{

       Mat a(Size(5,5),CV_8UC1);//單通道

       cout<<"a = "<<a<<endl;

      

       Mat b = Mat(Size(5,5),CV_8UC3);//3通道

       cout<<"b = "<<b<<endl;

       system("pause");

}

  

【注】:3通道矩陣中,一個矩陣元素包含3個變量;

【注】:Mat創建矩陣,默認通過隨機值初始化矩陣數值;

2.矩陣初始化:

Mat類幾種初始化創建方法:

void main()

{

       Mat mz = Mat::zeros(Size(5,5),CV_8UC1);//全0矩陣

       Mat mo = Mat::ones(Size(5,5),CV_8UC1);//全1矩陣

       Mat me = Mat::eye(Size(5,5),CV_32FC1);//對角線為1的對角矩陣

       cout<<"mz = "<<mz<<endl;

       cout<<"mo = "<<mo<<endl;

       cout<<"me = "<<me<<endl;

       system("pause");

}

3.OpenCV矩陣運算:Mat類支持所有矩陣運算;

①使用”+”,”-”符進行矩陣加減運算:

void main()

{

       Mat a = Mat::eye(Size(3,2),CV_32FC1);

       Mat b = Mat::ones(Size(3,2),CV_32FC1);

       Mat c = a+b;

       Mat d = a-b;

       cout<<"a = \n "<<a<<endl;

       cout<<"b = \n "<<b<<endl;

       cout<<"c = \n "<<c<<endl;

       cout<<"d = \n "<<d<<endl;

       system("pause");

}

4.矩陣乘法:“*”,“.*”

①使用“*”表示矩陣與標量相乘;

②矩陣與矩陣相乘“*”:滿足矩陣相乘條件;

③矩陣和矩陣點乘“.mul()”,對應元素相乘;

void main()

{

       Mat m1 = Mat::eye(2,3,CV_32FC1);

       Mat m2 = Mat::ones(3,2,CV_32FC1);

       cout<<"m1 = \n "<<m1<<endl;

       cout<<"m2 = \n "<<m2<<endl;

 

       cout<<"m1*2 = \n "<<m1*2<<endl;//矩陣*標量

       cout<<"(m1+2).*(m1+3) = \n "<<(m1+2).mul(m1+3)<<endl;//矩陣點乘

       cout<<"m1*m2 = \n "<<m1*m2<<endl;//矩陣相乘

       system("pause");

}

 5.矩陣轉置:矩陣的行與列對調;

由Mat類t()函數實現:

void main()

{

       Mat m1 = Mat::eye(4,6,CV_32FC1);

       cout<<"m1 = \n "<<m1<<endl;

       Mat m1t = m1.t();

       cout<<"m1t = \n "<<m1t<<endl;

       system("pause");

}

6.矩陣的逆:

有兩種方法:

①伴隨陣法:inv(A)=(1/|A|)×A* ;

其中inv(A)表示矩陣A的逆矩陣,|A|為矩陣A的行列式的值,A*為矩陣A的伴隨矩陣。

②行初等變換法:(A|E)經過初等變換得到(E|A^(-1));

【注】:初等變化只用行(列)運算,不能用列(行)運算,E為單位矩陣;

Mat矩陣的逆由inv()函數實現:

void main()

{

       Mat m1 = Mat::eye(5,5,CV_32FC1);

       cout<<"m1 = \n "<<m1<<endl;

       Mat m1inv = m1.inv();

       cout<<"m1inv = \n "<<m1inv<<endl;

       system("pause");

}

7.矩陣中非零元素個數:

計算物體的像素或面積常需要用到計算矩陣中的非零元素個數;

OpenCV中使用countNonZero()函數實現。

void main()

{

       Mat m1 = Mat::eye(6,6,CV_32FC1);

       cout<<"m1 = \n "<<m1<<endl;

       int m1num = countNonZero(m1);

       cout<<"m1中非零元素個數 = "<<m1num<<endl;

       system("pause");

}

8.均值和標准差:

OpenCV提供了矩陣均值和標准差計算功能,

使用meanStdDev(src,mean,stddev)函數實現;

src – 輸入矩陣或圖像

mean – 均值,OutputArray

stddev – 標准差,OutputArray

void main()

{

       Mat m1 = Mat::eye(5,5,CV_32FC1);

       cout<<"m1 = \n "<<m1<<endl;

 

       Mat mean,stddev;

       meanStdDev(m1,mean,stddev);

       cout<<"mean = "<<mean<<endl;

       cout<<"stddev = "<<stddev<<endl;

 

       Mat m3(Size(5,5),CV_8UC3,Scalar(255,200,100));

       cout<<"m3 = \n "<<m3<<endl;

       Mat mean3,stddev3;

       meanStdDev(m3,mean3,stddev3);

       cout<<"mean3 = \n "<<mean3<<endl;

       cout<<"stddev3 = \n "<<stddev3<<endl;

       system("pause");

}

  【注】:當src為多通道或多維矩陣時,則函數分別計算不同通道的均值與標准差,因此返回的mean和stddev為對應維度的向量;

9.求矩陣中元素的最大值最小值:

求輸入矩陣的全局最大最小值及其位置,可使用函數:

void minMaxLoc( InputArray src,

CV_OUT double* minVal, 

               CV_OUT double* maxVal=0,

CV_OUT Point* minLoc=0, 

               CV_OUT Point* maxLoc=0,

InputArray mask=noArray()); 

參數:

src – 輸入單通道矩陣(圖像).

minVal – 指向最小值的指針, 如果未指定則使用NULL

maxVal – 指向最大值的指針, 如果未指定則使用NULL

minLoc – 指向最小值位置(2維情況)的指針, 如果未指定則使用NULL

maxLoc – 指向最大值位置(2維情況)的指針, 如果未指定則使用NULL

mask – 可選的蒙版,用於選擇待處理子區域

int main()

{

       Mat img = imread("raw.jpg",0);

       imshow("raw_img",img);

 

       double minVal = 0, maxVal = 0;

       Point minPt,maxPt;

       minMaxLoc(img,&minVal,&maxVal,&minPt,&maxPt);

 

       cout<<"min value = "<<minVal<<endl;

       cout<<"max value = "<<maxVal<<endl;

 

       cout<<"minPt = ("<<minPt.x<<","<<minPt.y<<")"<<endl;

       cout<<"maxPt = ("<<maxPt.x<<","<<maxPt.y<<")"<<endl;

 

       Rect rectMin(minPt.x-50,minPt.y-50,100,100);

       Rect rectMax(maxPt.x-50,maxPt.y-50,100,100);

 

       rectangle(img,rectMin,Scalar(200),2);

       rectangle(img,rectMax,Scalar(255),2);

 

       imshow("image with min max location",img);

       waitKey(0);

       return 0;

}

10.計算矩陣的特征值和特征向量;

正定矩陣(positive definite matrix):矩陣的特征值都是正數;

半正定矩陣(semi-definite matrix):矩陣的特征值都是非負數(正數和0);

判斷矩陣是否正定或者半正定就需要計算矩陣的特征值和特征向量,

使用OpenCV中的eigen()函數進行計算;

#include <opencv2\opencv.hpp>

using namespace std;

using namespace cv;

int main()

{ 

       double myArray[3][3] =

       { 

              2, 1, 0, 

              1, 3, 1, 

              0, 1, 2 

       }; 

 

       Mat myMat = Mat(3, 3, CV_64FC1, myArray);//創建矩陣

       cout << "My Mat: \n " <<myMat<<endl; 

      

       Mat eValuesMat;//特征值 

       Mat eVectorsMat;//特征向量 

    eigen(myMat, eValuesMat, eVectorsMat); 

       cout << "Eigen Values : \n " <<eValuesMat<<endl;   

       cout << "Eigen Vector : \n " <<eVectorsMat<<endl;

       system("pause");

       return 0; 

}  

11.其他矩陣運算:

Function (函數名)                      Use (函數用處)

add:矩陣加法,A+B的更高級形式,支持mask;

scaleAdd:矩陣加法,縮放因子dst(I) = scale * src1(I) + src2(I);

addWeighted:矩陣加法,縮放因子dst(I) = saturate(src1(I) * alpha + src2(I) * beta + gamma);

subtract:矩陣減法,A-B的更高級形式,支持mask;

multiply:矩陣逐元素乘法,同Mat::mul()函數,與A*B區別,支持mask;

gemm:一個廣義的矩陣乘法操作;

divide:矩陣逐元素除法,與A/B區別,支持mask;

abs:對每個元素求絕對值;

absdiff:兩個矩陣的差的絕對值;

exp求每個矩陣元素 src(I) 的自然數 e 的 src(I) 次冪 dst[I] = esrc(I);

pow求每個矩陣元素 src(I) 的 p 次冪 dst[I] = src(I)p;

log求每個矩陣元素的自然數底 dst[I] = log|src(I)| (if src != 0);

sqrt求每個矩陣元素的平方根;

min, max求每個元素的最小值或最大值返回這個矩陣 dst(I) = min(src1(I), src2(I)), max同minMaxLoc定位矩陣中最小值、最大值的位置;

compare返回逐個元素比較結果的矩陣;

bitwise_and, bitwise_not, bitwise_or, bitwise_xor每個元素進行位運算,分別是和、非、或、異或;

cvarrToMat舊版數據CvMat,IplImage,CvMatND轉換到新版數據Mat;

extractImageCOI從舊版數據中提取指定的通道矩陣給新版數據Mat;

randu以Uniform分布產生隨機數填充矩陣,同 RNG::fill(mat, RNG::UNIFORM);

randn以Normal分布產生隨機數填充矩陣,同 RNG::fill(mat, RNG::NORMAL);

randShuffle隨機打亂一個一維向量的元素順序;

theRNG()返回一個默認構造的RNG類的對象,theRNG()::fill(...);

reduce矩陣縮成向量;

repeat矩陣拷貝的時候指定按x/y方向重復;

split多通道矩陣分解成多個單通道矩陣;

merge多個單通道矩陣合成一個多通道矩陣;

mixChannels矩陣間通道拷貝,如Rgba[]到Rgb[]和Alpha[];

sort, sortIdx為矩陣的每行或每列元素排序;

setIdentity設置單元矩陣;

completeSymm矩陣上下三角拷貝;

inRange檢查元素的取值范圍是否在另兩個矩陣的元素取值之間,返回驗證矩陣;

checkRange檢查矩陣的每個元素的取值是否在最小值與最大值之間,返回驗證結果bool;

sum求矩陣的元素和;

mean求均值;

meanStdDev均值和標准差;

countNonZero統計非零值個數;

cartToPolar, polarToCart笛卡爾坐標與極坐標之間的轉換;

flip矩陣翻轉;

transpose矩陣轉置,比較 Mat::t() AT;

trace矩陣的跡;

determinant行列式 |A|, det(A);

eigen矩陣的特征值和特征向量;

invert矩陣的逆或者偽逆,比較 Mat::inv();

magnitude向量長度計算 dst(I) = sqrt(x(I)2 + y(I)2);

Mahalanobis距離計算;

phase相位計算,即兩個向量之間的夾角;

norm求范數,1-范數、2-范數、無窮范數;

normalize標准化;

mulTransposed矩陣和它自己的轉置相乘 AT * A, dst = scale(src - delta)T(src - delta);

convertScaleAbs先縮放元素再取絕對值,最后轉換格式為8bit型;

calcCovarMatrix計算協方差陣;

solve求解1個或多個線性系統或者求解最小平方問題(least-squares problem);

solveCubic求解三次方程的根;

solvePoly求解多項式的實根和重根;

dct, idct正、逆離散余弦變換,idct同dct(src, dst, flags | DCT_INVERSE);

dft, idft正、逆離散傅立葉變換, idft同dft(src, dst, flags | DTF_INVERSE);

LUT查表變換;

getOptimalDFTSize返回一個優化過的DFT大小;

mulSpecturms兩個傅立葉頻譜間逐元素的乘法;

eigen:矩陣的特征值和特征向量

absdiff:兩個矩陣的差的絕對值

minMaxLoc:定位矩陣中最小值、最大值的位置


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM