opencv IplImage的資料結構

2021-07-29 17:18:47 字數 1687 閱讀 7966

iplimage的結構如下

typedef

struct _iplimage

iplimage;

對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++)

這樣,程式才能按我們的設想執行。

iplimage和單位元組char*之間相互轉換的正確、簡潔的方法:

已知 iplimage* image 和 char* data

從 iplimage 到 char* :

data = image->imagedata //對齊的影象資料

或者image->imagedataorigin //未對齊的原始影象資料

從 char* 到 iplimage :

image = cvcreateimageheader(cvsize(width,height), depth, channels);

cvsetdata(image, data, step);

step指定iplimage影象每行佔的位元組數。需要注意是,在釋放空間時不能直接使用cvreleaseimage,而需cvreleaseimageheader,然後再delete data,這也是opencv裡邊「自己管理記憶體」的思想。

container of 的的的原理

另外一篇,同樣精彩,揭開linux核心中container of的神秘面紗 華清遠見嵌入式學院講師。在linux 核心中有乙個大名鼎鼎的巨集container of 這個巨集是用來幹嘛的呢?我們先來看看它在核心中是怎樣定義的。呵呵,乍一看不知道是什麼東東。我們先來分析一下container of p...

存在的就是合理的,發生的即是必然的。

筆者有時候會想,什麼是對,什麼是錯?對於追求某一件事情之前首先會考慮,為什麼我要做這件事情。所以經過自我分析和生活周邊環境的總結。我認為,對於乙個人來,這是在站在個體的角度上說。什麼是對的?就是你自己覺得是對的,它就是對的。不過這個只是你自己的想法。主觀上的正確,不代表客觀上也受到了別人的認可。就拿...

Apache的rewrite的重寫相關的引數

apache mod rewrite規則重寫的標誌一覽 使用mod rewrite時常用的伺服器變數 rewriterule規則表示式的說明 匹配任何單字元 chars 匹配字串 chars chars 不匹配字串 chars text1 text2 可選擇的字串 text1或text2 匹配0到1...