0

入力を取得し、DFT (離散フーリエ変換) を実行してから、これらの値からゼロクロッシングの数を取得する必要があるプロジェクトに取り組んでいます。

アルゴリズムをコーディングしましたが、複素数を使用しており、それらを操作/計算する方法がわかりません。コードは次のとおりです。

#include <iostream>
#include <complex>
#include <vector>

using namespace std;

const double PI = 3.14159265358979323846;

vector< complex<double> > DFT(vector< complex<double> >& theData)
{
    // Define the Size of the read in vector
    const int S = theData.size();

    // Initalise new vector with size of S
    vector< complex<double> > out(S, 0);
    for(unsigned i=0; (i < S); i++)
    {
        out[i] = complex<double>(0.0, 0.0);
        for(unsigned j=0; (j < S); j++)
        {
            out[i] += theData[j] * polar<double>(2, (-2 * PI * i * j / S));
        }
    }

    return out;
}

int main(int argc, char *argv[]) {
    vector< complex<double> > numbers;

    numbers.push_back(128);
    numbers.push_back(127);

    vector< complex<double> > testing = DFT(numbers);

    for(unsigned i=0; (i < testing.size()); i++)
    {
        cout << testing[i] << endl;
    }
}

たとえば、実行したい場合:

if(testing[i] >= 0)
{
    // blah blah
}

その後、エラーが返されます。アイデアや提案はありますか?複素数を使用せずに DFT を作成することは可能ですか?

4

4 に答える 4

2

あなたの指示を与えた人は誰でも、DFT/FFT の結果でゼロクロッシングをカウントするように言っていませんでした。それは無意味でしょう。(彼らがあなたにそうするように言っているなら、彼らは無知でした. あなたは、あなたにそのようなばかげた指示を与えたことで彼らを笑う許可を持っています). むしろ、元のデータのゼロクロッシングをカウントし、データの FFT も確認するように指示していました。

でも、

  • ゼロクロッシング レートは、音声認識の出発点としてはかなりお粗末です。多分あなたはそれでどこかに行くことができます。少し誇張するだけで、ゼロクロッシングは最も堅牢性の低い DSP 分析であると言えます。ただ、これも単純ですし、音声認識の研究は古くから行われているので、研究が進んでいるのかもしれません。更新/訂正: これは少し誇張です。実際、多くの音声認識技術はゼロクロッシングを使用していると思いますが、最初に何をしているのかを理解する必要があります。なぜなら、それはあまり堅牢ではなく、オクターブ エラーのような多くの種類のエラーに敏感ではないからです。ゼロクロッシングを使用する場合は、最初に (おそらく積極的に) ローパスすることをお勧めします。間違いなく他の要因を考慮してください。

  • FFT の出力を理解することは、ここで頻繁に尋ねられるので、ブログ エントリを書きました。通常、人々はピッチを追跡しようとしますが、実際にはそれを行う必要がありますが、FFT から取得できるものは他にもあります。たとえば、周波数重心や、スピーチで重要なさまざまな周波数の相対的な強度などです。ここから始めてください: http://blog.bjornroche.com/2012/07/frequency-detection-using-fft-aka-pitch.html

  • また、重要な音声周波数を単純にフィルタリングすることを検討することもできます (これらが何であるかを調べるには、ウィキペディアの「調音の仕方」のエントリから始めてください。たとえば、シビラントへのリンクをたどると、「[s] が持っていることがわかります。約 8,000 Hz で最大の音響強度". Neeto!) その情報は FFT から、またはフィルター処理によって取得できます。それぞれに長所と短所があります。音声認識の文献を調べて、それらが何を使用しているかを確認することをお勧めします。

于 2012-09-21T04:00:04.633 に答える
0

同様の問題が発生しましたが、FFTライブラリで十分にサポートされておらず、単純な古い配列を使用することになったため、c++複素数の倍数のベクトルコンテナーの使用をあきらめました。あなたがやろうとしていることのほとんどはうまくいくでしょう。

 std::complex<double>*  in=new std::complex<double> [N];

すべてのarthmaticは、たとえば他の配列と同じように機能します。abs(in[i])またはin[i] *pi 、数学ライブラリのC++バージョンを使用するようにしてください。

特定の質問については、C ++リファレンスを確認する必要があります。これを使用して、ゼロより大きいかどうかを確認できる実関数とimag関数があります。

次に、確認してください(fftwを使用している場合)

すべての複素数にキャストされた再解釈を使用するには(複素数の場合は入力と出力)

    p = fftw_plan_dft_c2r_1d(N, reinterpret_cast<fftw_complex*>(in), out,FFTW_ESTIMATE);  

   fftw_execute(p);
于 2012-09-20T20:09:56.460 に答える
0

DFTは、少なくともその出力には常に複素数を使用します。入力が時間の経過とともに信号を表す場合、出力は周波数に従って信号を表します。各複素数は極形式で記述され、振幅を表す絶対値と位相を表す角度に分割されます。おそらくそれはあなたが興味を持っている振幅です。もしそうなら、絶対値を計算したいと思うでしょうが、それらはすべて非負でもあります。

実数で機能するDFTのバリエーションがあります。その点で、離散コサイン変換が頭に浮かびます。これがアプリケーションで役立つかどうかわからない。

コードよりも速くDFTを計算するFFTWのようなライブラリがあることに注意してください。入力サイズが2の累乗である限り、自作のFFTでさえ検討する価値があるかもしれません。しかし、これはすべて、実際の質問のポイントから少し外れています。

于 2012-09-20T20:11:32.240 に答える
0

DFTなどのフーリエ変換は複素数を返すため、実際にはそれらを回避することはできません。

アプリケーションによっては、複素数の虚数部分を安全に無視して、DFT の出力を実数のシーケンスとして扱うことができる場合があります。

複素数に対して実行できる操作はたくさんあります。アプリケーションに関連するものもあれば、そうでないものもあります。複素数をよりよく理解するには、少し時間をかける価値があります。

最後に、いいえ、複素数を使用せずに DFT を作成することはできません。DFT の複雑な出力を取得して実数に変換できますが、その過程で情報が失われます。複素数と、DFT がアプリケーションでどのように使用されているかを理解して、そのような変換を実行することが適切かどうかを判断できるようにする必要があります。

于 2012-09-20T20:05:55.943 に答える