IplImage資料結構的操作
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
int Dims;
int Height;
int Width;
int COIChannel;
int main()
{
IplImage *Image1;
CvRect Rect1,Rect2;
uchar *ptr1;
CvSize Size1;
CvScalar Scalar1;
Image1=cvLoadImage("bower.jpg",1);
Dims=cvGetDims(Image1,0);
Height=cvGetDimSize(Image1,0);
Width=cvGetDimSize(Image1,1);
Rect1=cvRect(140,305,115,165);
cvSetImageCOI(Image1,1);
cvSetImageROI(Image1,Rect1);
COIChannel=cvGetImageCOI(Image1);
Rect2=cvGetImageROI(Image1);
Size1=cvGetSize(Image1);
ptr1=cvPtr2D(Image1,50,40);
Scalar1=cvGet2D(Image1,50,40);
printf("pic ROI Information==\n");
printf("Dims is : %d\n",Dims);
printf("Height is : %d\n",Height);
printf("Width is : %d\n",Width);
printf("Set COI is : %d\n",COIChannel);
printf("ROI Size is : (%d,%d)\n\n",Size1.height,Size1.width);
printf("The Pointer 2D (50,40)Channels is : %d %d %d\n",*ptr1,*(ptr1+1),*(ptr1+2));
printf("The Scalar 2D (50,40) Channels is : %.1f %.1f %.1f\n",Scalar1.val[0],Scalar1.val[1],Scalar1.val[2]);
cvSet2D(Image1,50,40,cvScalar(255,255,255));
printf("The Pointer 2D (50,40)Channels is : %d %d %d\n",*ptr1,*(ptr1+1),*(ptr1+2));
cvNamedWindow("Bower ROI",1);
cvShowImage("Bower ROI",Image1);
cvResetImageROI(Image1);
cvNamedWindow("Bower",1);
cvShowImage("Bower",Image1);
cvWaitKey(0);
}
原始圖片:

執行結果:
一開始,開啟圖檔設定給ROI的CvRect資料結構大小空間,用cvSetImageCOI()設定感興趣的顏色(Color Of Interesting)設定為通道一,藍色,用cvSetImageROI()選定感興趣的區域而相對的,cvGetImageCOI()跟cvSetImageROI()則是取得資訊,cvGetDims()為取得維度,因為是圖片,所以當然是二維,再來是取得寬跟高,它也可以使用cvGetSize()取得CvSize資料結構的寬跟高資訊,cvPtr2D()是用指標的方式取得圖片座標位置,並且數據為通道一,藉由指標運算+1的方式如*(ptr1+1),可以取得通道二,通道三...由於取得的是指標位置,所以可以直接對它做直接修改數值,而cvGet2D()是傳值呼叫,必須要對它做cvSet()2D才能完成存取的動作,這是物件導向裡很基本Get跟Set的概念,而後面就直接用指標*ptr1得方式直接printf()修改的值出來,最後的部份cvResetImageROI()將ROI重置,因此就還原成原來的圖片了,值得注意的是,這邊修改了其中的一個點,而重置後,被修改的點的部份仍然不會恢復原狀,ROI只是對圖形做平移及縮小檢視範圍罷了.另一個比較重要的部份cvPtr2D()輸出為uchar *型別,cvGet2D()為CvScalar資料結構,在存取的時候千萬不能搞錯了,尤其是cvPtr2D()這個函式.
在OpenCV對IplImage資料結構的操作是很隨意的,很多函式甚至可以直接跟CvMat資料結構共用,但實際上,這是危險的,OpenCV的開發沒有做到降低程式設計的耦合性,也因為IplImage跟CvMat所使用的副程式及變數是有衝突,對於那些共用的副程式的回傳值套用在兩個不同的資料結構上,對使用者來講會有凌亂的困擾,但是它仍是有優點,它會比一些被封裝整理過的程式快一些,這仍會是個事實.
cvSetImageCOI()
設定感興趣的顏色(Color Of Interesting),第一個引數為IplImage資料結構,第二個引數為通道數據,如果為0表示不設立
cvSetImageCOI(IplImage資料結構,通道數據)
cvSetImageROI()
設定感興趣的區域(Region Of Interesting),第一個引數為IplImage資料結構,第二個引數為CvRect選取的區域大小.
cvSetImageROI(IplImage資料結構,RvRect區塊資料結構)
cvGetImageCOI()
取得圖形設定COI數據.
cvGetImageCOI(IplImage資料結構)
cvGetImageROI()
取得圖形ROI數據
cvGetImageROI(IplImage資料結構)
cvResetImageROI()
重置圖形ROI,也就是將CvRect所選定的區域取消掉,但是CvRect區域內修改的值不會被復原.
cvResetImageROI(IplImage資料結構)
cvGetDims()
取得維度資訊,這邊可以跟IplImage,CvMat共用,當然,圖片一定是二維陣列
cvGetDims(IplImage資料結構或CvMat資料結構)
cvGetDimSize()
取得IplImage圖形或CvMat矩陣的空間大小數據0為高(height)/列(row),數據1為寬(width)/欄(colunm)
cvGetDimSize(IplImage資料結構或CvMat資料結構,空間大小代號)
cvGetSize()
取得IplImage圖形或CvMat矩陣的空間大小,回傳值是CvSize資料結構.
cvGetSize(IplImage資料結構或CvMat資料結構)
cvPtr2D()
取得二維空間的座標值,此為一整串的函式之一,包括有
cvPtr1D()
cvPtr2D()
cvPtr3D()
cvPtrND()
3D跟ND則不能用IplImage及CvMat實作,這系列函數回傳值都是uchar *型別的記憶體位址,利用指標+1,+2,+3可以選擇其他通道
cvPtr2D(IplImage資料結構或CvMat資料結構,X軸座標數據,Y軸座標數據)
cvPtr1D()
取得一維空間的座標值,回傳值為uchar *記憶體位址,也可以用來取得二維陣列座標值(因為IplImage,CvMat資料結構都是由一維陣列組合而成的),但是不建議用一維函式去實作二,三維空間只是增加程式設計得難度及降低可讀性
cvPtr1D(IplImage資料結構或CvMat資料結構,一維陣列Index數據)
cvGet2D()
取得二維空間的純量值(CvScalar),亦為一整串的函式之一,其中包括有
cvGet1D()
cvGet2D()
cvGet3D()
cvGetND()
3D及ND不支援IplImage資料結構及CvMat,回傳值皆為CvScalar資料結構,對應cvSet*D()系列函數.
cvGet2D(IplImage資料結構或CvMat資料結構,X軸座標數據,Y軸座標數據)
cvGet1D()
取得IplImage資料結構及CvMat資料結構一維空間的純量值(CvScalar),可以用來取得二維陣列座標值,但不建議二維陣列用cvGet1D()實作.
cvGet1D(IplImage資料結構或CvMat資料結構,一維陣列Index數據)
cvSet2D()
為cvGet*D()系列的對應,也為一整串函式之一,其中包括
cvSet1D()
cvSet2D()
cvSet3D()
cvSetND()
為設定IplImage,CvMat純量數據之用途.
cvSet2D(IplImage資料結構或CvMat資料結構,X軸座標數據,Y軸座標數據,CvScalar資料結構)
cvSet1D()
設定IplImage資料結構及CvMat資料結構一維空間的純量值(CvScalar),可以用來取得二維陣列座標值,但不建議二維陣列用cvSet1D()實作.
cvSet1D(IplImage資料結構或CvMat資料結構,一維陣列Index數據,CvScalar資料結構)
2 意見:
,cvGetImageCOI()跟cv"S"etImageROI()則是取得資訊
"筆誤"?
cvGet2D和cvSet2D
的x,y座標要交換
張貼留言