# Hilbert transform using FFT

Im trying to calculate Hilbert transform using openCv base on matlab/ octave code

function y = hilbert(x)
if nargin != 1, usage("y = hilbert(x)"); endif
if !isreal(x), error("hilbert: requires real input vector"); endif
transpose = rows(x)==1;
if transpose, x=x.'; endif
[r, c] = size(x);
n=2^nextpow2(r);
if r < n, x = [ x ; zeros(n-r, c) ]; endif
y = fft(x);
y = ifft([y(1,:) ; 2*y(2:n/2,:) ; y(n/2+1,:) ; zeros(n/2-1,columns(y))]);
if r < n, y(r+1:n,:) = []; endif
if transpose, y = y.'; endif
endfunction


and my c++ code

#include <opencv2/core.hpp>
#include <opencv2/core/eigen.hpp>
#include "Eigen/Dense"
class HilbertTransformTest{

private:

cv::Mat CreateFilter(cv::Mat &data)const {
cv::Mat factor = cv::Mat::ones( data.rows, data.cols, CV_32FC2 );

for (int i=0; i<data.rows; ++i){
for (int j=1; j<data.cols/2; ++j){
factor.at<cv::Vec2f>(i, j)[0] = 2;
factor.at<cv::Vec2f>(i, j)[1] = 2;
factor.at<cv::Vec2f>(i, data.cols-j)[0] = 0;
factor.at<cv::Vec2f>(i, data.cols-j)[1] = 0;
}
}
return factor;
}

cv::Mat GetComplexMat(cv::Mat &Data) const {
cv::Mat planes[] = {cv::Mat_<float>(Data), cv::Mat::zeros(Data.size(), CV_32F)};
cv::Mat complexI;
cv::merge(planes, 2, complexI);
return complexI;
}

cv::Mat GenerateData() const {
Eigen::Matrix<float, -1, -1, Eigen::RowMajor> Data(1, 256);
cv::Mat Vis;
for (int iter = 0; iter < Data.cols(); ++iter) {
double t = double(iter) / 255.0 * 10.0;
Data(0, iter) = std::sin(2 * CV_PI * 0.5 * t);
}
cv::eigen2cv(Data, Vis);
return Vis;
}

public:
HilbertTransformTest() {

cv::Mat Data = GenerateData();
cv::Mat Kernel = CreateFilter(Data);
cv::Mat ComplexData = GetComplexMat(Data);
cv::Mat rfSpectrum;
cv::dft(ComplexData, rfSpectrum, cv::DFT_COMPLEX_OUTPUT);
cv::multiply(rfSpectrum, Kernel, rfSpectrum, 1.0, CV_32FC2);
cv::idft(rfSpectrum, ComplexData,  cv::DFT_ROWS + cv::DFT_COMPLEX_OUTPUT + cv::DFT_SCALE);

cv::Mat planes[2];
cv::split(ComplexData, planes);
cv::Mat REAL = planes[0];
cv::Mat IMAG = cv::abs(planes[1]);

}
};


After ifft I should obtain shifted by Pi / 2 signal (IMAG) and copy of signal in REAL, but imaginary part is in absolute values

When i run Octave ifft Im getting good answer, and input to function is same. Why there is a difference and how to get result like in Octave (no abs values in imaginary part of signal?

edit retag close merge delete