各位大大好,
小弟主修是影像處理,對於頻率域非常不熟,
但是最近在做影像的convolution時需要用到FFT,
爬了很多文依然失敗,因此想上來請教,
問題如下:
假設一張影像I跟遮罩k要做convolution,
空間上模糊影像 B = I * k,
因為影像與遮罩都很大,我需要將它轉換到頻率域計算,
頻率域上F(B) = F(I) o F(k),
空間的convolution = 頻率的點乘,
而因為點乘大小必須相同,但是I和k的大小不同,所以會在MAT的右下補0,
(通常FFT會補到2的倍數)
問題1:
我看到一個範例是做水平梯度fx=[1 -1],
它在轉換時使用 otfFx = pst2otf(fx,[SIZE(m,n)]),
就我的了解與測試,它是將fx的右下先補0,然後對原本的大小做circshift,最後轉FFT2,
請問這邊的shift是為了讓kernel的中心與影像的(0,0)對齊,以方便做點乘嗎?
(我有試過沒做circshift,轉回來會位移)
問題二:
陳上,假設我的kernel是2D,我一樣要先circshift才能轉FFT2吧?
那我的kernel轉回空間時,是不是要做反向的circshift回來呢?
問題三:
現在我的 F_I = FFT2(I),otfFx = FFT2(circshift(k,[SIZE()]))皆已在頻率域,
要做convolution時,有人會用fftshift(F_I)和fftshift(otfFx)將頻率進行位移,
這步驟好像是為了show頻率圖時方便看?那我沒有要show頻率圖是否可以不做這一步?
問題四:
有些範例是會先fftshift再fft2,這樣跟先fft2再fftshift有什麼差別嗎?
問題五:
我看過有人說影像右下補0會造成artifact,
所以一開始是補影像跟kernel的四周,
然後以補0後的影像中心當(0,0)對齊,這樣kernel是不是就不用做circshift了?
而由於沒有要show頻率,所以也不用做fftshift?
問題六:
陳上,若我有多個kernel,其原始大小皆不同,
像是fx=[1 -1],fy=[1;-1],k=[0,1,0;1,-4,1;0,1,0],
尤其是又有1 x 2, 3 x 3,這種奇數和偶數的kernel,
那我對齊時要如何對齊?
好像是將kernel正中間與影像預設的中心(0,0)對齊就可以一起計算了?
這邊影像中心若用"右下補0,kernel做circshift"則為最左上(0,0),
若用"四周補0,kernel的中心對齊影像中心"則為整個加邊的MAT的中心(H/2-1,W/2-1)?
問題七:
用ifft2轉回空間域時,影像的值是否要再處理?
主要是轉fft2之前,我的I和k值域皆為0-1,轉過去頻率後我可能會做複雜計算,
值show出來會超過0-255(有負值或正值很大),
若轉回來後不做處理,show影像出來會有很多區域是全白或全黑,
但若是將值normalize成(0-1)再*255,則會發生整張圖偏亮或偏暗,
我認為是原本最大或最小值太大,以至於正規化0-1時帶動到整體,
請問空間域和頻率域的值域要如何對應呢?
問題八:
我轉回空間域之後,要把剛剛補的那些0去掉,
所以無論補右下還是補四周,都是按照原本補的位置cut掉就可以了吧?
應該不會位移吧?