我正在玩一些玩具代碼,以嘗試驗證我是否了解離散傅立葉變換在 OpenCV 中的作業原理。我發現了一個相當令人困惑的案例,我相信原因是我呼叫 cv::dft() 的標志是不正確的。
我從實值(例如音頻)樣本的一維陣列開始。(作為列存盤在 cv::Mat 中。)
我使用 cv::dft() 來獲得一個復值的傅立葉桶陣列。
我使用 cv::dft() 和 cv::DFT_INVERSE 將其轉換回來。
我這樣做了幾次,列印結果。結果似乎是正確的形狀,但大小錯誤。
代碼:
cv::Mat samples(1, 2, CV_64F);
samples.at<double>(0, 0) = -1;
samples.at<double>(0, 1) = 1;
std::cout << "samples(" << samples.type() << "):" << samples << std::endl;
for (int i = 0; i < 3; i) {
cv::Mat buckets;
cv::dft(samples, buckets, cv::DFT_COMPLEX_OUTPUT);
samples = cv::Mat();
cv::dft(buckets, samples,
cv::DFT_INVERSE | cv::DFT_COMPLEX_INPUT | cv::DFT_REAL_OUTPUT);
std::cout << "buckets(" << buckets.type() << "):" << buckets << std::endl;
std::cout << "samples(" << samples.type() << "):" << samples << std::endl;
}
輸出:
samples(6):[-1, 1]
buckets(14):[0, 0, -2, 0]
samples(6):[-2, 2]
buckets(14):[0, 0, -4, 0]
samples(6):[-4, 4]
buckets(14):[0, 0, -8, 0]
samples(6):[-8, 8]
我本來希望上面的輸出會重復。例如 [-1, 1], [0, 0, -1, 0], ...。相反,每次往返的幅度加倍。
我的理解錯了嗎?還是我使用了錯誤的標志?等等。
uj5u.com熱心網友回復:
默認情況下,opencv 中的逆 DFT 不會縮放結果,因此您將輸入乘以陣列的長度。這是一種常見的優化,因為并不總是需要縮放,逆 DFT 的最有效演算法只使??用不產生縮放的正向 DFT。您可以通過將cv::DFT_SCALE標志添加到逆 DFT 來解決此問題。
一些庫以 1/sqrt(N) 縮放前向和后向變換,因此在使用傅立葉變換時檢查檔案(或撰寫快速測驗代碼)通常很有用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/424708.html
