how to Convert Matlab fft function to cvDft in opencv - matlab

I'm Very new to opencv.I need to convert the code from matlab to opencv.i have problem with use fft in matlab.i have a one dimensional matrix a.and i'm going apply fft in that as given below.
a = [0;0;0;0;0;0;0;0;0.09707;0.0998;0.1202;-0.1606;-0.0913;0.1523;0.1288];
c = abs(fft(a,15));
c >> 0.3463
0.1056
0.3608
0.5705
0.4232
0.2407
0.1486
0.1488
0.1488
0.1486
0.2407
0.4232
0.5705
0.3608
0.1056
C is my result,which i got from matlab.while i'm going to use cvDFT for this one the results are differnt.please help me with some example..my c code is given below...
CvMat* fftin = cvCreateMat(nn,1,CV_64FC2);
CvMat* fftout = cvCreateMat(nn,1,CV_64FC2);
cvZero(b); ////consider a hav the value of mat b is empty for imgin
cvMerge(a,b,NULL,NULL,fftin);
cvDFT(fftin,fftout,CV_DXT_FORWARD,0);
cvSplit(fftout,out_real,out_img,0,0);
for (int i = 0;i<out_real->rows;i++)
{
double val11= cvGetReal2D(out_real,i,0);
double val12= cvGetReal2D(out_img,i,0);
val11 = abs(val11);
val12 = abs(val12);
printf("DFT value is:%f %f\n",val11,val12);
cvSetReal2D(C_out,i,0,val11);
}

In your first example, you seem to be printing the magnitude of each complex value in the result. But in your second example you seem to be printing the absolute value of each component of the complex values (e.g. X and Y instead of the length or hypotenuse).

Related

Implementing my own FFT in MATLAB giving wrong results

I'm trying to implement my own fft in MATLAB the following way:
function z=FastFourierTransform(x)
N=length(x);
if N <= 1
z = x;
else
range = (0:N/2-1);
e = exp(-2i*pi/N).^range;
odd = FastFourierTransform(x(1:2:N-1));
even = e.*FastFourierTransform(x(2:2:N));
z = [even + odd, even - odd];
end
return
Turns out, there seems to be somthing wrong with it since it does not give the same result as the built in function provided by MATLAB.
I'm calling the function the following way:
N = 128;
x = 32*pi*(1:N)'/N;
u = cos(x/16).*(1+sin(x/16));
actualSolution = fft(u);
actualSolution
mySolution = FastFourierTransform(u)';
mySolution
actualSolution
mySolution
The numbers are always the same but they sometimes differ in their sign.
You have swapped odd and even.
Using this line to compute z will produce the correct FFT:
z = [odd + even, odd - even];
My guess is that the source of confusion is that Matlab uses 1-based indices, and the pseudocode you used to implement the function uses 0-based indices.

How to resolve MATLAB trapz function error?

I am working on an assignment that requires me to use the trapz function in MATLAB in order to evaluate an integral. I believe I have written the code correctly, but the program returns answers that are wildly incorrect. I am attempting to find the integral of e^(-x^2) from 0 to 1.
x = linspace(0,1,2000);
y = zeros(1,2000);
for iCnt = 1:2000
y(iCnt) = e.^(-(x(iCnt)^2));
end
a = trapz(y);
disp(a);
This code currently returns
1.4929e+03
What am I doing incorrectly?
You need to just specify also the x values:
x = linspace(0,1,2000);
y = exp(-x.^2);
a = trapz(x,y)
a =
0.7468
More details:
First of all, in MATLAB you can use vectors to avoid for-loops for performing operation on arrays (vectors). So the whole four lines of code
y = zeros(1,2000);
for iCnt = 1:2000
y(iCnt) = exp(-(x(iCnt)^2));
end
will be translated to one line:
y = exp(-x.^2)
You defined x = linspace(0,1,2000) it means that you need to calculate the integral of the given function in range [0 1]. So there is a mistake in the way you calculate y which returns it to be in range [1 2000] and that is why you got the big number as the result.
In addition, in MATLAB you should use exp there is not function as e in MATLAB.
Also, if you plot the function in the range, you will see that the result makes sense because the whole page has an area of 1x1.

issue with surface with MATLAB

a = 10:100
b = 10:100
c = power(a,b)
surf(a,b,c)
=> Error using surf (line 78)
Z must be a matrix, not a scalar or vector
any clue ?
Here's a vectorized way using bsxfun:
a = 10:100;
b = 1:.1:10; %// changed b to avoid very large numbers
c = bsxfun(#power, a, b.');
surf(a,b,c)
c=power(a,b) does not give you the combinations of all a power b, unfortunately.
Here there is a way of doing it (though most likely there is a vectorizedd way of doing it)
a = 10:100;
b = linspace(1,10,length(a));
% I changed the values of b, because 100^100 is that a big number that Matlab will not plot it, it is too big for storing in a double
%loop and save
for ii=1:length(b)
c(ii,:)=a.^(b(ii));
end
surf(a,b,c)

Error: Matrix dimensions must agree for plot

having a problem with my "new love", matlab: I wrote a function to calculate an integral using the trapz-method: `
function [L]=bogenlaenge_innen(schwingungen)
R = 1500; %Ablegeradius
OA = 1; %Amplitude
S = schwingungen; %Schwingungszahl
B = 3.175; %Tapebreite
phi = 0:2.*pi./10000:2.*pi;
BL = sqrt((R-B).^2+2.*(R-B).*OA.*sin(S.*phi)+OA.^2.*(sin(S.*phi)).^2+OA.^2.*S.^2.*(cos(S.*phi)).^2);
L = trapz(phi,BL)`
this works fine when i start it with one specific number out of the command-window. Now I want to plot the values of "L" for several S.
I did the following in a new *.m-file:
W = (0:1:1500);
T = bogenlaenge_innen(W);
plot(W,T)
And there it is:
Error using .*
Matrix dimensions must agree.
What is wrong? Is it just a dot somewhere? I am using matlab for the second day now, so please be patient.... ;) Thank you so much in advance!
PS: just ignore the german part of the code, it does not really matter :)
In your code, the arrays S and phi in the expression sin(S.*phi) should have same size or one of them should be a constant in order the code works
The error is most likely because you have made it so that the number of elements in schwingungen, i.e. W in your code, must be equal to the number of elements in phi. Since size(W) gives you a different result from size(0:2.*pi./10000:2.*pi), you get the error.
The way .* works is that is multiplies each corresponding elements of two matrices provided that they either have the same dimensions or that one of them is a scalar. So your code will work when schwingungen is a scalar, but not when it's a vector as chances are it has a different number of elements from the way you hard coded phi.
The simplest course of action (not necessarily the most Matlabesque though) for you is to loop through the different values of S:
W = (0:1:1500);
T = zeros(size(W); %Preallocate for speed)
for ii = 1:length(W)
T(ii) = bogenlaenge_innen(W(ii));
end
plot(W,T)
In your function you define phi as a vector of 10001 elements.
In this same function you do S.*phi, so if S is not the same length as phi, you will get the "dimensions must agree" error.
In your call to the function you are doing it with a vector of length 1501, so there is your error.
Regards

How to use aryule() in Matlab to extend a number series?

I have a series of numbers. I calculated the "auto-regression" between them using Yule-Walker method.
But now how do I extend the series?
Whole working is as follows:
a) the series I use:
143.85 141.95 141.45 142.30 140.60 140.00 138.40 137.10 138.90 139.85 138.75 139.85 141.30 139.45 140.15 140.80 142.50 143.00 142.35 143.00 142.55 140.50 141.25 140.55 141.45 142.05
b) this data is loaded in to data using:
data = load('c:\\input.txt', '-ascii');
c) the calculation of the coefficients:
ar_coeffs = aryule(data,9);
this gives:
ar_coeffs =
1.0000 -0.9687 -0.0033 -0.0103 0.0137 -0.0129 0.0086 0.0029 -0.0149 0.0310
d) Now using this, how do I calculate the next number in the series?
[any other method of doing this (except using aryule()) is also fine... this is what I did, if you have a better idea, please let me know!]
For a real valued sequence x of length N, and a positive order p:
coeff = aryule(x, p)
returns the AR coefficients of order p of the data x (Note that coeff(1) is a normalizing factor). In other words it models values as a linear combination of the past p values. So to predict the next value, we use the last p values as:
x(N+1) = sum_[k=0:p] ( coeff(k)*x(N-k) )
or in actual MATLAB code:
p = 9;
data = [...]; % the seq you gave
coeffs = aryule(data, p);
nextValue = -coeffs(2:end) * data(end:-1:end-p+1)';
EDIT: If you have access to System Identification Toolbox, then you can use any of a number of functions to estimate AR/ARMAX models (ar/arx/armax) (or even find the order of AR model using selstruc):
m = ar(data, p, 'yw'); % yw for Yule-Walker method
pred = predict(m, data, 1);
coeffs = m.a;
nextValue = pred(end);
subplot(121), plot(data)
subplot(122), plot( cell2mat(pred) )
Your data has a non-zero mean. Doesn't the Yule-Walker model assume the data is the output of a linear filter excited by a zero-mean white noise process?
If you remove the mean, this example using ARYULE and LPC might be what you're looking for. The procedure boils down to:
a = lpc(data,9); % uses Yule-Walker modeling
pred = filter(-a(2:end),1,data);
disp(pred(end)); % the predicted value at time N+1