[問題] opencv實作FFT convolution影像位移

看板C_and_CPP (C/C++)作者 (lyalyalya)時間11年前 (2015/04/11 15:17), 編輯推噓1(106)
留言7則, 2人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) VC++ 2008 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) Opencv 問題(Question): 我要做image與kernel的convolution, 因為在spatial domain跑太慢, 於是找到可以用FFT來加速, 但是我做了幾個實驗,idft回spatial domain後影像都會出現位移, 因為對frequency domain很不熟,想請教是哪邊出問題了? 謝謝。 餵入的資料(Input): 實驗一: 我用Mat(3,3)=(1,0,1 0,1,0 1,0,1) 和Mat(1,2)=(1,-1) 簡單測試水平梯度的計算。 ----------------------------- 實驗二: 我用實際灰階影像跟Mat(1,2)=(1,-1)做convolution。 --------------------------------- 實驗三: 用實際影像和複雜的kernel帶入algorithm做FFT convolution。 預期的正確結果(Expected Output): 實驗一: 預期結果為( 1,-1, 1 -1, 1, 0 1,-1, 1) spatial domain預期邊緣為右邊補0,所以最後邊一排數值不變。 -------------------------------------------------------- 實驗二: 預期為正確的水平梯度圖。 -------------------------- 實驗三: 預期為正確的convolution影像。 錯誤結果(Wrong Output): 實驗一: 實際結果為( 1,-1, 1 0, 1,-1 1,-1, 1) 上面的1有些有些微小數誤差,中間那排0跟-1和預期結果相反, 由於FFT好像有週期性,在想是不是週期導致的位移? ------------------------------------------------------- 實驗二: http://imgur.com/RMt0Rok
如圖所示,可以看到最左邊的一個column的值還是灰階影像的值, 而沒有被convolution運算到。 ------------------------------------------------------- 實驗三: http://imgur.com/bMfca83
圖片為使用getOptimalDFTSize()的convolution結果, 之後會將正確的size用Rect(0,0,Img.rows,Img.cols)切回來, 可以看出有一排row跟col跑掉了, 導致我切回來後影像往左上位移了一個pixel, 而最右下的row跟col則會變為一條值為0的填補區域。 程式碼(Code):(請善用置底文網頁, 記得排版) 大致步驟為: 1.使用getOptimalDFTSize(Img.rows+kernel.rows-1) getOptimalDFTSize(Img.cols+kernel.cols-1) //這邊的大小是看書上寫的最佳大小,我測試過只要大於上面的大小,實驗結果都一樣 這邊的問題是: 我的演算法裡會有不只兩個Mat在頻率域裡運算, 大小是都調整成這樣就可以嗎?(找到的資料都只有兩個MAT做運算,沒有多個MAT的) 2.用copyMakeBorder()加邊框 這邊我看別人都將邊框加在影像右下,本來以為位移是因為這裡, 但是我改成邊框加在影像周圍結果還是一樣。 3.設MAT[2]={Img,Zero()}存實數虛數。 4.merge成雙通道影像。 5.dft轉成頻率域。 6.algorithm的計算,實驗一和二單純用mulSpectrums()進行convolution 實驗三有代其他加減乘除運算,皆有考慮到複數的問題。 7.idft回空間域。 8.用normalize()將值域縮成(0-1)之間,之後影像在同乘255並show出來 (這步不確定要不要做,因為做了會導致整張影像偏亮,但是不做又會有負值) -------------------------------------------------------------------------- 實驗結果就如同上面所示, 都會有位移的問題, 因為我不太懂頻率域的運算方式, 想請問各位大大,我是哪個步驟沒有考慮到嗎? 謝謝。 補充說明(Supplement): 我對頻率的知識有點差,可能有很多觀念錯誤,請多包涵,謝謝各位。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 163.13.127.22 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1428736666.A.5C2.html

04/11 23:15, , 1F
之前學的時候再fft前要shift 但我不確定opencv的idft
04/11 23:15, 1F

04/11 23:15, , 2F
是怎樣的..
04/11 23:15, 2F

04/12 13:05, , 3F
我看到的是說shift是為了show頻率圖出來時比較好看
04/12 13:05, 3F

04/12 13:05, , 4F
沒shift頻率會在四個角落 所以把它shift到中間
04/12 13:05, 4F

04/12 13:07, , 5F
我沒有要show頻率圖 所以沒shift就直接idft回空間域了
04/12 13:07, 5F

04/12 13:08, , 6F
opencv單純代公式轉回來而已 shift的話要自己寫
04/12 13:08, 6F

04/12 13:09, , 7F
我看別人是都切四塊對角線對調
04/12 13:09, 7F
文章代碼(AID): #1LACgQN2 (C_and_CPP)
文章代碼(AID): #1LACgQN2 (C_and_CPP)