let us consider following code taken from
http://www.mathworks.com/matlabcentral/fileexchange/45848-stockwell-transform--s-transform-/content/stran.m
to compute S transform, here is my code
function ST=stran(h)
% Compute S-Transform without for loops
%%% Coded by Kalyan S. Dash %%%
%%% IIT Bhubaneswar, India %%%
[~,N]=size(h); % h is a 1xN one-dimensional series
nhaf=fix(N/2);
odvn=1;
if nhaf*2==N;
odvn=0;
end
f=[0:nhaf -nhaf+1-odvn:-1]/N;
Hft=fft(h);
%Compute all frequency domain Gaussians as one matrix
invfk=[1./f(2:nhaf+1)]';
W=2*pi*repmat(f,nhaf,1).*repmat(invfk,1,N);
G=exp((-W.^2)/2); %Gaussian in freq domain
% End of frequency domain Gaussian computation
% Compute Toeplitz matrix with the shifted fft(h)
HW=toeplitz(Hft(1:nhaf+1)',Hft);
% Exclude the first row, corresponding to zero frequency
HW=[HW(2:nhaf+1,:)];
% Compute Stockwell Transform
ST=ifft(HW.*G,[],2); %Compute voice
%Add the zero freq row
st0=mean(h)*ones(1,N);
ST=[st0;ST];
end
and consider following chirp signal
>> t = 0:0.001:2;
x = chirp(t,100,1,200,'quadratic');
i need confirmation that i am doing correctly following things
>> ST=stran(x);
>> plot(abs(ST))
?
picture is here
Posting my comment as answer:
I don't have much idea of the s-transform, but AFAIK the result of it is a 3D signal (as you can clearly see in the size of ST), so you may want to do imagesc(abs(ST)) or surf(abs(ST),'linestyle','none') instead of plot.
In your figure you have plotted 1000 lines, that's why its so chaotic.
Using
imagesc(abs(ST))
Related
I will keep the explanation, how my codes works, very short. I advise you to try this code yourself, so perhaps you understand it better that way. I have an audio-file and read it in my code. Now i switch from the time domain to the frequency domain by using the function FFT. But the only difference is, that i am performing an STFT on my audio signal. I do it every 30ms, until to the length of my signal. I am aware, that there are many different function in matlab, which also can perform this easily, but there are not giving me the results i need. Now, i am plotting many different frequency spectrums every 30ms. But i split up my signal in three frequency bands. They are called LOW, MEDIUM and HIGH. Basically, this means I have 3 different spectrums plotting every 30ms. The next step I do, is summing all the magnitudes from ONE frequency spectrum together, this means I have ONE VALUE per frequency spectrum, which are being squared.
Now, i have the power from every spectrum ! And all of these values are being plotted in my code. I am only plotting the power values, otherwise my code performance time would be extremely slow.
Btw, the code looks long, but there are two for loop. In the first, i read the low spectrum and when it is finished, the second starts with the medium and high spectrum. Basically they are the same. I am aware, i can probably do that with findpeaks or something similar. But how can i write/pull that of? Or what the necessary steps to do that. At the end, i included a file, Hopefully you can see that.
I want to measure the peaks and get the distance between them from the red plot.
EDIT:
Ok, i got the peaks, but not in the way i imagined. I want to show the peaks, which are above 5000-line. Sorry for not being clear at the beginning. See my plot, what i mean. I want to say my code, that only the peaks should be measured, which are above the 5000-line.
[pks, locs] = findpeaks(ValuesOfYc);
p=plot(x,ValuesOfYc,'r-' ,x(locs), pks,'ob');
This is, what I did above, in my first loop. How should i go on from there?
clear;
clc;
%% MATLAB
%% read file
%_________________________________________
[y,fs]=audioread('Undertale - Megalovania.wav');
% audioread = read wav -file
% y = contains the audio signal
% fs = 44100
% 'UnchainMyHeart' = name of the wav-file
%_________________________________________
%% PARAMETER FOR STFT
%_________________________________________
t_seg=0.03; % length of segment in ms
fftlen = 4096; %FFT-Points
% Defining size of frequency bands
f_low= 1:200; %lower frequencies
f_medium= 201:600; %medium frequencies
f_high= 601:1000; %higher frequencies
%__________________________________________
%% CODE
segl =floor(t_seg*fs);
windowshift=segl/2;
% defining the size of the window shift
window=hann(segl);
% apply hann function on segment length (30 ms)
window=window.';
% transpose vector
si=1;
% defining start index
ei=segl;
% defining end index
N=floor( length(y)/windowshift - 1);
% Calculates the number, how often the window has to shift
% until to length of the audio signal
f1=figure;
% Generating new window
f=0:1:fftlen-1;
f=f/fftlen*fs;
% defining frequency vector
Ya=zeros(1,fftlen);
ValuesOfYc = NaN(1,N);
ValuesOfYd = NaN(1,N);
ValuesOfYe = NaN(1,N);
x =(1:N)*windowshift/fs;
% defining x-axis
for m= 1:1:N
y_a = y(si:ei);
% a segment is taken out from audio signal length(30ms)
y_a= y_a.*window;
% multiplying segment with window (hanning)
Ya=fft(y_a, fftlen);
% Applying fft on segment
Yb=abs(Ya(1:end/2)).^2;
% Squaring the magnitudes from one-sided spectrum
drawnow; % Updating the graphical values
figure(f1);
% Showing the power values
%% frequency bands
y_low = Yb(f_low); % LOW frequency spectrum
Yc=sum(y_low);
% Summing all the power values from one frequency spectrum together
% so you get one power value from one spectrum
ValuesOfYc(m) = Yc;
%Output values are being saved here, which are generated from the for
%loop
% m = start variable from for loop
[pks, locs] = findpeaks(ValuesOfYc);
subplot(2,1,1)
p=plot(x,ValuesOfYc,'r-', x(locs(pks>=5000)), pks(pks>=5000),'ob');
p(1).LineWidth =0.5;
xlabel('time (Audio length)')
ylabel('Power')
grid on
si=si+windowshift;
% Updating start index
ei=ei+windowshift;
% Updating end index
end
for o= 1:1:N
y_a = y(si:ei);
% a segment is taken out from audio signal length(30ms)
y_a= y_a.*window;
% multiplying segment with window (hanning)
Ya=fft(y_a, fftlen);
% Applying fft on segment
Yb=abs(Ya(1:end/2)).^2;
% Squaring the magnitudes from one-sided spectrum
drawnow; % Updating the graphical values
figure(f1);
% Showing the power values
[![enter image description here][1]][1]
%% frequency bands
y_medium = Yb(f_medium); % MEDIUM frequency spectrum
y_high = Yb(f_high); % HIGH frequency spectrum
Yd=sum(y_medium);
Ye=sum(y_high);
% Summing all the power values from one frequency spectrum together
% so you get one power value from one spectrum
ValuesOfYd(o) = Yd;
ValuesOfYe(o) = Ye;
%Output values are being saved here, which are generated from the for
%loop
% m = start variable from for loop
subplot(2,1,2)
p=plot(x, ValuesOfYd,'g-', x, ValuesOfYe,'b-' );
p(1).LineWidth =0.5;
xlabel('time (Audio length)')
ylabel('Power')
grid on
si=si+windowshift;
% Updating start index
ei=ei+windowshift;
% Updating end index
end
I'm trying to understand how the FFT in matlab works, particularly, how to define the frequency range to plot it. It happens that I have read from matlab help links and from other discussions here and I think (guess) that I'm confused about it.
In the matlab link:
http://es.mathworks.com/help/matlab/math/fast-fourier-transform-fft.html
they define such a frequency range as:
f = (0:n-1)*(fs/n)
with n and fs as:
n = 2^nextpow2(L); % Next power of 2 from length of signal x
fs = N/T; % N number of samples in x and T the total time of the recorded signal
But, on the other hand, in the previous post Understanding Matlab FFT example
(based on previous version of matlab), the resulting frequency range is defined as:
f = fs/2*linspace(0,1,NFFT/2+1);
with NFFT as the aforementioned n (Next power of 2 from length of signal x).
So, based on that, how these different vectors (equation 1 and final equation) could be the same?
If you can see, the vectors are different since the former has n points and the later has NFFT/2 points! In fact, the factor (fs/n) is different from fs/2.
So, based on that, how these different vectors (equation 1 and final equation) could be the same?
The example in the documentation from Mathworks plots the entire n-point output of the FFT. This covers the frequencies from 0 to nearly fs (exactly (n-1)/n * fs). They then make the following observation (valid for real inputs to the FFT):
The first half of the frequency range (from 0 to the Nyquist frequency fs/2) is sufficient to identify the component frequencies in the data, since the second half is just a reflection of the first half.
The other post you refer to just chooses to not show that redundant second half. It then uses half the number of points which also cover half the frequency range.
In fact, the factor (fs/n) is different from fs/2.
Perhaps the easiest way to make sense of it is to compare the output of the two expressions for some small value of n, says n=8 and setting fs=1 (since fs multiplies both expressions). On the one hand the output of the first expression [0:n-1]*(fs/n) would be:
0.000 0.125 0.250 0.500 0.625 0.750 0.875
whereas the output of fs/2*linspace(0,1,n/2+1) would be:
0.000 0.125 0.250 0.500
As you can see the set of frequencies are exactly the same up to Nyquist frequency fs/2.
The confusion is perhaps arising from the fact that the two examples which you have referenced are plotting results of the fft differently. Please refer to the code below for the references made in this explanation.
In the first example, the plot is of the power spectrum (periodogram) over the frequency range. Note, in the first plot, that the periodogram is not centered at 0, meaning that the frequency range appears to be twice that of the Nyquist sampling frequency. As mentioned in the mathworks link, it is common practice to center the periodogram at 0 to avoid this confusion (figure 2).
For the second example, taking the same parameters, the original plot is of amplitude of the fourier spectrum with a different normalization than in the first example (figure 3). Using the syntax of Matlab's full frequency ordering (as commented in the code), it is trivial to convert this seemingly different fft result to that of example 1; the identical result of the 0-centered periodogram is replicated in figure 4.
Thus, to answer your question specifically, the frequency ranges in both cases are the same, with the maximum frequency equal to the Nyquist sampling frequency as in:
f = fs/2*linspace(0,1,NFFT/2+1);
The key to understanding how the dfft works (also in Matlab) is to understand that you are simply performing a projection of your discrete data set into fourier space where what is returned by the fft() function in matlab are the coefficients of the expansion for each frequency component and the order of the coefficients is given (in Matlab as in example 2) by:
f = [f(1:end-1) -fliplr(f(1,2:end))];
See the Wikipedia page on the DFT for additional details:
https://en.wikipedia.org/wiki/Discrete_Fourier_transform
It might also be helpful for you to take the fft omitting the length as a power of 2 parameter as
y = fft(x).
In this case, you would see only a few non-zero components in y corresponding to the exact coefficients of your input signal. The mathworks page claims the following as a motivation for using or not using this length:
"Using a power of two for the transform length optimizes the FFT algorithm, though in practice there is usually little difference in execution time from using n = m."
%% First example:
% http://www.mathworks.com/help/matlab/math/fast-fourier-transform-fft.html
fs = 10; % Sample frequency (Hz)
t = 0:1/fs:10-1/fs; % 10 sec sample
x = (1.3)*sin(2*pi*15*t) ... % 15 Hz component
+ (1.7)*sin(2*pi*40*(t-2)); % 40 Hz component
% Removed the noise
m = length(x); % Window length
n = pow2(nextpow2(m)); % Transform length
y = fft(x,n); % DFT
f = (0:n-1)*(fs/n); % Frequency range
power = y.*conj(y)/n; % Power of the DFT
subplot(2,2,1)
plot(f,power,'-o')
xlabel('Frequency (Hz)')
ylabel('Power')
title('{\bf Periodogram}')
y0 = fftshift(y); % Rearrange y values
f0 = (-n/2:n/2-1)*(fs/n); % 0-centered frequency range
power0 = y0.*conj(y0)/n; % 0-centered power
subplot(2,2,2)
plot(f0,power0,'-o')
% plot(f0,sqrt_power0,'-o')
xlabel('Frequency (Hz)')
ylabel('Power')
title('{\bf 0-Centered Periodogram} Ex. 1')
%% Second example:
% http://stackoverflow.com/questions/10758315/understanding-matlab-fft-example
% Let's redefine the parameters for consistency between the two examples
Fs = fs; % Sampling frequency
% T = 1/Fs; % Sample time (not required)
L = m; % Length of signal
% t = (0:L-1)*T; % Time vector (as above)
% % Sum of a 3 Hz sinusoid and a 2 Hz sinusoid
% x = 0.7*sin(2*pi*3*t) + sin(2*pi*2*t); %(as above)
NFFT = 2^nextpow2(L); % Next power of 2 from length of y
% NFFT == n (from above)
Y = fft(x,NFFT)/L;
f = Fs/2*linspace(0,1,NFFT/2+1);
% Plot single-sided amplitude spectrum.
subplot(2,2,3)
plot(f,2*abs(Y(1:NFFT/2+1)),'-o')
title('Single-Sided Amplitude Spectrum of y(t)')
xlabel('Frequency (Hz)')
ylabel('|Y(f)|')
% Get the 0-Centered Periodogram using the parameters of the second example
f = [f(1:end-1) -fliplr(f(1,2:end))]; % This is the frequency ordering used
% by the full fft in Matlab
power = (Y*L).*conj(Y*L)/NFFT;
% Rearrange for nicer plot
ToPlot = [f; power]; [~,ind] = sort(f);
ToPlot = ToPlot(:,ind);
subplot(2,2,4)
plot(ToPlot(1,:),ToPlot(2,:),'-o')
xlabel('Frequency (Hz)')
ylabel('Power')
title('{\bf 0-Centered Periodogram} Ex. 2')
I wrote the following code as an implementation to the registration algorithm presented in an article named:"E. Arce-Santana, D. Campos-Delgado and A. Alba, Affine image registration guided by particle filter, IET Image Process. 6 (2012)".
Question 1: When I run the code no matter how many particles or iterations I choose, the output is still inaccurate. I do not know what is the problem?
Question 2: I commented a formula for updating the particle's weight, my question is, does I implement the equation write or the one that appears above it (which relied on the entropy) is the right one and therefore delete the commented one and leave the entropy based equation?
The code is as follow:
%% clear everything
clear all
close all
clc
%% Read the image data
% I1: Reference Image
I1=imread('cameraman.tif');
I1=double(imresize(I1,[256 256]));
figure,imshow(I1)
[I1r I1c I1d]=size(I1);
%I2: Target image
I2=randomtransform(I1); %user-defined function to generate random transformation
% I2=double(imresize(I2,[I1r I1c]));
figure,imshow(I2)
%% Particle Filter Steps:
%%%%% Input:
n=4; % Related to the initialization
m=256; % Related to the initialization
N=20; %(no. of iteration)
M=100; %(no. of particles)
phai=[]; %(state vector of the affine transformation parameters)
w=[]; %(the vector of the phai weights)
%k: iteration no.
%i: particle no.
Vk=1; % noise variance in the system (Used in the predection state)
w_v=1; % weights update equation related variance
beta=0.99; % annealing factor
%%%%% Output
phai_est=[]; %(Final estimated state vector of affine parameters)
%%%%% Steps:
%%% Step 1: Random generation of the particles
% The ranges are obtained from the paper
rotationAngle=double(int8(unifrnd(-pi/4,pi/4,1,1)));
scalingCoefX = double(unifrnd(0.5,2,1,1));
scalingCoefY = double(unifrnd(0.5,2,1,1));
shearingCoefX = double(unifrnd(0.5,2,1,1));
shearingCoefY = double(unifrnd(0.5,2,1,1));
translationCoefX = double(int8(unifrnd(-I1r/2,I1r/2,1,1)));
translationCoefY = double(int8(unifrnd(-I1c/2,I1c/2,1,1)));
%The initialization of the first phai
phai(1,:)=[round(rotationAngle*10^n)/10^n, round(scalingCoefX*10^n)/10^n, round(scalingCoefY*10^n)/10^n, round(shearingCoefX*10^n)/10^n, round(shearingCoefY*10^n)/10^n, round(translationCoefX*10^n)/10^n, round(translationCoefY*10^n)/10^n]';
%Make the randomly generated particles from the initial prior gaussian distribution
for i = 1:M
phai(i,:) = phai(1,:) + sqrt(2) * randn; %2: the variance of the initial esimate
w(i,:)=1/M;
end
% Normalize the weights:
w = w./sum(w);
%%% Step2: Resample process
for k=1:N
for i=1:M
% rand: u (Uniform random value between 0 and 1
j=find((cumsum(w) >= max(w)),1,'first');
phai_select(i,:)=phai(j,:);
phai(i,:)=phai_select(i,:)+(sqrt(Vk^2)*randn);
I2_new=targettransform(I2,phai(i,:)); %user-defined function to apply the generated transformation to the target image
E_I1=entropy(I1);
I=E_I1+entropy(I2_new)-joint_entropy(I1,I2_new); %joint_entropy: user defined function to calculate joint entropy of the two images
w(i)=(1/sqrt(2*pi*w_v))*exp(-((E_I1-I)^2)/(2*w_v));
% w(i)=prod(prod(((1/sqrt(2*pi*w_v))*exp(-((I2_new-I1)^2)/(2*w_v)))));
end
% Normalize the weights
w = w./sum(w);
% Reduce the noise standard deviation
Vk=beta*Vk;
phai_est=mean(phai);
end
I am trying to get an MLP to work. My goal is to get the net to predict output Yt when given Yt-1,Yt-2...,Yt-10. I've been using a generated dataset, which should be no trouble. My net will always output a straight line and will shift that line up and down. The line is always flat everywhere, it does not start to curve. My target is a portion of a sin(x) curve.
This is my code:
Dataset:
% Underlying function
syms f(a)
f(a)=sin(a/50);
% Data: lagged
x=[1:100+10]';
% add noise
y=eval(f(x))+0.01*randn(numel(x),1);
% rescale dataset to [0,1]
y=(y-min(y))/(max(y)-min(y));
% Lagged predictor
X=[];
for L=1:10
temp=lagmatrix(y,-L);
X=horzcat(X,temp);
end
% train set size m
y_training=y(1:100);
X_training=X(1:100,:);
Training:
%% Network
% Initialize weights
W1=randn(10,10)/10; Wb1=randn(10,1)/10;
W2=randn(10,10)/10; Wb2=randn(10,1)/10;
W3=randn(1,10)/10; Wb3=randn(1,1)/10;
% Activation function
syms f(z);
f(z)=1/(1+exp(-z));
Df=diff(f);
% Net parameters
alpha=3;
lambda=0;
costs=[];
m=numel(y_training); % size of training set
no_iter=500; % number of iterations of grad descent
p=1;
for j=1:no_iter
%Initialize error
deltaW1=zeros(size(W1)); deltaWb1=zeros(size(Wb1));
deltaW2=zeros(size(W2)); deltaWb2=zeros(size(Wb2));
deltaW3=zeros(size(W3)); deltaWb3=zeros(size(Wb3));
JW=0;
keep_output=[];
for i=1:m
% input layer
a1=[X_training(i,:)']; y_true=y_training(i);
% FP activations
z2=[W1 Wb1]*[a1; 1]; a2=eval(f(z2));
z3=[W2 Wb2]*[a2; 1]; a3=eval(f(z3));
z4=[W3 Wb3]*[a3; 1]; a4=eval(f(z4));
% BP individual errors
delta_a4= -(y_true-a4) .* eval(Df(z4));
delta_a3= W3'*delta_a4 .* eval(Df(z3));
delta_a2= W2'*delta_a3 .* eval(Df(z2));
% DJDW for each parameter
DJDW3=delta_a4*(a3)'; DJDWb3=delta_a4;
DJDW2=delta_a3*(a2)'; DJDWb2=delta_a3;
DJDW1=delta_a2*(a1)'; DJDWb1=delta_a2;
% summing DJDW of each example
deltaW1=deltaW1+DJDW1; deltaWb1=deltaWb1+DJDWb1;
deltaW2=deltaW2+DJDW2; deltaWb2=deltaWb2+DJDWb2;
deltaW3=deltaW3+DJDW3; deltaWb3=deltaWb3+DJDWb3;
% Cost function
JW_xy=(y_true-a4)^2; % single example
JW=JW+JW_xy; % aggregate
% store output and true values
keep_output=[keep_output a4];
end
% update weights according to average cost of current iteration
W1=W1-alpha*( (1/m)*deltaW1) ; Wb1=Wb1-alpha*( (1/m)*deltaWb1);
W2=W2-alpha*( (1/m)*deltaW2) ; Wb2=Wb2-alpha*( (1/m)*deltaWb2);
W3=W3-alpha*( (1/m)*deltaW3) ; Wb3=Wb3-alpha*( (1/m)*deltaWb3);
clf, plot(y_training), hold on
plot(keep_output);
drawnow
end
It only seemed that the backpropagation algorithm wasn't working. What I observed was a line shifting up and down with each iteration. The problem was I wasn't scaling the output.
Given that I scaled the input dataset, the output should also be scaled.
I need some advice on some AAM e.g. coding that I trying to understand. The result were unable to complete since an error occur that said that the Matlab is out of memory:
Error using zeros
Out of memory. Type HELP MEMORY for your options.
In the coding that causes the error was:
Error in AAM_MakeSearchModel2D (line 6)
drdp=zeros(size(ShapeAppearanceData.Evectors,2)+4,6,length(TrainingData),length(AppearanceData.g_mean));
the actual data in the drpd are:
drdp=zeros(13,6,10,468249);
Since the 4th array is large, it's understandable that the Matlab that I was using which is 32bit is out of memory. The output that the code will produce is a 2d. Here is the code that will later use the drpd:
drdpt=squeeze(mean(mean(drdp,3),2));
R=pinv(drdpt)';
The question that i want to ask is, is it possible to split the 4D matrices into smaller ones (e.g. 2D or 3D) and do normal addition and division (to get mean). If yes, how would one do it?
edited 17/12/2013
I cannot used sparse since the 4D drpd is an initialization for obtaining another whole calculation that stored all weighted errors of model versus real into the drpd. I copy the part of the AAM function that calculate this drpd:
function R=AAM_MakeSearchModel2D(ShapeAppearanceData,ShapeData,AppearanceData,TrainingData,options)
% Structure which will contain all weighted errors of model versus real
% intensities, by several offsets of the parameters
drdp=zeros(size(ShapeAppearanceData.Evectors,2)+4,6,length(TrainingData),length(AppearanceData.g_mean));
% We use the trainingdata images, to train the model. Because we want
% the background information to be included
% Loop through all training images
for i=1:length(TrainingData);
% Loop through all model parameters, bot the PCA parameters as pose
% parameters
for j = 1:size(ShapeAppearanceData.Evectors,2)+4
if(j<=size(ShapeAppearanceData.Evectors,2))
% Model parameters, offsets
de = [-0.5 -0.3 -0.1 0.1 0.3 0.5];
% First we calculate the real ShapeAppearance parameters of the
% training data set
c = ShapeAppearanceData.Evectors'*(ShapeAppearanceData.b(:,i) -ShapeAppearanceData.b_mean);
% Standard deviation form the eigenvalue
c_std = sqrt(ShapeAppearanceData.Evalues(j));
for k=1:length(de)
% Offset the ShapeAppearance parameters with a certain
% value times the std of the eigenvector
c_offset=c;
c_offset(j)=c_offset(j)+c_std *de(k);
% Transform back from ShapeAppearance parameters to Shape parameters
b_offset = ShapeAppearanceData.b_mean + ShapeAppearanceData.Evectors*c_offset;
b1_offset = b_offset(1:(length(ShapeAppearanceData.Ws)));
b1_offset= inv(ShapeAppearanceData.Ws)*b1_offset;
x = ShapeData.x_mean + ShapeData.Evectors*b1_offset;
pos(:,1)=x(1:end/2);
pos(:,2)=x(end/2+1:end);
% Transform the Shape back to real image coordinates
pos=AAM_align_data_inverse2D(pos,TrainingData(i).tform);
% Get the intensities in the real image. Use those
% intensities to get ShapeAppearance parameters, which
% are then used to get model intensities
[g, g_offset]=RealAndModel(TrainingData,i,pos, AppearanceData,ShapeAppearanceData,options,ShapeData);
% A weighted sum of difference between model an real
% intensities gives the "intensity / offset" ratio
w = exp ((-de(k)^2) / (2*c_std^2))/de(k);
drdp(j,k,i,:)=(g-g_offset)*w;
end
else
% Pose parameters offsets
j2=j-size(ShapeAppearanceData.Evectors,2);
switch(j2)
case 1 % Translation x
de = [-2 -1.2 -0.4 0.4 1.2 2]/2;
case 2 % Translation y
de = [-2 -1.2 -0.4 0.4 1.2 2]/2;
case 3 % Scaling & Rotation Sx
de = [-0.2 -.12 -0.04 0.04 0.12 0.2]/2;
case 4 % Scaling & Rotation Sy
de = [-0.2 -.12 -0.04 0.04 0.12 0.2]/2;
end
for k=1:length(de)
tform=TrainingData(i).tform;
switch(j2)
case 1 % Translation x
tform.offsetv(1)=tform.offsetv(1)+de(k);
case 2 % Translation y
tform.offsetv(2)=tform.offsetv(2)+de(k);
case 3 % Scaling & Rotation Sx
tform.offsetsx=tform.offsetsx+de(k);
case 4 % Scaling & Rotation Sy
tform.offsetsy=tform.offsetsy+de(k);
end
% From Shape tot real image coordinates, with a certain
% pose offset
pos=AAM_align_data_inverse2D(TrainingData(i).CVertices, tform);
% Get the intensities in the real image. Use those
% intensities to get ShapeAppearance parameters, which
% are then used to get model intensities
[g, g_offset]=RealAndModel(TrainingData,i,pos, AppearanceData,ShapeAppearanceData,options,ShapeData);
% A weighted sum of difference between model an real
% intensities gives the "intensity / offset" ratio
w =exp ((-de(k)^2) / (2*2^2))/de(k);
drdp(j,k,i,:)=(g-g_offset)*w;
end
end
end
end
% Combine the data to the intensity/parameter matrix,
% using a pseudo inverse
% for i=1:length(TrainingData);
% drdpt=squeeze(mean(drdp(:,:,i,:),2));
% R(:,:,i) = (drdpt * drdpt')\drdpt;
% end
% % Combine the data intensity/parameter matrix of all training datasets.
% %
% % In case of only a few images, it will be better to use a weighted mean
% % instead of the normal mean, depending on the probability of the trainingset
% R=mean(R,3);
drdpt=squeeze(mean(mean(drdp,3),2));
R=pinv(drdpt)';
%R = (drdpt * drdpt')\drdpt;
As you can see in the final code of the function, the 4D drpd is then squeeze and then calculate again to become a 2D matrices store in R. Because of 'Out of Memory' problem, the function cannot initialize the drpd because it used to much space (the drdp=zeros(13,6,10,468249)). Can I stored the data in a 2D or 3D form (split the drpd part) and then do simple addition and division to get the mean and then finally get the 'R'?
Thank you, and sorry for the long question.
I guess you want to use some sparse representation if many elements ofdrdpremain zero.
Matlab'ssparsecommand only creates 2D matrices though so something like this might work?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/167669
Once you get that to work you can worry about computing means --
apart from requiring a little bookkeeping that should be doable.