3

GPUで高速化されたアルゴリズムを使用して、高速でメモリを節約するdftを実行したいと思います。しかし、を実行すると、ドキュメントgpu::dftで説明されているように、宛先マトリックスがスケーリングされます。幅をにスケーリングすることでこの問題を回避するにはどうすればよいですか?また、なぜこのようにスケーリングされるのですか?DFTの私のコードはこれです:dft_size.width / 2 + 1

cv::gpu::GpuMat d_in, d_out;
d_in = in;
d_out.create(d_in.size(), CV_32FC2 );
cv::gpu::dft( d_in, d_out, d_in.Size );

ここで、は512x512inCV_32FC1行列です。

最良の解決策は、サイズd_in.sizeとタイプがである宛先マトリックスCV_32FC2です。

4

2 に答える 2

4

これは、FFTの出力に存在する複素共役対称性によるものです。Intel IPPには、このパッキングの適切な説明があります(OpenCVでも同じパッキングが使用されています)。OpenCV dft関数は、このパッキングについても説明しています。

したがって、gpu::dftのドキュメントから次のようになります。

ソース行列が複雑で、出力が実数として指定されていない場合、宛先行列は複雑で、dft_sizeサイズとCV_32FC2タイプになります。

gpu::dftしたがって、関数をパックしたくない場合は、関数に複雑な行列を渡すようにしてください。2番目のチャネルをすべてゼロに設定する必要があります。

Mat realData;

// ... get your real data...

Mat cplxData = Mat::zeros(realData.size(), realData.type());

vector<Mat> channels;
channels.push_back(realData);
channels.push_back(cplxData);

Mat fftInput;
merge(channels, fftInput);

GpuMat fftGpu(fftInput.size(), fftInput.type());
fftGpu.upload(fftInput);

// do the gpu::dft here...

ただし、注意点があります... CCSパックデータを使用するとパフォーマンスが約30〜40%向上するため、完全に複雑な出力を使用するとパフォーマンスが低下します。

お役に立てば幸いです。

于 2011-12-19T15:09:51.713 に答える
0

スケーリングは、の範囲内の結果を得るために行われます+/- 1.0。これは、データの周波数表現を処理する必要があるほとんどのアプリケーションにとって最も便利な形式です。スケーリングされていない結果を取得するには、DFT_SCALEフラグを有効にしないでください。

編集

結果の幅は対称であるため、スケーリングされます。したがって、必要なのは、以前の値を対称的に追加することだけです。

幅の半分でサンプリング定理が満たされるため、スペクトルは対称です。たとえば、サンプルレートが48 kHzの信号ソースの2048ポイントDFTは、24 kHzまでの値しか表すことができず、この値は幅の半分で表されます。

また、参考のために、離散フーリエ変換を使用したスペクトル分析を参照してください。

于 2011-12-19T14:37:41.793 に答える