2Dの2D信号処理のためのIOS加速フレームワークを使用しますか?
-
13-12-2019 - |
質問
//編集...
2つの画像以外の画像で特に働くという問題に対処するために、私の質問を少し編集しています。 256 x 256または1024 x 1024のようなサイズで正方形のグレースケール画像で動作する基本的な構造がありますが、任意のサイズの画像に一般化する方法はわかりません。 FFT機能は幅と高さのlog2を含めて欲しいようですが、結果のデータを解凍する方法、またはデータがスクランブルされているだけではない場合は不明です。私は明らかなことをすることは、すべてのブラックイメージ内でNPOTイメージを中心にして、データを見るときにそれらの位置にある値を無視することです。しかし、NPOTデータを扱う厄介な方法が少なければ疑問に思う。
// ...終了編集
フレームワークのマニュアルを加速するのに少しの問題があります。私は通常FFTW3を使用しますが、実際のiOSデバイスでコンパイルするためにそれを得るのに問題がある(この質問)。誰かが私を強化を使った超簡単な実装を指していることができますそれは次のようなものです:
1)画像データを適切なデータ構造に変えて、FFTメソッドを加速させることができます。
FFTW3では、グレースケールイメージを使用して、符号なしバイトを「FFTW_Complex」アレイに配置することは、符号なしバイトを「FFTW_Complex」アレイに配置します。各ピクセルに対してゼロに初期化されます。
2)このデータ構造を取り、それにFFTを実行します。
3)大きさと位相を印刷します。
4)はITのIFFTを実行します。
5)IFFTから生じるデータから元の画像を再現します。
これは非常に基本的な例ですが、私はアップルのサイトからのドキュメントを使うのに問題があります。 so href="https://stackoverflow.com/questions/3398753/using-the-apple-fupt-and-accelerate-framework">ここでPIによる回答は非常に役立ちますが、まだ私はまだグレースケール(またはカラー)2Dイメージを使用してこの基本的な機能を実行するために加速する方法についてはやや混乱しています。
とにかく、2D画像を処理する任意のポインタ、特にいくつかの簡単なワークコードは非常に役立ちます。
\\\編集\\\
大丈夫、 PKMITALのGitHub Repo 、私は1)以来投稿したと思った作業コードを持っています。残りの質問...
FFT「計画」を初期化します。 2つの画像の2つの画像を仮定する:
#include <Accelerate/Accelerate.h>
...
UInt32 N = log2(length*length);
UInt32 log2nr = N / 2;
UInt32 log2nc = N / 2;
UInt32 numElements = 1 << ( log2nr + log2nc );
float SCALE = 1.0/numElements;
SInt32 rowStride = 1;
SInt32 columnStride = 0;
FFTSetup setup = create_fftsetup(MAX(log2nr, log2nc), FFT_RADIX2);
.
二乗パワーの2つのグレースケール画像のバイト配列を渡し、それをcomplex_splitに変換する:
COMPLEX_SPLIT in_fft;
in_fft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
in_fft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );
for ( UInt32 i = 0; i < numElements; i++ ) {
if (i < t->width * t->height) {
in_fft.realp[i] = t->data[i] / 255.0;
in_fft.imagp[i] = 0.0;
}
}
.
変換された画像データのFFTを実行してから、大きさと位相をつかみます。
COMPLEX_SPLIT out_fft;
out_fft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
out_fft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );
fft2d_zop ( setup, &in_fft, rowStride, columnStride, &out_fft, rowStride, columnStride, log2nc, log2nr, FFT_FORWARD );
magnitude = (float *) malloc(numElements * sizeof(float));
phase = (float *) malloc(numElements * sizeof(float));
for (int i = 0; i < numElements; i++) {
magnitude[i] = sqrt(out_fft.realp[i] * out_fft.realp[i] + out_fft.imagp[i] * out_fft.imagp[i]) ;
phase[i] = atan2(out_fft.imagp[i],out_fft.realp[i]);
}
.
今すぐあなたはOUT_FFTデータのIFFTを実行して元の画像を得ることができます...
COMPLEX_SPLIT out_ifft;
out_ifft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
out_ifft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );
fft2d_zop (setup, &out_fft, rowStride, columnStride, &out_ifft, rowStride, columnStride, log2nc, log2nr, FFT_INVERSE);
vsmul( out_ifft.realp, 1, SCALE, out_ifft.realp, 1, numElements );
vsmul( out_ifft.imagp, 1, SCALE, out_ifft.imagp, 1, numElements );
.
またはあなたは自己相関を得るために大きさでIFFTを実行することができます...
COMPLEX_SPLIT in_ifft;
in_ifft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
in_ifft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );
for (int i = 0; i < numElements; i++) {
in_ifft.realp[i] = (magnitude[i]);
in_ifft.imagp[i] = 0.0;
}
fft2d_zop ( setup, &in_fft, rowStride, columnStride, &out_ifft, rowStride, columnStride, log2nc, log2nr, FFT_INVERSE );
vsmul( out_ifft.realp, 1, SCALE, out_ifft.realp, 1, numElements );
vsmul( out_ifft.imagp, 1, SCALE, out_ifft.imagp, 1, numElements );
.
最後に、IFFTの結果を画像配列に戻すことができます。
for ( UInt32 i = 0; i < numElements; i++ ) {
t->data[i] = (int) (out_ifft.realp[i] * 255.0);
}
.
早期の2つの画像を処理するために高速フレームワークの使用方法を考え出していません。セットアップに十分なメモリを割り当てると、FFTを実行し、その後にオリジナルのイメージを入手するためにIFFTを実行できます。しかし、(FFTの大きさを持つ)自己相関をやろうとすると、私のイメージは正しく考えられます。私はイメージを適切に埋めるための最良の方法がよくわからないので、誰かがこれを行う方法の考えを持っています。 (またはVDSP_CONVメソッドの作業バージョンを共有しましょう!)
解決
任意の画像サイズで作業を実行するために、あなたがしなければならないのはあなたの入力値配列のサイズを2の次の力に適切にサイズすることです。
ハード部品は、元の画像データを置く場所と埋めたものです。画像から画像やデータ鉱山に本当にやろうとしているものは不可欠です。
下のリンクされたPDFでは、12.4.2を超える段落に特に注意を払う http://www.mathcs.org/java/programs/fft. /fftinfo/c12-4.pdf
2軸に沿った操作について上記が話すが、2番目の寸法の前に同様の考えを実行し、2次元に次のようになる可能性があります。 IMが正しい場合、この例は適用される可能性があります(そしてこれはまだ正確なアルゴリズムを意味する):
900×900の画像を持っているとします。 まず、イメージを512,256,128、および4の垂直ストリップに分割できます。 次に、次の256ピクセルの次の256ピクセルについて、次の256ピクセルの場合は、次の256ピクセルの場合、次の256ピクセルの場合は4つの1D FFTを処理します.FFTの出力は本質的に人気ですので周波数のうち、これらは単純に(周波数のみから角度オフセットではなく)追加することができます。 その後、この同じ技術を2次元に向かって押すことができました。この時点で、実際には埋め込む必要なしにすべての入力ピクセルを考慮したであろう。
これは本当に思考のための食べ物です、私は自分自身を試してみません、そして確かにこれを私自身を調べるべきです。あなたが今このような仕事をしているのであれば、この時点で私よりも多くの時間があるかもしれません。