最近利用做項目,遇到了一個問題:我是用opencv讀的映像,然後自己新開闢了一個空間,以下是代碼
Byte *inputImage=NULL;
IplImage* image_get=NULL;
image_get=cvLoadImage(imageName,0);
imageWidth=image_get->width;
imageHeight=image_get->height;
inputImage=new Byte(imageHeight * imageWidth);
inputImage=image_get->imageData;
這時候出問題了。我給inputimage分配的是一個imageHeight * imageWidth的空間,然而,讀入的映像為800*600的時候還沒問題
當為801*601的時候發現處理出來的結果不是那麼回事了。後來查看發現image_get裡面的widthstep為804,而不是801.這才開始尋找問題
以下是引用的別人的文章:解決此問題。
OpenCV裡IplImage資料結構極易出錯的問題
對OpenCV稍有瞭解的同學都知道裡邊用於儲存映像資料的IplImage,其中有兩個屬性非常值得關注,稍不留神就會導致錯誤(後附錯例一則):
一是width屬性;二是widthStep屬性。
前者是表示映像的每行像素數,後者指表示儲存一行像素需要的位元組數。
在OpenCV裡邊,widthStep必須是4的倍數,從而實現位元組對齊,有利於提高運算速度。
如果8U單通道映像寬度為3,那麼widthStep是4,加一個位元組補齊。這個映像的一行需要4個位元組,只使用前3個,最後一個空著。
也就是一個寬3高3的映像的imageData資料大小為4*3=12位元組。
需要注意的是,空著的那個像素並不是無效的,它仍然可以被操作,這就是導致錯誤的根源。
範例:
錯例: 假如現在有一個char* data的指標指向一個17*15的灰階映像(17列,15行)的資料起始地址,我們想把映像資料通過cvShowImage函數顯示出來,比較直觀的一種做法如下:
...... IplImage* image = cvCreateImage(cvSize(17, 15), 8, 1);
memcpy(image->imageData, data, 17*15);
cvNamedWindow("window");
cvShowImage("window", image);
cvWaitKey();
cvReleaseImage(&image);
cvDestroyWindow("window"); ......
你會發現,顯示的映像奇怪的往左下角歪過去了。
當你看完這篇文章後希望不要再因為這個問題浪費你的時間了(shamed:這個問題鬱悶了我整整一天)。
其實原因就在於,在cvCreateImage的時候,OpenCV為實現位元組對齊,使得每行資料實際有16個位元組(多出一個),在使用memcpy的過程中,這些多出的位元組就把對應的資料給“吃”了,因為這些資料在cvShowImage的時候並不會顯示出來,這樣,第二行就少一個位元組,第三行少兩個位元組,……,所以整個映像就偏向左下角了!
知道這一點後可以將memcpy語句更改如下:
for(int i = 0; i<15; i++){ memcpy(image->imageData + image->widthStep*i, data + 17*i, 17); }
這樣,程式才能按我們的設想運行。
註:如果是16bit資料,則每行資料大小需*2,即“data + 17*i*2, 17*2
Fr:http://blog.csdn.net/yihandk666/article/details/6960671