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...