2012-10-12 36 views
1

我想對圖像應用濾鏡,例如,模糊濾鏡[[1/9.0, 1/9.0, 1/9.0], [1/9.0, 1/9.0, 1/9.0], [1/9.0, 1/9.0, 1/9.0]]將fft2用於RGB濾鏡的變形

另外,我想使用空間域中的卷積相當於頻域中的乘法的方法。

所以,我的算法會像。

  1. 加載圖像。
  2. 創建過濾器。
  3. 將兩個濾鏡&轉換爲頻域。
  4. 兩者相乘。
  5. 將輸出重新轉換爲空間域,並且應該是所需的輸出。

以下是我使用的基本代碼,將圖像加載並顯示爲cv.cvmat對象。

Image是一類由我創造的,它有一個成員圖像這是scipy.matrix對象和toFrequencyDomain(size = None)使用spf.fftshift(spf.fft2(self.image, size))其中spfscipy.fftpackdotMultiply(img)使用scipy.multiply(self.image, image)

f = Image.fromMatrix([[1/9.0, 1/9.0, 1/9.0], 
      [1/9.0, 1/9.0, 1/9.0], 
      [1/9.0, 1/9.0, 1/9.0]]) 
lena = Image.fromFile("Test/images/lena.jpg") 
print lena.image.shape 
lenaf = lena.toFrequencyDomain(lena.image.shape) 
ff = f.toFrequencyDomain(lena.image.shape) 
lenafm = lenaf.dotMultiplyImage(ff) 
lenaff = lenafm.toTimeDomain() 
lena.display() 
lenaff.display() 

所以,上面的代碼工作得很好,如果我告訴OpenCV通過GRAY_SCALE加載圖片。

但是,如果我讓顏色要加載的圖像... lena.image.shape(512, 512, 3) ..

如此,它使用scipy.fttpack.ftt2"When given, Shape and Axes should be of same length"當給我一個錯誤。

是我的嘗試下一個轉變我的過濾器,以3 d ..作爲

[[[1/9.0, 1/9.0, 1/9.0], 
    [1/9.0, 1/9.0, 1/9.0], 
    [1/9.0, 1/9.0, 1/9.0]], 
[[1/9.0, 1/9.0, 1/9.0], 
    [1/9.0, 1/9.0, 1/9.0], 
    [1/9.0, 1/9.0, 1/9.0]], 
[[1/9.0, 1/9.0, 1/9.0], 
    [1/9.0, 1/9.0, 1/9.0], 
    [1/9.0, 1/9.0, 1/9.0]]] 

而且,不知道軸參數做什麼,我用隨機數增加一條,作爲(-2, -1, -1), (-1, -1, -2), .. etc.直到它給了我正確的過濾dotMultiply的輸出形狀。

但是,它當然不是正確的價值。事情完全變得更糟。

我的最終試驗是在每個組件二維矩陣上使用fft2函數,然後使用以下代碼重新制作三維矩陣。

# Spiltting the 3-D matrix to three 2-D matrices. 
for i, row in enumerate(self.image): 
      r.append(list()) 
      g.append(list()) 
      b.append(list()) 
      for pixel in row: 
       r[i].append(pixel[0]) 
       g[i].append(pixel[1]) 
       b[i].append(pixel[2]) 
     rfft = spf.fftshift(spf.fft2(r, size)) 
     gfft = spf.fftshift(spf.fft2(g, size)) 
     bfft = spf.fftshift(spf.fft2(b, size)) 
     newImage.image = sp.asarray([[[rfft[i][j], gfft[i][j], bfft[i][j]] for j in xrange(len(rfft[i]))] for i in xrange(len(rfft))]) 
     return newImage 

任何幫助我做錯了什麼,或者我怎麼能達到GreyScale和彩色圖片。

+0

是否有一個原因,你需要在頻域做這個過濾?我對這兩種方式都很感興趣,我只是好奇你爲什麼決定這麼做。 – aganders3

+0

好吧,我們被要求在圖像處理課程實驗室的灰度級中使用它,使用MatLab很容易,所以我試圖用Python和Scipy重新制作它,所以它不想實際工作,所以我寧願讓它工作。 :D –

回答

1

在您將3D矩陣分成三個二維矩陣的末端,您正朝着正確的方向前進。這就是我將如何做到這一點 - 顯然這是未經測試的(我沒有你的Image班,等等。),但它應該給你一個很好的開始:

for i, channel in enumerate(self.image): 
    channel_ = spf.fftshift(spf.fft2(channel)) # take FFT of each channel (r,g,b) separately 
    channel_ = scipy.multiply(channel_,ff) # multiply each channel by the filter (freq. domain) 
    filtered_image[:][:][i] = spf.fftshift(spf.ifft2(channel_)) # inverse FFT each channel separately 
+0

我相信我可以看到你正在做的事情,這似乎很棒,我會努力實現它。提前致謝! –

+0

偉大的工作完全好,謝謝! –

2

最簡單的解決方案是將圖像分成單獨的r/g/b圖像並獨立地進行過濾。

+0

我相信我嘗試過,當我將3-D矩陣分解爲3並在每個矩陣上應用fft時,乘法運算完全相同。 –