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]]

また、空間領域での畳み込みが周波数領域での乗算と同等であるというアプローチを使用したいと思います。

したがって、私のアルゴリズムは次のようになります。

  1. 画像を読み込みます。
  2. フィルタを作成します。
  3. フィルターと画像の両方を周波数ドメインに変換します。
  4. 両方を掛けます。
  5. 出力を Spatial Domain に再変換すると、それが必要な出力になります。

以下は私が使用する基本的なコードです。画像が読み込まれ、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そのため、 say を使用するとエラーが発生します"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 が機能するための正しいフィルター出力形状が得られるまで、乱数を追加しました。

しかし、もちろん、それは正しい値ではありませんでした。状況は完全に悪化しました。

私の最後の試行は、次のコードを使用して、コンポーネントの 2 次元行列のそれぞれで fft2 関数を使用してから、3 次元行列を再作成することでした。

# 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

私が間違っていたこと、またはグレースケールとカラーの両方の写真でそれをどのように達成できますか。

4

2 に答える 2

2

最も簡単な解決策は、画像を個別の r/g/b 画像に分割し、それぞれを独立してフィルタリングすることです。

于 2012-10-12T15:39:17.903 に答える
1

最後に、3D マトリックスを 3 つの 2D マトリックスに分割する正しい方向に向かっています。これが私が行う方法です-明らかにこれはテストされていません(私はあなたの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
于 2012-10-12T15:53:45.280 に答える