ImageMagick 例 --
フーリエ乗算/除算
DIY FFT 数学入門
以下は、2種類の高速フーリエ変換画像による乗算と除算を行うためのいくつかの技法の例です。数学的手法には基本的に2つの方法があります。FX演算と合成演算です。- FX 演算
- FX、DIY 演算子 を使用すると、式を直接適用できます。ただし、解釈されるため非常に遅くなります。しかし、式はすべて単一の式で適用されるため、中間画像が不要になります。IMの非HDRIバージョンでは、量子化丸め誤差が減少します。
- 合成演算
- これは画像合成を使用して算術演算を実行するもので、「FX 演算」よりもはるかに高速です。ただし、一度に1つの算術演算しか実行できないため、各演算後に画像を別のメモリ内画像に保存する必要があります。非HDRIバージョンでは、演算間で追加の「丸め誤差」が発生します。
中間HDRI画像をディスクファイルに保存する場合は、非常に少ない数の浮動小数点画像ファイル形式のいずれかを使用する必要があります。これらの形式には、NetPBM PFMファイル形式、TIFF、または特別な設定「-define quantum:format=floating-point」を伴うMIFFファイル形式が含まれます。
|
使用する畳み込みカーネル画像を以下に示します。
-roll -64-64」を適用する必要があります。カーネル画像は、FFT乗算または除算の対象となる画像の強度を維持するために、平均値で除算する必要もあります。これは、FFT乗算と除算における大きな問題です。非HDRI画像はこのように正規化できないため、これは一般的にFFT変換が適用された後、乗算の前に実行されます。IMのHDRIバージョンでは、いつでもこれを実行できます。
FFT 乗算(
)
振幅/位相画像のFFT乗算、IM Q16を使用
R = A ⊗ B ( FFT Multiply )
Rm = Am × Bm
Rp = mod( Ap + Bp +0.5, 1.0)
mean = the DC value (center pixel) of the magnitude image
FX演算を使用(注: 値 v.p{64x64} は、畳み込みカーネルのDC、つまり平均です)
# non-HDRI
magick convolve_kernel.png -roll -64-64 -fft \
\( cameraman_sm.png -fft \) \
\
\( -clone 0,2 -fx 'u*v / p{64,64} ' \) \
\( -clone 1,3 -fx 'mod(u + v + 0.5, 1.0)' \) \
\
-delete 0-3 -ift cameraman_convolve_1.png
|
# non-HDRI
magick convolve_kernel.png -roll -64-64 -fft \
\( -clone 0 -crop 1x1+64+64 +repage -scale 128x128 \
-clone 0 -compose divide -composite \) -swap 0 +delete \
\( cameraman_sm.png -fft \) \
\
\( -clone 0,2 -compose multiply -composite \) \
\( -clone 1,3 -compose add -background gray50 -flatten \) \
-delete 0-3 -ift cameraman_convolve_2.png
|
元の画像の平均で除算
# non-HDRI
magick convolve_kernel.png \( -clone 0 -roll -64-64 -fft \) \
\( -clone 0 -scale 1x1 -scale 128x128 \
-clone 1 -compose divide -composite \) \
-delete 0,1 +swap \
\( cameraman_sm.png -fft \) \
\
\( -clone 0,2 -compose multiply -composite \) \
\( -clone 1,3 -compose add -background gray50 -flatten \) \
-delete 0-3 -ift cameraman_convolve_2b.png
|
DC値/DC値 == 1.0に注意してください。DC値は振幅スペクトルの中で最大の値であるため、正規化しないのはなぜですか!例:
-auto-level"これは振幅画像に対してのみ実行でき、実数/虚数ペアでは同じ量だけ引き伸ばす必要があるため機能しません。
# non-HDRI
magick convolve_kernel.png -roll -64-64 -fft \
\( -clone 0 -auto-level \) -swap 0 +delete \
\( cameraman_sm.png -fft \) \
\
\( -clone 0,2 -compose multiply -composite \) \
\( -clone 1,3 -compose add -background gray50 -flatten \) \
\
-delete 0-3 -ift cameraman_convolve_2c.png
|
実数/虚数画像のFFT乗算、IM HDRIを使用
R = A ⊗ B ( FFT Multiply )
Rr = Ar×Br - Ai×Bi
Ri = Ar×Bi + Ai×Br
mean = the DC value (center pixel) of the real image
FXを使用5つの画像が関与し、5番目の画像がスケールされた平均です - FXが除算を実行します
|
平均値にDC値を使用(5番目の画像はなし)
|
スケール画像平均を使用!
|
画像スケーリングからの平均
|
平均値にDC値を使用
|
FFT乗算の後、DC値平均を適用
|
FFT 除算(
)
ここでは、除算を使用して、上記の画像に追加されたぼかしを除去またはデコンボリューションします(より良い言葉が見つからないため)。基本的にまったく同じですが、「正規化された」畳み込みカーネルがメイン画像から除算されます。各例では、上記と同じ手法を使用して生成された画像を使用します。
振幅/位相のFFT除算、IM Q16を使用
R = B ø A ( FFT Divide )
Rm = Bm / Am
Rp = mod( -Ap + Bp +1.5, 1.0)
mean = the DC value (center pixel) of the magnitude image
注:ゼロによる完全な除算を回避するために、分母に量子化スケールの最小値が追加されます。これは後で画像からノイズを除去するためにも使用されます。FX演算を使用 |
|
|
|
|
|
実数/虚数のFFT除算、IMのHDRIバージョンを使用
R = B ø A ( FFT Divide )
Denom = Ar×Ar + Ai×Ai + noise
Rr = ( Ar×Br + Ai×Bi ) / Denom
Ri = ( Ar×Bi - Ai×Br ) / Denom
mean = the DC value (center pixel) of the real image
FXを使用 |
|
|
|
|
|
|
|
|
|
|
|
更新:上記の色「gray50」の使用は、「gray(50%)」に変更して、より正確な50%グレイ値を生成する必要があります。「名前付き」の色は実際には8ビットカラーのみであり、そのためあまり正確ではありません。また、新しいカラー空間処理では、gray50はsRGBカラー空間にあるのに対し、gray(50%)は線形カラー空間にあるため、上記の計算で使用すべきです。例は、線形グレースケールカラー空間の使用についても確認する必要があります。
![[IM Text]](roundtrip_cmp_1.txt.gif)
![[IM Output]](cameraman_convolve_1hdri.png)
![[IM Output]](cameraman_deconvolve_1hdri.png)
![[IM Text]](roundtrip_cmp_1hdri.txt.gif)
![[IM Text]](roundtrip_cmp_2.txt.gif)
![[IM Output]](cameraman_convolve_2hdri.png)
![[IM Output]](cameraman_deconvolve_2hdri.png)
![[IM Text]](roundtrip_cmp_2hdri.txt.gif)
![[IM Text]](roundtrip_cmp_3.txt.gif)
![[IM Text]](roundtrip_cmp_3b.txt.gif)
![[IM Text]](roundtrip_cmp_4.txt.gif)
![[IM Text]](roundtrip_cmp_4b.txt.gif)