HS and LK Robust Optical flow - matlab

I am trying to make LK and HS original algorithm robust using Black & Anandan Lorentzian method
I did not know how to apply this concept in my MATLAB code ! ... and when I tried to apply what I know I got worse results than the original HS
I will attach my MATLAB code ... if any one have any idea how to do it ... or where is my mistakes .. I will be appreciate it
this code read 4 gray images (i0, i1, i2, i3)
the actual robustness process in perform_reg_iter ( I tried to applied to data and smoothing term ) but it gives me worse flow than the original method
function [regularized_u,regularized_v]=regularization_robust (i0,i1,i2,i3)
alpha=10.0;
numpass=100;
ROBUST_FLAG = true;
[pic_x, pic_y]=size(i0);
I=cell(1,2);
I{1,1}=double(box_filter(i0,i1,i2));
I{1,2}=double(box_filter(i1,i2,i3));
%Simocelli
[Ix,Iy,It]=apply_Simoncelli_filters(I{1,1},I{1,2});
[row, col]= size(Ix);
%%%caculate the flow %%%%%%
[regularized_u,regularized_v]= calc_intensity_regularization_flow(Ix,Iy,It,alpha,numpass, ROBUST_FLAG);
%%%%% print output
end
function [seq]=box_filter(seq1,seq2,seq3)
box(1)=0.25;
box(2)=0.5;
box(3)=0.25;
seq=box(1)*seq1+box(2)*seq2+box(3)*seq3;
temp=imfilter(seq,box,'same','conv','symmetric');
seq=imfilter(temp,box','same','conv','symmetric');
end % box_filter
function [Ix,Iy,It]=apply_Simoncelli_filters(I1,I2)
It=I2-I1;
gd=[1 -8 0 8 -1]/12;
Ix=-imfilter(I1,gd,'conv','symmetric','same');
Iy=-imfilter(I1,gd','conv','symmetric','same');
end
% Robust function
function [y]= robust_functions (type, x, sigma, order)
switch (type)
case 'lorentzian'
switch (order)
case 0
y = log(1 + x.^2 / (2 * sigma^2));
case 1
y = 2 * x ./ (2 * sigma^2 + x.^2);
if (2 * sigma^2 + x.^2) ==0
y = 100;
end
case 2
y = 2 ./ (2 * sigma^2 + x.^2);
end
case 'quadratic'
switch (order)
case 0
y = x.^2 / sigma^2;
case 1
y = 2 * x / sigma^2;
case 2
y = repmat(2 / sigma^2, size(x));
end
otherwise
error('Invalid robust function type.');
end
end
function [regularized_u,regularized_v]=...
calc_intensity_regularization_flow(Ix,Iy,It,alpha,numpass,ROBUST_FLAG)
regularized_u=zeros(size(Ix),'double');
regularized_v=zeros(size(Iy),'double');
% Perform iterations
for iter_no=0:2:numpass
[u2,v2]=perform_reg_iter(regularized_u,regularized_v,...
Ix,Iy,It,alpha,ROBUST_FLAG);
[regularized_u,regularized_v]=perform_reg_iter(u2,v2,Ix,Iy,It,...
alpha,ROBUST_FLAG);
end
end
function [u,v]=perform_reg_iter(u,v,Ix,Iy,It,alpha,ROBUST_FLAG)
kernel_1=[1/12 1/6 1/12;1/6 0 1/6;1/12 1/6 1/12];
estimator_weight=0.0;
robust_type= 'lorentzian'; % 'lorentzian'; % charbonnier
% (0) original ... (1) first derivative ... (2) 2 ./ (2 * sigma^2 + x.^2)
% in Sun paper
robust_order=2;
uAvg=conv2(u,kernel_1,'same');
vAvg=conv2(v,kernel_1,'same');
if (ROBUST_FLAG)
% Smoothing term
% robust_sigma =1; %0.03 in Sun paper
%uAvg = feval('robust_functions',robust_type,uAvg,robust_sigma,robust_order);
%vAvg = feval('robust_functions',robust_type,vAvg,robust_sigma,robust_order);
%Data term
robust_sigma=0.01; % 1.5 in Sun paper
value = Ix.*u + Iy.*v + It;
estimator_weight =
feval('robust_functions',robust_type,value,robust_sigma,robust_order);
Ix= Ix.* estimator_weight;
Iy= Iy.* estimator_weight;
It= It.* estimator_weight;
end
u= uAvg - ( Ix .* ( ( Ix .* uAvg ) + ( Iy .* vAvg ) + It ) ) ./ ...
( alpha^2 + Ix.^2 + Iy.^2);
v= vAvg - ( Iy .* ( ( Ix .* uAvg ) + ( Iy .* vAvg ) + It ) ) ./ ...
( alpha^2 + Ix.^2 + Iy.^2);
end
Without Robust calculation I got this results
with the robust I got this result

Related

Confirm that ( x + d/dx ) exp( -x^2 / 2 ) = 0 [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have written a small code that is supposed to verify that ( x + d/dx ) exp(-x^2 / 2 ) = 0. The idea is to use a Fourier series exp( 2 * pi j n x / L ) with sufficiently large L to represent the Gaussian and perform the operation there.
The algorithm in Matlab works as follows:
function[] = verify
epsilon = 0.05; % step-size numerical integration
N = 40; % number of Fourier coefficients
L = 30; % window length numerical integration Fourier basis
X = -L / 2:epsilon:L / 2; % grid
xFourier = zeros(2 * N + 1); %Allocate space for Fourier coefficients of f(x)=x
inix = zeros(2 * N + 1); % Allocate space for Fourier coefficients of f(x)=exp(-x^2/2)
% Compute Fourier coefficients of f(x)=x
for i1=-N:N
A = X.*exp(-2 * pi * 1i * i1. * X / L ) / sqrt( L );
xFourier(i1 + ( N + 1 ) ) = trapz( X, A );
end
% Compute Fourier coefficients of f(x)=exp(-x^2/2)
for i1 = -N : N
A = 1 / sqrt(L) * exp(-X.^2 / 2 ). * exp(-2 * pi * 1i * i1. * X / L );
inix( i1 + N + 1 ) = trapz( X, A ); % These are the Fourier coefficients of the |x|^2*Gaussian part
end
TO = Hamilton( N, xFourier, L );
norm( TO * inix' )
end
So the heart of the above algorithm is the function Hamilton that I am calling, it contains the matrix representation of the operator x d/dx, which is why norm( TO * inix' ) should return something close to zero, but it does not(?) and the function Hamilton is as follows
function [ Hamilton ] = Hamilton( N, xFourier, L)
Hamilton = zeros( ( 2 * N + 1 ),( 2 * N + 1 ) );
for i1 = -N : N
for i2 = -N : N
if i1 == i2
Hamilton(
(i1 + ( N + 1 ) ), ( i2 + ( N + 1 ) )
) = Hamilton(
( i1 + ( N + 1)),( i2 + ( N + 1 ) )
) + 1i * 2 * pi / L * i1;
end
if abs( i2 - i1 ) <= N
Hamilton(
( i1 + ( N + 1 ) ), ( i2 + ( N + 1 ) )
) = Hamilton(
(i1 + ( N + 1 ) ), ( i2 + ( N + 1 ) )
) + xFourier( i1 - i2 + ( N + 1 ) );
end
end
end
end
Does anybody see a mistake?
While not into Matlab , I somewhat miss a few terms in the code, like the factor 2 pi j k for the derivative. So here I put a Python version of what I think it should look like (sorry for the Python, but I guess it translates to Matlab quite easily):
import numpy as np
## non-normalized gaussian with sigma=1
def gauss( x ):
return np.exp( -x**2 / 2 )
## interval on which the gaussian is evaluated
L = 10
## number of sampling points
N = 21
## sample rate
dl = L / N
## highest frequency detectable
kmax= 1 / ( 2 * dl )
## array of x values
xl = np.linspace( -L/2, L/2, N )
## array of k values
kl = np.linspace( -kmax, kmax, N )
## matrix of exponents
## the Fourier transform is defined via sum f * exp( -2 pi j k x)
## i.e. the 2 pi is in the exponent
## normalization is sqrt(N) where n is the number of sampling points
## this definition makes it forward-backward symmetric
## "outer" also exists in Matlab and basically does the same
exponent = np.outer( -1j * 2 * np.pi * kl, xl )
## linear operator for the standard Fourier transformation
A = np.exp( exponent ) / np.sqrt( N )
## nth derivative is given via partial integration as ( 2 pi j k)^n f(k)
## every row needs to be multiplied by the according k
B = np.array( [ 1j * 2 * np.pi * kk * An for kk, An in zip( kl, A ) ] )
## for the part with the linear term, every column needs to be multiplied
## by the according x or--as here---every row is multiplied element
## wise with the x-vector
C = np.array( [ xl * An for An in A ] )
## thats the according linear operator
D = B + C
## the gaussian
yl = gauss( xl )
## the transformation with the linear operator
print( np.dot( D, yl ).round( decimals=9 ) )
## ...results in a zero-vector, as expected
provides:
[ 0.+4.61e-07j 0.-3.75e-07j 0.+1.20e-08j 0.+3.09e-07j -0.-5.53e-07j
0.+6.95e-07j -0.-7.28e-07j 0.+6.54e-07j -0.-4.91e-07j -0.+2.62e-07j
-0.+0.00e+00j -0.-2.62e-07j -0.+4.91e-07j -0.-6.54e-07j 0.+7.28e-07j
-0.-6.95e-07j 0.+5.53e-07j -0.-3.09e-07j 0.-1.20e-08j 0.+3.75e-07j
0.-4.61e-07j]
This is basically zero.

how to improve the running speed of this Matlab code?

I am trying to simulate a motion of some particles.The program seems to be very slow.
I just started lean programming so I dont know where is the problem exactly that make it slow, I think that plotting is take much time.
could some sone suggest me how to improve it?
function folks(N , T)
if nargin < 1
N = 50;
T = 100;
end
A=20;R=50;a=100;r=2;
x0=10*randn(3,N);
v0=0*randn(3,N);
clear c
% Initilazing plot
color = hsv(N);
xh=zeros(1,N);
f=2*max(max(x0));ff=f/1000000;
figure(2),clf
set(gcf,'doublebuffer','on')
hold on, grid on, axis([-1 1 -1 1 -.5 .5]*f)
for j = 1:N
xh(j) = line(x0(1,j),x0(2,j),x0(3,j),'color',color(j,:), ...
'marker','.','markersize',15);
end
title('t = 0','fontsize',18)
rotate3d;
view([1.8,-1.8,1])
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Solving the ode system
tol = 3e-14;
opts = odeset('reltol',tol,'abstol',tol);
X0=[x0(:);v0(:)];
dt=T/1000;
for tnext = dt:dt:10*T
tspan = [tnext-dt tnext];
[T1,X1] = ode45(#odefolk,tspan,X0,opts,r,R,a,A);
X0 = X1(end,:);
if max(abs(X0(1:3*N)))>f
f=1.1*f;
axis([-1 1 -1 1 -1 1]*f)
end
for j=0:N-1
set(xh(j+1),'xdata',X0(3*j+1),'ydata',X0(3*j+2),'zdata',X0(3*j+3))
end
title(sprintf('t = %3.0f %5.0e',tnext),'fontsize',18),
drawnow
end
I tried to save the data in a matrix and then plot every thing in new loop but it make it much slower.
And also its not related to the solver ode45 or the system odefolk
function dx = fkt(~,x,r,R,a,A)
n = length(x); % n = 90 = 6 *N
M = n/6; % M= 15
dx = zeros(n,1);
for i = 1 : 3 : n/2
vx = 0 ; vy = 0 ; vz = 0;
for j = 1 : 3 : n/2
if (i~=j)
vx = x(i) - x(j) ;
vy = x(i+1) - x(j+1);
vz = x(i+2) - x(j+2);
% ex = expo (vx , vy , vz ,r , a);
%
% val = (ex(1) * R - ex(2) * A);
leng = sqrt(vx^ 2 +vy^ 2 + vz^ 2);
expo1 = exp(-1 * leng / r) / r;
expo2 = exp(-1 * leng / a) / a;
val = (expo1 * R - expo2 * A);
vx = vx * val;
vy = vy * val;
vz = vz * val;
end
end
vx = vx/M ;
vy = vy/M;
vz = vz/M;
dx(i) = x(i + 3 * M );
dx(i + 1) = x(i + 3 * M + 1);
dx(i + 2) = x(i + 3 * M + 2);
dx(i + 3 * M ) = vx;
dx(i + 3 * M + 1 ) = vy;
dx(i + 3 * M + 2 ) = vz;
end
end
To perform a code, it's a good idea to analyze it with the Profiler:
https://es.mathworks.com/help/matlab/ref/profile.html
Anyway, I see some things you could change. First, avoid to draw in each iteration. Do it in the end or draw every M interations.
Secondly, avoid using a loop to define the graphic. Plot it with vector type input data.
Thirdly, ode45 can do the iterations for you and can return you a vector with all the interations. Use it to plot.
Some tips:
use tic and toc to measure the execution time of your code (lines, functions, etc.)
preassign arrays and avoid letting them grow in loops
do not use plot in a loop. Try to use low-level commands and change the value of exisiting lines by refering to their handles (like for example handle = line([0 1][2 3][4 5]) and then set(handle,'XDATA',[4 7],'YDATA',[2 6],'ZDATA',[2 4]))
MATLAB is an interpreted language, so your code will run slower in most cases compared to compiled programs

Matlab - Creating two arrays that consider all possible values for two objects

I have two physical "objects." I am representing their positions with two different arrays.
• Object 1 moves in the xy-plane only
• Object 2 moves in all three physical dimensions
Objective: Vectorize the four for loops without distorting the data. Also, the intent is to perform this operation for all possible values of object 1 to be compared with object 2.
Here is the code snippet:
Npos = 21;
Nsam = 200;
% dummy initialisation
AX = rand(1, Npos);
AY = zeros(1, Npos);
AZ = rand(1, Npos);
Bx = rand(Nsam);
By = rand(Nsam);
Bz = rand(Nsam);
for qx = 1 : Npos
for yx = 1 : Npos
for zx = 1 : Nsam
for cx = 1 : Nsam
Tx2Array( qx, yx, zx, cx ) = sqrt( ( AX( qx ) - Bx( zx, cx ) ).^2 + ( AY( yx ) - By( zx, cx ) ).^2 + ( AZ( yx ) - Bz( zx, cx ) ).^2 );
end
end
end
end
% Result is a 21 x 21 x 200 x 200 matrix filled with all real numbers
Legend
AX, AY, AZ are 1 x 21 arrays and represent the (x,y=0,z) of Object 1
AY is all zeros, but for readability is still included (hence no fifth loop!)
Bx, By, Bz are all 200 x 200 arrays and represent the (x,y,z) of Object 2
Npos = 21; Nsam = 200;
The formula used above is:
sqrt( (a1-b1)^2 + (a2-b2)^2 + (a3-b3)^2 )
If you have the Statistics Toolbox available, you can use pdist2 to calculate the distance between each coordinate for Object 1 and each coordinate for Object 2:
[X1, Z1] = ndgrid(AX(:), AZ(:)); % X1 and Z1 will be 21x21
D = pdist2([X1(:), zeros(size(X1(:))), Z1(:)], [Bx(:), By(:), Bz(:)]);
The output in this case will be a 441 x 40,000 array where D(i, j) gives you the distance between point i of Object 1 and point j of Object 2, both using linear indexing.
You can avoid the to inner loops by replacing zx and cx with : as follows:
Tx2Array = zeros(Npos, Npos, Nsam, Nsam); % preallocate memory
for qx = 1 : Npos
for yx = 1 : Npos
Tx2Array( qx, yx, :, : ) = sqrt( ( AX( qx ) - Bx( :, : ) ).^2 + ( AY( yx ) - By( :, : ) ).^2 + ( AZ( yx ) - Bz( :, : ) ).^2 );
end
end
In this way, the largest dimensions are vectorised. So, the largest improvement is already done.
By converting your B* to 4D and generating a mesh for your A* matrices, you can even remove all the for loops as follows:
[AX_, AZ_] = meshgrid(AX, AZ);
AX_ = AX_';
AZ_ = AZ_';
AY_ = zeros(Npos);
Bx_(1, 1, :, :) = Bx;
By_(1, 1, :, :) = By;
Bz_(1, 1, :, :) = Bz;
Tx2Array2 = sqrt( ( AX_ - Bx_ ).^2 + ( AY_ - By_ ).^2 + ( AZ_ - Bz_ ).^2 );
You can check the the results are the same using the following check:
max(max(max(max(abs(Tx2Array - Tx2Array2))))) < eps
If the arrays are correctly initialized your task will be very simple:
Initialize the arrays with the correct dimensions
AX = rand( Npos,1);
AY = zeros(1, Npos);
AZ = rand(1, Npos);
Bx = rand(1,1,Nsam,Nsam);
By = rand(1,1,Nsam,Nsam);
Bz = rand(1,1,Nsam,Nsam);
Then in MATLAB r2016b / Octave you can simply write:
Tx2Array = sqrt( ( AX - Bx ).^2 + ( AY - By ).^2 + ( AZ - Bz ).^2 );
In pre r2016b you can use bsxfun:
Tx2Array = sqrt(bsxfun(#plus,bsxfun(#plus,bsxfun(#minus,AX , Bx).^2,bsxfun(#minus,AY , By).^2),bsxfun(#minus,AZ , Bz).^2));

Intersection point between circle and line (Polar coordinates)

I'm wondering if there is a way of finding the intersection point between a line and a circle written in polar coordinates.
% Line
x_line = 10 + r * cos(th);
y_line = 10 + r * sin(th);
%Circle
circle_x = circle_r * cos(alpha);
circle_y = circle_r * sin(alpha);
So far I've tried using the intersect(y_line, circle_y) function without any success. I'm relatively new to MATLAB so bear with me.
I have generalised the below so that other values than a=10 can be used...
a = 10; % constant line offset
th = 0; % constant angle of line
% rl = ?? - variable to find
% Coordinates of line:
% [xl, yl] = [ a + rl * cos(th), a + rl * sin(th) ];
rc = 1; % constant radius of circle
% alpha = ?? - variable to find
% Coordinates of circle:
% [xc, yc] = [ rc * cos(alpha), rc * sin(alpha) ];
We want the intersection, so xl = xc, yl = yc
% a + rl * cos(th) = rc * cos(alpha)
% a + rl * sin(th) = rc * sin(alpha)
Square both sides of both equations and sum them. Simplifying sin(a)^2 + cos(a)^2 = 1. Expanding brackets and simplifying further gives
% rl^2 + 2 * a * rl * (cos(th) + sin(th)) + 2 * a - rc^2 = 0
Now you can use the quadratic formula to get the value of rl.
Test discriminant:
dsc = (2 * a * (cos(th) + sin(th)) )^2 - 4 * (2 * a - rc^2);
rl = [];
if dsc < 0
% no intersection
elseif dsc == 0
% one intersection at
rl = - cos(th) - sin(th);
else
% two intersection points
rl = -cos(th) - sin(th) + [ sqrt(dsc)/2, -sqrt(dsc)/2];
end
% Get alpha from an earlier equation
alpha = acos( ( a + rl .* cos(th) ) ./ rc );
Now you have 0, 1 or 2 points of intersection of the line with the circle, from certain known and unknown values about each line. Essentially this is just simultaneous equations, see the start of this article for a basis of the maths
https://en.wikipedia.org/wiki/System_of_linear_equations
Do you need to do it numerically? This problem would have an easy analytical solution: The point (10 + r*cos(th),10 + r*sin(th)) is on a circle with radius R iff
(10+r*cos(th))^2 + (10+r*sin(th))^2 == R^2
<=> 200+r^2 + 2*r*(cos(th)+sin(th)) == R^2
<=> r^2 + 2*r*sqrt(2)*sin(th+pi/4) + 200 - R^2 = 0
which is a quadratic equation in r. If the discriminant is positive, there are two solutions (corresponding to two intersection points), otherwise, there are none.
If you work out the math, the condition for intersection is 100*(sin(2*th)-1)+circle_r^2 >= 0 and the roots are -10*sqrt(2)*sin(th+pi/4)*[1,1] + sqrt(100*(sin(2*th)-1)+circle_r^2)*[1,-1].
Here is a Matlab plot as an example for th = pi/3 and circle_r = 15. The magenta markers are calculated in closed-form using the equation shown above.

Gabor Phase ?? my values are too small

Hi every one >> hope you all are doing fine
I wanted to ask you about calculating the phase values for an image ,, you see I used the Gabor wavlet like so :
k = ( Kmax / ( f ^ v ) ) * exp( 1i * u * pi / 8 );% Wave Vector
kn2 = ( abs( k ) ) ^ 2;
GW = zeros ( R , C );
for m = -R/2 + 1 : R/2
for n = -C/2 + 1 : C/2
GW(m+R/2,n+C/2) = ( kn2 / Delt2 ) * exp( -0.5 * kn2 * ( m ^ 2 + n ^ 2 ) / Delt2) * ( exp( 1i * ( real( k ) * m + imag ( k ) * n ) ) - exp ( -0.5 * Delt2 ) );
end
end
I=imread('a.pgm');
Myimage=conv2(I,double(GW),'same');
then I called the image and the filter with different orientations and scales and stored the phase in P then I wanted to quantize it with rang 4 i:
close all;
clear all;
clc;
% Parameter Setting
R = 32;
C = 32;
Kmax = pi;
f = sqrt( 2 );
Delt = 2 * pi;
Delt2 = Delt * Delt;
% Show the Gabor Wavelets
for v=1:7 %v = 1 : 7
for u = 1:5 % u= 1: 5
[GW,Myimage]= GaborWavelet ( R, C, Kmax, f, u, v, Delt2 ); % Create the Gabor wavelets
figure;
subplot( 5, 8, v * 7 + u ),imshow ( real( GW ) ,[]); % Show the real part of Gabor wavelets
end
figure ;
subplot( 1, 5, v + 1 ),imshow ( abs( GW ),[]); % Show the magnitude of Gabor wavelets
end
%clear I;
R=real(GW);
I=imag(GW);
M=abs(Myimage);
P=atan(imag(Myimage)/real(Myimage)); <<<< is this even right ??
%P=atan(I/R);
save P P;
[xx,yy] = size (P);
DATA =zeros(size(P));
for i=1:48
for j=1:48
for zz=1:3
if (360* zz/4) <= abs(P(i,j))&& abs(P(i,j))<(360*(zz+1)/4)
DATA(i,j)=zz ; end;
end;
end;
end;
save DATA DATA ;
But the data is so small like : -1.49279186693682 1.50990968797986 -1.39225915272978 0.966151874072431
which leads to quantized value of 0 >> Where did I go wrong
I think values seem small because they are given in radians and you expect them in degrees. As for getting the magnitude and angle of a complex number, take a look at http://www.mathworks.fr/fr/help/matlab/ref/angle.html.
I quote:
"For complex Z, the magnitude R and phase angle theta are given by
R = abs(Z)
theta = angle(Z)"
Z would be your GW.
Hope this helps!