作者elfkiller (沒有暱稱)
看板C_and_CPP
標題Re: [問題] 灰階圖片的width和widthstep
時間Mon Mar 19 22:31:54 2012
※ 引述《Arim (Arim5566)》之銘言:
: 想藉這個標題問一下,由於最近使用opencv做影像處理的時候也碰到這個問題
: 以一個3*3的3 channel(RGB)來說的話,
: 每一行的byte數目總共為12個byte,其中為了要使得其為4的倍數所以後面多補了3個byte
: 因此widthstep=12
: 但是這多出來的3個byte再做處理的時候並不會用到,只是要對齊用的
: 而一般來說
: 如果想要對一張影像的每個像素做處理的話
: opencv的作法會是
: for (int i = 0; i < height;i++)
: for (int j = 0; j < widthStep; j++) {
: Img->imageData[i*widthStep+j]=0; //將整張圖用1-dim的方式表示
: }
: 但是上面的程式碼卻不適用於3*3的影像,因為會出現index out of range
: 不知道是不是因為imageData並不會包含被align所多出來的byte???
: 但是我不懂為什麼我的index還是可以是i*widthStep+j ??
: 因為只要把第二個for迴圈的widthStep改成width,結果又正確了...
這樣就ok了
不需要用到下面的寫法
: 而我的想法是
: 如果要改成4*4(不會有byte多出來)以及3*3(會有byte多出來)的影像都適用的話
: 應該要把上述的程式碼改成
: for (int i = 0; i < height;i++)
: for (int j = 0; j < widthStep-(widthStep-width*nchannel); j++) {
: Img->imageData[i*widthStep+j]=0; //將整張圖用1-dim的方式表示
: }
: 其中 widthStep-width*nchannel=因為align而多出來的byte
: 也就是widthStep-(多出來的byte)=真正的ImageData
: 但是我在網路上沒看過有這樣的寫法@@,幾乎都是第1種居多
: 執行結果看起來是沒問題的
: 不知道我這樣的寫法是否正確?
其實沒這麼複雜......
widthStep是一列共幾byte
所以i*widthStep就是前面幾列所佔的總byte數
+j就是這一列的第幾個(j < width)
考慮通道數可以寫成這樣
+channel*j + ?
以三通道為例
就是3j (B), 3j+1 (G), 3j+2 (R)
OpenCV有時候會需要做一次跳多byte的舉動
例如使用cvSobel(), type是int16
細節我忘了
可以寫成這樣的形狀:
((int16*)Img->imageData)[i*(widthStep/sizeof(int16)) + channel*j + ?]
簡單的說就是一次跳兩格......你在第幾格?
widthStep/sizeof(int16)可以在迴圈外先算好
另外OpenCV內建的讀Pixel函式速度是不會輸給這樣讀取的速度
甚至比較快, 因為有最佳化(我不是很確定)?
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 223.138.221.136
推 johnlinvc:cvGet2D & cvSet2D 比pointer慢但cv::mat的iterator 03/19 23:20
→ johnlinvc:和pointer就差不多了,CV2.2 以後官方推薦用cv::Mat 03/19 23:24
推 Arim:請問要怎麼學opencv或其他函式庫呢? 看原始碼跟文件嘛? 03/20 00:01
→ diabloevagto:Tutorials裡面有很多範例 03/20 00:12