1

クラスが周波数領域で畳み込みを行うための C++ プログラムを書いていますが、最終結果の隅にエラーがあることに気付きました。そのため、MATLAB で試してみましたが、まったく同じ結果が得られました。例えば

http://engronline.ee.memphis.edu/eece7214/images/Downlodable.htmのカメラマンを使用

やった

a = imread('cameraman.pgm');
h = ones(25,25)/25/25;
a(512,512) = 0;
h(512,512) = 0;
c = ifft2(fft2(a).*fft2(h))/256;
c = c(1:256, 1:256);
c = real(c);
imwrite(c,'test2.png')

左上隅を抽出する前に c をのぞき見したところ、隅から少し翻訳されていることを除いて、imfilter(a, h) と同じ答えであることがわかりました。Gonzalez による Digital Image Processing はこれについて何も言っておらず、Google は私の目から血を流している。

主な質問とは関係ありませんが、この MATLAB コードで 256 で除算しなければならなかった理由も知りたいです。私の C++ コードでは、結果をスケーリングする必要はなく、この MATLAB コードと同じ答えが得られました。

編集:1次元ベクトル(convとifft(fft * fft)を実行)を少しいじりましたが、「エラー」は、 「同じ」畳み込み。しかし、そうであったとしても、「「フル」の左上の 256x256 部分ではなく、「同じ」を取得するためだけにこの部分を抽出する」という決定論的なコーディング方法がわかりません。

編集: http://jeremy.fix.free.fr/IMG/pdf/fftconvolution.pdfを介して、さらにグーグルで解決できる可能性があります。これまでに見たことのない数学記号がたくさんありますが、収集できることから、nxn と mxm を畳み込む場合は、m:(m+n-1) を抽出して、から「同じ」畳み込みを取得します。 fft近似。私はまだ私よりも専門家からの意見を聞きたいので、この更新に基づいてコメントしないことを選択しないでください!

4

2 に答える 2

2

MATLAB は 1 から N までの配列にインデックスを付けます。
正規 C の使用法 (およびほとんどの C 行列数学ライブラリ) は、0 から N-1 までの配列にインデックスを付けます。それが一桁違いの原因かもしれません。

ID であるためには、生の ifft(fft(x)) アルゴリズムはどこかで 1/N の倍率を必要とします。一部の C ライブラリでは、その 1/N を fft() 内に配置しています。多くの場合、その倍率を ifft() に組み込みます。両方に 1/sqrt(N) を入れる人もいます。組み込みの倍率を追加しないものもあり、ID を取得するために必要に応じてユーザーがスケーリングする必要があります。

于 2011-10-01T05:31:33.410 に答える
0

ウィンドウサイズの半分だけシフトする必要があります。この場合、次のようにする必要があります。 c = c(13:256+12,13:256+12); 代わりに: c = c(1:256, 1:256);

信号をゼロでパディングしていますが、信号を 1 から 256 まで取得しているため、それを使用することはできません。エッジにはまだスラッシュがあり、右隅には貴重な信号があり、失われます。

于 2014-04-28T11:04:05.323 に答える