【转】OpenCV里IplImage数据结构极易出错的问题,IplImage和单字节char*的相互转换
http://blog.csdn.net/liuyi1985/article/details/2174328
http://blog.csdn.net/liuyi1985/article/details/2195364
?對OpenCV稍有了解的同學都知道里邊用于存儲圖像數據的IplImage,其中有兩個屬性非常值得關注,稍不留神就會導致錯誤(后附錯例一則):一是width屬性;二是widthStep屬性。前者是表示圖像的每行像素數,后者指表示存儲一行像素需要的字節數。
????? 在OpenCV里邊,widthStep必須是4的倍數,從而實現字節對齊,有利于提高運算速度。如果8U單通道圖像寬度為3,那么widthStep是4,加一個字節補齊。這個圖像的一行需要4個字節,只使用前3個,最后一個空著。也就是一個寬3高3的圖像的imageData數據大小為4*3=12字節。
????? 需要注意的是,空著的那個像素并不是無效的,它仍然可以被操作,這就是導致錯誤的根源。
????? 錯例:
????? 假如現在有一個char* data的指針指向一個15*15的灰度圖像的數據起始地址,我們想把圖像數據通過cvShowImage函數顯示出來,比較直觀的一種做法如下:
......IplImage*?image?=?cvCreateImage(cvSize(15,?15),?8,?1);
memcpy(image->imageData,?data,?15*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 + 15*i,?15);
}
????? 這樣,程序才能按我們的設想運行。
OpenCV中IplImage和單字節char*的相互轉換
?IplImage和單字節char*之間相互轉換的正確、簡潔的方法:
????? 已知 IplImage* image 和 char* data
????? 從 IplImage 到 char* :
data?=?image->imageData?//對齊的圖像數據????? 或者
data?=?image->imageDataOrigin?//未對齊的原始圖像數據????? 從 char* 到 IplImage :
image?=?cvCreateImageHeader(cvSize(width,height),?depth,?channels);cvSetData(image,?data,?step);
????? step指定IplImage圖像每行占的字節數。需要注意是,在釋放空間時不能直接使用cvReleaseImage,而需cvReleaseImageHeader,然后再delete data,這也是OpenCV里邊“自己管理內存”的思想。
????? 附《Intel image processing library》文檔中關IplImage的聲明(非OpenCV版):
typedef?struct?_IplImage?...{????int?nSize?/**//*?size?of?iplImage?struct?*/
????int?ID?/**//*?image?header?version?*/
????int?nChannels;
????int?alphaChannel;
????int?depth;?/**//*?pixel?depth?in?bits?*/
????char?colorModel[4];
????char?channelSeq[4];
????int?dataOrder;
????int?origin;
????int?align;?/**//*?4-?or?8-byte?align?*/
????int?width;
????int?height;
????struct?_IplROI?*roi;?/**//*?pointer?to?ROI?if?any?*/
????struct?_IplImage?*maskROI;?/**//*pointer?to?mask?ROI?if?any?*/
????void?*imageId;?/**//*?use?of?the?application?*/
????struct?_IplTileInfo?*tileInfo;?/**//*?contains?information?on?tiling?*/
????int?imageSize;?/**//*?useful?size?in?bytes?*/
????char?*imageData;?/**//*?pointer?to?aligned?image?*/
????int?widthStep;?/**//*?size?of?aligned?line?in?bytes?*/
????int?BorderMode[4];?/**//*?the?top,?bottom,?left,?and?right?border?mode?*/
????int?BorderConst[4];?/**//*?constants?for?the?top,?bottom,?left,?and?right?border?*/
????char?*imageDataOrigin;?/**//*?ptr?to?full,?nonaligned?image?*/
}?IplImage; 分享到:
轉載于:https://www.cnblogs.com/justiner/archive/2011/12/07/2278829.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的【转】OpenCV里IplImage数据结构极易出错的问题,IplImage和单字节char*的相互转换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HttpWebRequest WebRe
- 下一篇: windows phone7---MVV