看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《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:http://opencv.itseez.com/trunk/ 03/20 00:12
diabloevagto:Tutorials裡面有很多範例 03/20 00:12