Различное значение результата между openCV DFT и Matlab FFT

Я пытаюсь преобразовать простой код Matlab, выполняющий БПФ. Код выглядит следующим образом:

c = fft([y; zeros(N-M, 1)]);

Значения для N = 256, M = 100. Вот значения y (100 баллов), которые я использую для тестирования:

0.504747377917058
0.897277682272301
0.151672365249603
0.355122573738706
0.553925412440538
0.158834350258486
0.356559717393412
0.267749785433509
0.739084139656738
0.166499777727771
0.473321012784302
0.0347129610206839
0.553675931056349
0.583457423409536
0.639157091136979
0.463509283032041
0.0721174152598855
0.566980735391889
0.0564211028148701
0.403891120545224
0.845764884433777
0.245839907426279
0.417378682568391
0.384599711924719
0.570345181829177
0.326215319711704
0.681210248049855
0.681911636855699
0.213479990231251
0.905962428666556
0.131834588282127
0.296816364347757
0.690153889060709
0.761416677611842
0.0714190758056392
0.537581523685523
0.357804064206785
0.229092225340180
0.436965221822875
0.639092951254091
0.266833951366296
0.907009864842252
0.0287396847461444
0.00354789906847874
0.0407293156496344
0.716630537833777
0.404597364977079
0.521979978932170
0.561113191209460
0.818419687885502
0.443967335108977
0.788295508722246
0.286075857076539
0.803257985515235
0.207251351861903
0.908923717800780
0.0130631950214316
0.330605441808835
0.369225622245975
0.191168972446011
0.831355663626163
0.306827929264038
0.203683945236538
0.795374294250967
0.0778432960896650
0.128758372989548
0.256502648405316
0.124572930296307
0.199568413846996
0.839391857527602
0.501216953834577
0.971952162130999
0.170535216236638
0.277776070299947
0.908871398673197
0.288621521395466
0.980428090500101
0.205282271849582
0.0707921626520792
0.308532590965935
0.895700477583215
0.180418430046274
0.849252966420743
0.398632936696243
0.440812620599911
0.653863109764075
0.279796493230911
0.243739491638821
0.568050355671034
0.380054323853321
0.228045989904235
0.896776869422718
0.876857169145763
0.755206498677754
0.524798827885731
0.920629262138363
0.398003897749699
0.876539603027160
0.129403908185034
0.880161905088309

Итак, приведенный выше код дополняет y нулями и вычисляет ДПФ. Я получаю следующие значения результата (значения 256 баллов):

45.8596712225745 + 0.00000000000000i
9.90434329814591 - 33.1904512138980i
-9.12359458464445 - 5.03410521169996i
6.88875948700932 - 4.14225868238042i
-3.97879406384973 - 8.95069642483800i
-0.527684387456332 + 2.49845418099316i
3.85809982985414 - 5.46937641811437i
-3.96764853651787 - 2.34622628122165i
2.20477059738870 + 1.21426385106703i
0.494216471811413 - 2.84233764317402i
1.67052509268845 + 1.44291526425030i
4.54686817774770 - 5.00046801253062i
-4.31838007965185 - 4.18173183306384i
-0.276534703962634 + 3.01315071721780i
2.45931586744252 - 1.92877554774639i
-0.775672552130784 - 0.365912343111928i
2.53732707972096 - 0.359708926302334i
-0.338432336750164 - 2.54841065708277i
-0.0128016284267085 + 1.20550118120132i
2.16174758056324 - 1.04725923641435i
-0.212684062587258 - 0.127085617245476i
3.71317625428346 + 0.674037969249136i
2.38482681651969 - 4.88327784674562i
-3.06758182489689 - 2.09961047697791i
0.000691527211423293 + 2.10787067861023i
2.85169534443216 - 0.376549947505046i
1.23326995958507 - 2.40200017215140i
-0.317620832360280 - 1.48903574432911i
0.251940317179818 - 0.643351296056338i
0.00930606921802246 - 1.18071469400497i
-0.509930040194971 - 0.0329926167865611i
0.620743500961637 + 0.175064493081313i
0.303282838848640 + 0.179045734469449i
2.06591676232483 + 0.698270946400612i
1.97112401938429 - 2.69897963013191i
-2.40412657412667 - 1.37901746213921i
-0.202632416045422 + 3.10755952760580i
3.50925516742759 + 1.28839007116726i
3.24727373839066 - 0.940897471110965i
2.64325152341096 - 2.17943692267966i
1.30799382172766 - 2.47822481553404i
1.32599179978654 - 2.67395778722997i
-0.986223940591071 - 3.68434488630701i
-2.37397199420597 + 0.0863862937971753i
1.75612486025878 + 0.440133150835220i
0.217872882867626 - 3.22195028710911i
-2.42857924351522 - 0.243480282383912i
0.841485027643107 + 0.933917732567782i
0.422741103230674 - 1.93213154653598i
-2.17182249956523 - 0.447966223543852i
-0.534226111926907 + 2.26248911200429i
2.34595128320700 + 0.995875514513595i
1.23828590770716 - 1.81788924123758i
-1.31381520384945 - 0.438781136926015i
0.265569631334004 + 1.73930782577809i
1.85654792500427 + 0.563287578738156i
1.58612903941583 - 0.151235703033427i
1.86894101685822 - 0.687265117225119i
1.10063046309645 - 1.86684873608126i
-0.890895639693862 - 1.45443893165233i
-1.11313824626327 + 1.36408710279701i
2.30523219751891 + 2.06232967195442i
2.84846099212384 - 1.15626879459107i
0.928183105903925 - 0.675737787752056i
2.88598323818832 - 0.713720560169680i
1.12841138006926 - 3.57619314936123i
-1.23179681632529 - 1.04173699888163i
0.925059201315028 - 0.387556955822837i
-0.169072092684776 - 1.16363457635363i
1.01563765726148 + 0.561251083390194i
1.95141252445168 - 2.43282704213811i
-1.87854880792222 - 1.77482710659158i
0.176507496090988 + 1.53542330799445i
2.00569856856358 - 0.933651039757763i
0.284232256927046 - 1.26021487457486i
0.589097218232281 - 0.975698723321199i
-0.491037106876860 - 0.743795157266385i
0.906822721777090 + 1.04721948050224i
2.48212298438052 - 1.07110175914052i
0.830963132157770 - 1.39152736449028i
2.67147957474919 - 1.02323863530096i
2.17190751971229 - 5.21563379285477i
-3.37410990478670 - 5.09685988720914i
-4.38902357375578 - 0.0192413821976393i
-1.31664318793529 + 1.53561536269269i
-0.653544794176269 + 0.877748843132741i
0.529502357912636 + 2.06871784149389i
3.16460668474131 - 0.160744995586227i
0.375477909858005 - 2.58413073509201i
0.129257069000674 + 0.529692136818612i
3.22633319435650 - 2.55949068459183i
-2.92042331728758 - 4.98020044465782i
-3.90009789695450 + 2.75868357879037i
3.67799307428386 + 1.99347477429359i
1.73465460088017 - 4.23652816255638i
-2.84410643528760 - 2.24808597343154i
-1.60905449517424 + 1.12708764949203i
1.42327484687350 + 0.468881927174310i
0.472720936110344 - 2.98548947092464i
-3.49035858658498 - 1.07770564278035i
-0.795992594555446 + 2.59825440908341i
1.46713579129870 + 0.00166027566181515i
-0.0651156361235383 - 0.399824806712336i
0.561472972516193 - 0.400492784351395i
-0.793050199774314 - 0.383990648072381i
1.04332080518458 + 1.74344594301767i
3.24371299641559 - 1.37236880617660i
1.03075929301523 - 2.91913224178309i
0.727940154411399 - 3.80388794365699i
-3.58535129816023 - 4.67072029875468i
-4.47074615544602 + 1.24195856609816i
0.659580252238487 + 0.544677844169043i
-2.14447773734732 - 2.70111564548618i
-4.02700043526524 + 0.849174553022399i
-1.83450527627658 + 2.54475157375658i
0.608195609119577 + 2.47425153582646i
1.30155430877605 - 1.13157550967776i
-3.13920679624116 - 0.390514308539891i
0.200292581452531 + 3.49797987498687i
1.50861168473858 - 1.78987000427086i
-3.72398117780173 + 0.714924052874505i
1.82403650609921 + 3.47240526436940i
0.352173215074743 - 2.76175261945447i
-4.35157215858281 + 2.88529710006693i
3.13355239421224 + 5.36768555378865i
4.25657660829636 - 0.414024831155080i
2.71630589835319 - 1.71234848535067i
-0.0191279971491571 - 4.40183593230476i
-4.79936170909190 + 0.00000000000000i
-0.0191279971491571 + 4.40183593230476i
2.71630589835319 + 1.71234848535067i
4.25657660829636 + 0.414024831155080i
3.13355239421224 - 5.36768555378865i
-4.35157215858281 - 2.88529710006693i
0.352173215074743 + 2.76175261945447i
1.82403650609921 - 3.47240526436940i
-3.72398117780173 - 0.714924052874505i
1.50861168473858 + 1.78987000427086i
0.200292581452531 - 3.49797987498687i
-3.13920679624116 + 0.390514308539891i
1.30155430877605 + 1.13157550967776i
0.608195609119577 - 2.47425153582646i
-1.83450527627658 - 2.54475157375658i
-4.02700043526524 - 0.849174553022399i
-2.14447773734732 + 2.70111564548618i
0.659580252238487 - 0.544677844169043i
-4.47074615544602 - 1.24195856609816i
-3.58535129816023 + 4.67072029875468i
0.727940154411399 + 3.80388794365699i
1.03075929301523 + 2.91913224178309i
3.24371299641559 + 1.37236880617660i
1.04332080518458 - 1.74344594301767i
-0.793050199774314 + 0.383990648072381i
0.561472972516193 + 0.400492784351395i
-0.0651156361235383 + 0.399824806712336i
1.46713579129870 - 0.00166027566181515i
-0.795992594555446 - 2.59825440908341i
-3.49035858658498 + 1.07770564278035i
0.472720936110344 + 2.98548947092464i
1.42327484687350 - 0.468881927174310i
-1.60905449517424 - 1.12708764949203i
-2.84410643528760 + 2.24808597343154i
1.73465460088017 + 4.23652816255638i
3.67799307428386 - 1.99347477429359i
-3.90009789695450 - 2.75868357879037i
-2.92042331728758 + 4.98020044465782i
3.22633319435650 + 2.55949068459183i
0.129257069000674 - 0.529692136818612i
0.375477909858005 + 2.58413073509201i
3.16460668474131 + 0.160744995586227i
0.529502357912636 - 2.06871784149389i
-0.653544794176269 - 0.877748843132741i
-1.31664318793529 - 1.53561536269269i
-4.38902357375578 + 0.0192413821976393i
-3.37410990478670 + 5.09685988720914i
2.17190751971229 + 5.21563379285477i
2.67147957474919 + 1.02323863530096i
0.830963132157770 + 1.39152736449028i
2.48212298438052 + 1.07110175914052i
0.906822721777090 - 1.04721948050224i
-0.491037106876860 + 0.743795157266385i
0.589097218232281 + 0.975698723321199i
0.284232256927046 + 1.26021487457486i
2.00569856856358 + 0.933651039757763i
0.176507496090988 - 1.53542330799445i
-1.87854880792222 + 1.77482710659158i
1.95141252445168 + 2.43282704213811i
1.01563765726148 - 0.561251083390194i
-0.169072092684776 + 1.16363457635363i
0.925059201315028 + 0.387556955822837i
-1.23179681632529 + 1.04173699888163i
1.12841138006926 + 3.57619314936123i
2.88598323818832 + 0.713720560169680i
0.928183105903925 + 0.675737787752056i
2.84846099212384 + 1.15626879459107i
2.30523219751891 - 2.06232967195442i
-1.11313824626327 - 1.36408710279701i
-0.890895639693862 + 1.45443893165233i
1.10063046309645 + 1.86684873608126i
1.86894101685822 + 0.687265117225119i
1.58612903941583 + 0.151235703033427i
1.85654792500427 - 0.563287578738156i
0.265569631334004 - 1.73930782577809i
-1.31381520384945 + 0.438781136926015i
1.23828590770716 + 1.81788924123758i
2.34595128320700 - 0.995875514513595i
-0.534226111926907 - 2.26248911200429i
-2.17182249956523 + 0.447966223543852i
0.422741103230674 + 1.93213154653598i
0.841485027643107 - 0.933917732567782i
-2.42857924351522 + 0.243480282383912i
0.217872882867626 + 3.22195028710911i
1.75612486025878 - 0.440133150835220i
-2.37397199420597 - 0.0863862937971753i
-0.986223940591071 + 3.68434488630701i
1.32599179978654 + 2.67395778722997i
1.30799382172766 + 2.47822481553404i
2.64325152341096 + 2.17943692267966i
3.24727373839066 + 0.940897471110965i
3.50925516742759 - 1.28839007116726i
-0.202632416045422 - 3.10755952760580i
-2.40412657412667 + 1.37901746213921i
1.97112401938429 + 2.69897963013191i
2.06591676232483 - 0.698270946400612i
0.303282838848640 - 0.179045734469449i
0.620743500961637 - 0.175064493081313i
-0.509930040194971 + 0.0329926167865611i
0.00930606921802246 + 1.18071469400497i
0.251940317179818 + 0.643351296056338i
-0.317620832360280 + 1.48903574432911i
1.23326995958507 + 2.40200017215140i
2.85169534443216 + 0.376549947505046i
0.000691527211423293 - 2.10787067861023i
-3.06758182489689 + 2.09961047697791i
2.38482681651969 + 4.88327784674562i
3.71317625428346 - 0.674037969249136i
-0.212684062587258 + 0.127085617245476i
2.16174758056324 + 1.04725923641435i
-0.0128016284267085 - 1.20550118120132i
-0.338432336750164 + 2.54841065708277i
2.53732707972096 + 0.359708926302334i
-0.775672552130784 + 0.365912343111928i
2.45931586744252 + 1.92877554774639i
-0.276534703962634 - 3.01315071721780i
-4.31838007965185 + 4.18173183306384i
4.54686817774770 + 5.00046801253062i
1.67052509268845 - 1.44291526425030i
0.494216471811413 + 2.84233764317402i
2.20477059738870 - 1.21426385106703i
-3.96764853651787 + 2.34622628122165i
3.85809982985414 + 5.46937641811437i
-0.527684387456332 - 2.49845418099316i
-3.97879406384973 + 8.95069642483800i
6.88875948700932 + 4.14225868238042i
-9.12359458464445 + 5.03410521169996i
9.90434329814591 + 33.1904512138980i

Теперь, чтобы преобразовать его в opencv с помощью функции dft(), вот что я сделал

#include<iostream>
#include<fstream>
#include<complex>
#include <opencv2/core/core.hpp>



using namespace std;
using namespace cv;

int main()
{
    ifstream fl("data.txt");


    float val = 0.0;
    float dataVal = 0.0;

    int M = 100;
    int N = 256;

    Mat data;

    // Some checking...
    if(!fl)
    {
        cout << "Could not read data file !. Exiting..." << endl;
        return 1;
    }

    // Read our noisy data into a matrix
    while(fl >> dataVal)
    {
        data.push_back(dataVal);
    }

    //****************Zero Padding*********************
    Mat dataPad = Mat::zeros(N,1,CV_32FC1);

    for(int i = 0; i < data.rows; i++)
    {
        dataPad.at<float>(i) = data.at<float>(i);
    }
    //****************End zero Padding******************


    Mat c;
    Mat d;
    dft(dataPad,c,DFT_COMPLEX_OUTPUT);

    cout << c << endl;

    return 0;
}

С кодом opencv я получаю значения результата как:

[45.859673, 0;
  9.9043427, -33.190449;
  -9.1235943, -5.0341053;
  6.8887596, -4.1422586;
  -3.9787939, -8.950696;
  -0.52768385, 2.4984541;
  3.8580999, -5.4693766;
  -3.9676485, -2.346226;
  2.2047706, 1.2142636;
  0.49421644, -2.8423376;
  1.6705251, 1.4429153;
  4.5468678, -5.0004683;
  -4.3183804, -4.1817312;
  -0.27653497, 3.0131505;
  2.4593158, -1.9287753;
  -0.77567172, -0.36591226;
  2.5373268, -0.35970855;
  -0.33843231, -2.5484109;
  -0.012800932, 1.2055011;
  2.1617475, -1.0472594;
  -0.21268401, -0.1270858;
  3.7131763, 0.67403829;
  2.3848267, -4.8832779;
  -3.0675817, -2.0996101;
  0.00069129467, 2.1078703;
  2.8516955, -0.37655008;
  1.2332697, -2.402;
  -0.31762052, -1.4890362;
  0.25194019, -0.64335132;
  0.0093064308, -1.180715;
  -0.50993007, -0.032992482;
  0.62074387, 0.17506447;
  0.30328292, 0.1790455;
  2.0659165, 0.69827104;
  1.9711246, -2.6989799;
  -2.4041266, -1.3790178;
  -0.20263243, 3.1075594;
  3.5092552, 1.2883899;
  3.2472734, -0.94089746;
  2.6432514, -2.1794367;
  1.3079934, -2.4782252;
  1.3259914, -2.6739581;
  -0.98622423, -3.6843452;
  -2.3739715, 0.086386234;
  1.7561252, 0.44013286;
  0.21787286, -3.2219501;
  -2.4285789, -0.24348021;
  0.8414849, 0.93391728;
  0.42274117, -1.932132;
  -2.1718223, -0.44796661;
  -0.53422636, 2.2624891;
  2.3459511, 0.99587536;
  1.2382859, -1.817889;
  -1.3138154, -0.43878132;
  0.2655696, 1.739308;
  1.8565477, 0.56328744;
  1.586129, -0.15123606;
  1.8689405, -0.68726492;
  1.1006303, -1.8668489;
  -0.89089596, -1.454439;
  -1.1131381, 1.3640884;
  2.305232, 2.0623293;
  2.8484609, -1.1562686;
  0.92818314, -0.6757369;
  2.8859835, -0.71372032;
  1.1284113, -3.5761924;
  -1.2317965, -1.0417366;
  0.92505932, -0.38755757;
  -0.16907227, -1.1636349;
  1.0156378, 0.56125128;
  1.9514127, -2.432827;
  -1.878549, -1.7748275;
  0.17650753, 1.5354227;
  2.0056989, -0.93365103;
  0.28423253, -1.2602149;
  0.58909744, -0.97569865;
  -0.49103725, -0.74379516;
  0.90682238, 1.0472198;
  2.4821229, -1.0711014;
  0.83096313, -1.3915272;
  2.6714797, -1.0232389;
  2.1719074, -5.2156334;
  -3.3741097, -5.0968595;
  -4.3890228, -0.019241691;
  -1.3166432, 1.5356154;
  -0.65354478, 0.87774885;
  0.52950221, 2.068718;
  3.1646068, -0.16074491;
  0.37547803, -2.5841308;
  0.1292572, 0.52969253;
  3.2263327, -2.5594907;
  -2.9204228, -4.9801998;
  -3.9000978, 2.758683;
  3.6779933, 1.9934752;
  1.7346549, -4.2365279;
  -2.8441062, -2.2480862;
  -1.6090539, 1.1270874;
  1.4232746, 0.4688811;
  0.47272092, -2.9854898;
  -3.4903586, -1.0777055;
  -0.79599231, 2.5982544;
  1.4671355, 0.0016607046;
  -0.065115452, -0.3998251;
  0.56147325, -0.40049303;
  -0.79304993, -0.38399071;
  1.043321, 1.7434461;
  3.2437129, -1.3723691;
  1.0307595, -2.9191318;
  0.72794068, -3.8038878;
  -3.5853515, -4.6707206;
  -4.470746, 1.2419586;
  0.65958107, 0.54467773;
  -2.1444774, -2.7011158;
  -4.0270004, 0.84917492;
  -1.834505, 2.5447512;
  0.60819596, 2.474251;
  1.3015544, -1.1315759;
  -3.1392064, -0.39051461;
  0.20029259, 3.4979796;
  1.5086112, -1.7898697;
  -3.7239809, 0.71492398;
  1.8240362, 3.4724047;
  0.35217285, -2.7617524;
  -4.351572, 2.8852968;
  3.1335518, 5.3676848;
  4.2565765, -0.41402435;
  2.7163055, -1.7123489;
  -0.019128323, -4.4018335;
  -4.7993603, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0;
  0, 0]

Вопрос в том, почему я получаю конечные нулевые значения с кодом opencv? Как получить точный результат в виде кода Matlab FFT? я что-то тут упускаю...


person tarmizi    schedule 21.05.2015    source источник


Ответы (1)


Вы почти у цели. Просто пропустил, чтобы включить воображаемую плоскость, в которой все нули.

Mat planes[] = {Mat_<float>(dataPad), Mat::zeros(dataPad.size(), CV_32F)};
Mat complexI;
merge(planes, 2, complexI);

dft(complexI, complexI, DFT_COMPLEX_OUTPUT);
std::cout << complexI ;

Менее важным является то, что способ заполнения OpenCV заключается в использовании copyMakeBorder и getOptimalDftSize.

Mat dataPadded; //expand input image to optimal size
int m = getOptimalDFTSize( data.rows );
int n = getOptimalDFTSize( data.cols );
// on the border add zero values
copyMakeBorder(data, dataPadded, 0, m - data.rows, 0, n - data.cols, BORDER_CONSTANT, Scalar::all(0));
person kiranpradeep    schedule 21.05.2015
comment
Спасибо... Означает ли это, что для сложной матрицы мнимая часть хранится в другом канале/плоскости? Не могли бы вы немного осветить это? - person tarmizi; 21.05.2015
comment
@tarmizi Да, сложная часть находится на другом канале. Это еще один канал даже для результата (если мы не используем DFT_REAL_OUTPUT для обратного преобразования). Я не очень понимаю, почему так получилось, что последние 128 элементов в вашем вводе были пропущены ранее. - person kiranpradeep; 21.05.2015