圖形空間的算數運算
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
int main()
{
CvCapture *capture;
IplImage *frame,*frame1,*frame2;
frame1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
frame2=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
capture =cvCaptureFromCAM(0);
cvNamedWindow("Webcam",0);
while(true)
{
frame = cvQueryFrame(capture);
cvSub(frame,frame1,frame2);
cvAdd(frame2,frame,frame2);
cvFlip(frame2,frame2,0); // frame2->origin=1;
cvShowImage("Webcam",frame2);
if(cvWaitKey(10)>=0) break;
printf("%d",frame->origin);
printf("%d",frame2->origin);
cvCopy(frame,frame1);
}
cvReleaseCapture(
&
capture);cvReleaseImage(
&
frame1);cvReleaseImage(
&
frame2);cvDestroyWindow("Webcam");
}
上面的程式可好玩多了,執行後會製造出殘像的效果,由於前一張frame減後一張frame,所製造出來的差異再跟原始影像做相加,因此影像會因為運動後而產生差異,對於影像的相減及相加,由於uchar格式的圖片範圍界在0~255之間,因此全部的最小值會為0,最大值會為255,不會有負號的存在,它會自動變為0,因此,對於連續影像的運算不適合uchar的型別,可以用前面型別轉換的方式,或是把它轉成RGB三個float型別的二維陣列自己做連續影像的計算.而這邊cvQueryFrame()所擷取的視訊圖片為上下顛倒的圖形影像,跟cvCreateImage()創造出來的圖像是相反的,解決的方法是把origin設為1,或是用cvFlip()來做圖形的翻轉.origin的部份可以參考前面IplImage資料結構介紹的部份.
矩陣空間的算數運算
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
float MatrixData1[]={1,2,3,4,5,6,7,8,9};
float MatrixData2[]={8,7,6,5,4,3,2,1,0};
float MatrixData3[9];
void PrintMatrix(CvMat *Matrix);
int main()
{
CvMat Matrix1=cvMat(3,3,CV_32FC1,MatrixData1);
CvMat Matrix2=cvMat(3,3,CV_32FC1,MatrixData2);
CvMat Matrix3=cvMat(3,3,CV_32FC1,MatrixData3);
printf("\nMatrix Add:\n");
cvAdd(
&
Matrix1,&
Matrix2,&
Matrix3);PrintMatrix(
&
Matrix3);printf("\nMatrix Sub:\n");
cvSub(
&
Matrix1,&
Matrix2,&
Matrix3);PrintMatrix(
&
Matrix3);printf("\nMatrix Mul:\n");
cvMul(
&
Matrix1,&
Matrix2,&
Matrix3,2);PrintMatrix(
&
Matrix3);printf("\nMatrix Div:\n");
cvDiv(
&
Matrix1,&
Matrix2,&
Matrix3,3);PrintMatrix(
&
Matrix3);printf("\nMatrix AddS:\n");
cvAddS(
&
Matrix1,cvRealScalar(4),&
Matrix3);PrintMatrix(
&
Matrix3);printf("\nMatrix SubS:\n");
cvSubS(
&
Matrix1,cvRealScalar(5),&
Matrix3);PrintMatrix(
&
Matrix3);printf("\nMatrix SubRS:\n");
cvSubRS(
&
Matrix1,cvRealScalar(2),&
Matrix3);PrintMatrix(
&
Matrix3);printf("\nMatrix SubRS:\n");
cvScaleAdd(
&
Matrix1,cvRealScalar(3),&
Matrix2,&
Matrix3);PrintMatrix(
&
Matrix3);printf("\nMatrix AddWeighted:\n");
cvAddWeighted(
&
Matrix1,2,&
Matrix2,-4,5,&
Matrix3);PrintMatrix(
&
Matrix3);system("pause");
}
void PrintMatrix(CvMat *Matrix)
{
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
printf("%.1f ",cvGet2D(Matrix,i,j).val[0]);
}
printf("\n");
}
}
執行結果:
上面的程式是矩陣所有加減乘除的函式,而乘跟除不是標準矩陣運算,矩陣運算的部份就要參考後面線性代數的地方,上面cvAdd(),cvAddS(),cvSub(),cvSubS()cvSubRS()都具有Mask遮罩的功能,遮罩的部份也是會在後面詳細敘述,以下為各算數運算的計算方式
1.cvAdd(
&
Matrix1,&
Matrix2,&
Matrix3)2.cvSub(
&
Matrix1,&
Matrix2,&
Matrix3)3.cvMul(
&
Matrix1,&
Matrix2,&
Matrix3,2)4.cvDiv(
&
Matrix1,&
Matrix2,&
Matrix3,3)5.cvAddS(
&
Matrix1,cvRealScalar(4),&
Matrix3)6.cvSubS(
&
Matrix1,cvRealScalar(5),&
Matrix3)7.cvSubRS(
&
Matrix1,cvRealScalar(2),&
Matrix3)8.cvScaleAdd(
&
Matrix1,cvRealScalar(3),&
Matrix2,&
Matrix3)9.cvAddWeighted(
&
Matrix1,2,&
Matrix2,-4,5,&
Matrix3)5~7的S代表的就是全1矩陣的純量積(Scalar multiplication).
cvAdd()
矩陣加法運算,適用於IplImage及CvMat資料結構,輸入跟輸出資料結構必須同類型,同大小,同型別,具有遮罩的功能.
cvAdd(輸入IplImage或CvMat結構,輸入IplImage或CvMat結構,輸出IplImage或CvMat結構,IplImage資料結構目標Mask區域)
cvSub()
矩陣減法運算,適用於IplImage及CvMat資料結構,輸入跟輸出資料結構必須同類型,同大小,同型別,且具有遮罩的功能.
cvAdd(輸入IplImage或CvMat結構,輸入IplImage或CvMat結構,輸出IplImage或CvMat結構,IplImage資料結構目標Mask區域)
cvMul()
矩陣內部乘法運算,非一般矩陣乘法,具有兩個IplImage或CvMat資料結構矩陣輸入,一個純量輸入及一個矩陣輸出,輸入跟輸出資料結構必須同類型,同大小,同型別.
cvMul(輸入IplImage或CvMat結構,輸入IplImage或CvMat結構,輸出IplImage或CvMat結構,純量數據)
cvDiv()
矩陣內部除法運算,非一般矩陣運算,具有兩個IplImage或CvMat資料結構矩陣輸入,一個純量輸入及一個矩陣輸出,輸入跟輸出資料結構必須同類型,同大小,同型別.
cvADiv(輸入IplImage或CvMat結構,輸入IplImage或CvMat結構,輸出IplImage或CvMat結構,純量數據)
cvAddS()
目標矩陣與全1矩陣的純量積加法,也就是矩陣內全部數據加某數,第一個引數為IplImage資料結構或CvMat資料結構,第二個為CvScalar資料結構,因此可支援多通道,第三個為輸出資料結構,輸入跟輸出資料結構必須同類型,同大小,同型別.
cvAddS(輸入IplImage或CvMat結構,CvScalar資料結構,輸出IplImage或CvMat結構)
cvSubS()
目標矩陣與全1矩陣的純量積減法,也就是矩陣內全部數據減去某數,第一個引數為IplImage資料結構或CvMat資料結構,第二個為CvScalar資料結構,第三個為輸出資料結構,輸入跟輸出資料結構必須同類型,同大小,同型別.
cvSubS(輸入IplImage或CvMat結構,CvScalar資料結構,輸出IplImage或CvMat結構)
cvSubRS()
全1矩陣的純量積減目標矩陣,也就是矩陣內全部數據加負號加上某數,第一個引數為IplImage資料結構或CvMat資料結構,第二個為CvScalar資料結構,因此可支援多通道,第三個為輸出資料結構,輸入跟輸出資料結構必須同類型,同大小,同型別.
cvSubRS(輸入IplImage或CvMat結構,CvScalar資料結構,輸出IplImage或CvMat結構)
cvScaleAdd()
第一個輸入矩陣的純量積加上第二個輸入矩陣,第一個引數為IplImage資料結構或CvMat資料結構,第二個為CvScalar資料結構,因此可支援多通道,第三個為欲加上的矩陣資料結構,第四個為輸出資料結構,輸入跟輸出資料結構必須同類型,同大小,同型別.
cvSubRS(輸入IplImage或CvMat結構,CvScalar資料結構,輸入IplImage或CvMat結構,輸出IplImage或CvMat結構)
cvAddWeighted()
主要的方式是以權重去分配每個矩陣的比值,分別為第一個矩陣純量積加上第二個矩陣純量積加上全1矩陣純量積,這邊只能做單通道的運算.
cvSubRS(輸入IplImage或CvMat結構,double型別純量數據,輸入IplImage或CvMat結構double型別純量數據,double型別純量數據,輸出IplImage或CvMat結構)
4 意見:
文中的函数cvAdd()应该改为cvAdd(frame2,frame,frame);才能实现。作者笔误了吧 :-)
為何會有cvCopy' : too few actual parameters
一樓講錯囉
我們要輸出的是frame2
張貼留言