簡單線性映射實作
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
void PrintMatrix(CvMat *Matrix,int Rows,int Cols,int Channels);
float Array1[]={4,1,0,2,1,1,3,2,1,1,4,1.5};
float Array2[]={2,1,2};
int main()
{
CvMat *A=cvCreateMat(4,3,CV_32FC1);
CvMat *x=cvCreateMat(1,1,CV_32FC3);
CvMat *T_x=cvCreateMat(1,1,CV_32FC4);
cvSetData(A,Array1,A->step);
cvSetData(x,Array2,x->step);
cvTransform(x,T_x,A);
PrintMatrix(T_x,T_x->rows,T_x->cols,4);
system("pause");
}
void PrintMatrix(CvMat *Matrix,int Rows,int Cols,int Channels)
{
for(int i=0;i<Rows;i++)
{
for(int j=0;j<Cols;j++)
{
for(int k=0;k<Channels;k++)
{
printf("%.2f ",cvGet2D(Matrix,i,j).val[k]);
}
}
printf("\n");
}
}
執行結果:
A矩陣則是叫轉移矩陣(Transition Matrix),可以專門在做基底座標變換的運用,這邊要特別注意的是,cvTransform()它拿通道來代替向量,而不是拿矩陣來代替向量,事實上,矩陣也可以作為向量的表達,但不適用於cvTransform().這邊cvTransform()輸入,x矩陣為通道三,而A則一定要輸入通道一的矩陣,輸出的T_x矩陣為通道四,而對於一個向量而言,此種運算方式叫做線性映射,如果對於一個矩陣圖形的話,則叫做矩陣變換(Matrix Transformation).
矩陣變換的部分,就拿RGB轉YCbCr的公式來實作,跟前面的線性映射不同的是,它直接拿通道三的矩陣來做色彩空間的轉換.
RGB轉YCbCr實作
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
float Array1[]={0.2989,0.5867,0.1140,-0.1687,-0.3312,0.5,0.5,-0.4183,-0.0816};
float Array2[]={0,128,128};
int main()
{
CvMat *TransitionMatrix=cvCreateMat(3,3,CV_32FC1);
CvMat *ShiftVector=cvCreateMat(3,1,CV_32FC1);
IplImage *Image1=cvLoadImage("MineCar.jpg",1);
IplImage *GrayImage1=cvLoadImage("MineCar.jpg",0);
IplImage *YCbCrImage1=cvCreateImage(cvGetSize(Image1),IPL_DEPTH_8U,3);
IplImage *YImage=cvCreateImage(cvGetSize(Image1),IPL_DEPTH_8U,1);
IplImage *CbImage=cvCreateImage(cvGetSize(Image1),IPL_DEPTH_8U,1);
IplImage *CrImage=cvCreateImage(cvGetSize(Image1),IPL_DEPTH_8U,1);
cvSetData(TransitionMatrix,Array1,TransitionMatrix->step);
cvSetData(ShiftVector,Array2,ShiftVector->step);
cvTransform(Image1,YCbCrImage1,TransitionMatrix,ShiftVector);
cvSplit(YCbCrImage1,YImage,CbImage,CrImage,0);
cvNamedWindow("YImage",1);
cvShowImage("YImage",YImage);
cvNamedWindow("GrayImage",1);
cvShowImage("GrayImage",GrayImage1);
cvWaitKey(0);
}
原始圖片:

執行結果:
由上面線性映射的基礎來對一個通道三個圖形做矩陣變換,這邊將RGB的圖片藉由公式轉成YCbCr的格式,這個部分就叫做色彩空間的轉換,Y代表的是亮度,也就是灰階值,Cb則是藍色的色差,Cr則為紅色的色差,因此,這邊直接拿cvLoadImage()讀取灰階圖形來跟Y值圖形來做比較.中間有用到通道分割的函式cvSplit()則是要參考前面資料結構"通道的分割,合併與混合"的部份,cvTransform()的第四個引數則是對轉移矩陣計算後的數值結果做平移的運算.
cvTransform()
將圖形或矩陣做矩陣變換,矩陣變換的向量維度是以通道為基礎,也就是轉移矩陣會對通道向量做相乘而完成色彩空間的轉換,第四個引數則是對計算結果的向量做位移的調整,而轉移矩陣的m*n大小可以決定輸出通道的維度,這邊m代表輸入通道數,n代表輸出通道數.
cvTransform(輸入CvMat或IplImage資料結構,輸出CvMat或IplImage資料結構,CvMat轉移矩陣資料結構,CvMat平移向量資料結構)
1 意見:
IplImage 的色彩格式應該是BGR,可是這邊卻沒有轉換成RGB就直接相乘,這樣的原因在哪??不太懂,謝謝!!
張貼留言