Ramping values of a matrix smoothly down to zero around its edges - matlab

Hi I am looking for some help to optimize some Matlab code. I have an input matrix M, which is Ny rows by Nx columns. I would like to define a boundary all the way round the edge of the matrix where the values should be attenuated smoothly down to zero. To do this, I attempted to define a masking function MSK and multiply it point by point to get an output N, shown below:
My attempt above was created using the code below, where I use a cosine squared function to get the smooth drop off from 1 to zero:
%%% Set up some grids %%%
Nx = 128;
Ny = 64;
dx = 0.1;
dy = 0.1;
x = -(Nx*dx/2):dx:(Nx*dx/2-dx);
y = -(Ny*dy/2):dy:(Ny*dy/2-dy);
x = permute(x, [1 2 3]); % Creates a [1 x Nx x 1] vector (saves memory)
y = permute(y, [2 1 3]); % Creates a [Ny x 1 x 1] vector
M = complex( double( rand(Ny,Nx)+10 ) ); % Create some input data
bnd_frac = 0.7; % The fraction of the grid to begin masking boundary, i.e 70% of the grid max
MSK = create_mask_function(x,y,Nx,Ny,bnd_frac); % Create masking function
N = M.*MSK; % Apply mask to input data, to smoothly ramp edges to zero
figure;
subplot(1,3,1);imagesc(x,y, abs(M) )
subplot(1,3,2);imagesc(x,y, abs(MSK) )
subplot(1,3,3);imagesc(x,y, abs(N) )
%%%%%%%%%%%%%%%%%%%%%%%%
%%% Masking Function %%%
%%%%%%%%%%%%%%%%%%%%%%%%
function MSK = create_mask_function(x,y,Nx,Ny,bnd_frac)
[~,bndind_x] = min( abs(x - bnd_frac*x(Nx)) ); % Find the index to begin the masking
x_bound = x(bndind_x); % Find the grid coordinate to begin masking
[~,bndind_y] = min( abs(y - bnd_frac*y(Ny)) );
y_bound = y(bndind_y);
dbnd_xp = x(Nx) - x_bound; % Find the width of the boundary region at each edge
dbnd_xm = x(1) + x_bound;
dbnd_yp = y(Ny) - y_bound;
dbnd_ym = y(1) + y_bound;
MSK = ones(Ny,Nx); % Initialise the mask matrix as ones
% Set the values within each boundary region at the edge to ramp smoothly to 0 from 1
MSK( : , x > x_bound ) = repmat( ( cos( ( x(x>+x_bound) - x_bound )/dbnd_xp * pi/2 ) ).^2 , Ny , 1);
MSK( : , x < -x_bound ) = repmat( ( cos( ( x(x<-x_bound) + x_bound )/dbnd_xm * pi/2 ) ).^2 , Ny , 1);
MSK( y > y_bound , : ) = repmat( ( cos( ( y(y>+y_bound) - y_bound )/dbnd_yp * pi/2 ) ).^2 , 1 , Nx);
MSK( y < -y_bound , : ) = repmat( ( cos( ( y(y<-y_bound) + y_bound )/dbnd_ym * pi/2 ) ).^2 , 1 , Nx);
MSK(:,Nx,:) = 0;
MSK(:,1,:) = 0;
MSK(Ny,:,:) = 0;
MSK(1,:,:) = 0;
end
The problem with the code above is that it allocates too much memory to MSK.
(In the real version of my code, all of of the matrices are 3D, and the sizes can be more like 1024x512x512 in reality, but I have made a simplifed 2D example here to help explain.)
Note that this is the reason that I am using permute() on the x and y vectors above, because other parts of my full code use Matlab's implicit expansion. This is to avoid storing 3D versions of x and y that have been generated using meshgrid().
It is clear in the above image that MSK contains mostly values of 1, and the ramping values only occur near the edges. So this seems like large waste of memory to store those 1's because their purpose is to just make sure the input matrix is not modified in the centre. Can anyone help me understand a way in Matlab to implement what I want but in a way that will use less RAM?

If you can't store, then you need to recompute the weights each time and use them on the fly.
The short answer then is that instead of some precomputing of MSK and then usage later, as:
MSK( : , x > x_bound ) = repmat( ( cos( ( x(x>+x_bound) - x_bound )/dbnd_xp * pi/2 ) ).^2 , Ny , 1);
etc()
...
N = M.*MSK
You want to just, on the fly:
N( : , x > x_bound ) = M( : , x > x_bound ).*repmat( ( cos( ( x(x>+x_bound) - x_bound )/dbnd_xp * pi/2 ) ).^2 , Ny , 1);
etc()
I'll leave how you restructure the code to you, but I'd basically just add the matrix M as input to your function, and rename it to "apply_mask" or something like that. There will likely be ways to optimize this further if needed, but "early optimization is the root of all evil".

Related

Finding the odd point in a dataset without using loops

I am given a set of points (p1,q1) (p2,q2) ... (p20,q20) which satisfy the function q = 1/(ap + b)^2 except that one of these does not satisfy the given relation. The values of a and b are not given to me. All I have with me is two inputs p and q as arrays. I need to find the index of the point which does not satisfy the given relation.
The way I proceeded to solve is to find the values of a and b using the first two pairs (p1,q1) and (p2,q2) and check if the remaining points satisfy the function for the solved values of a and b. The results will be stored in a logical matrix. I wish to make use of the logical matrix to pick out the odd pair, but unable to proceed further.
Specifically, the challenge is to make use of vectorization in MATLAB to find the odd point, instead of resorting to for-loops. I think that I will have to first search for the only logical zero in any of the row. In that case, the column index of that zero will fetch me the odd point. But, if there are more than one zeros in all 4 rows, then the odd point is either of the first two pairs. I need help in translating this to efficient code in MATLAB.
Please note that vectors p and q have been named as x and y in the below code.
function [res, sol] = findThePair(x, y)
N = length(x);
syms a b
vars = [a,b];
eqns = [y(1) - 1/(a*x(1) + b)^2 == 0; y(2) - 1/(a*x(2) + b)^2];
[solA, solB] = solve(eqns,vars);
sol = [double(solA) double(solB)]; %solution of a & b (total 4 possibilites)
xTest = x(3:end); % performing check on remaining points
yTest = y(3:end);
res = zeros(4, N-2); % logical matrix to store the results of equality check
for i = 1:4
A = sol(i,1); B = sol(i, 2);
res(i, :) = [yTest == 1./(A*xTest + B).^2]; % perform equality check on remaining points
end
Let's do some maths up front, to avoid needing loops or vectorisation. At most this leaves us with half a dozen function evaluations, and we only need 5 points.
q = 1 / (a*p + b)^2
% ->
sqrt(q) * ( a*p + b ) = 1
% ->
a = ( 1 - b*sqrt(q) ) / ( p * sqrt(q) )
% Sub in some points (1 and 2) ->
a1 = ( 1 - b*sqrt(q1) ) / ( p1 * sqrt(q1) )
a2 = ( 1 - b*sqrt(q2) ) / ( p2 * sqrt(q2) )
% a1 and a2 should be the same ->
( 1 - b*sqrt(q1) ) * ( p2 * sqrt(q2) ) = ( 1 - b*sqrt(q2) ) * ( p1 * sqrt(q1) )
% Rearrange ->
b = ( p2*sqrt(q2) - p1*sqrt(q1) ) / ( (p2-p1)*sqrt(q1)*sqrt(q2) )
We have two unknowns, a and b. All we need are two points to create simultaneous equations. I'll use the following logic
Choose (pm, qm) and (pn, qn) with any m ~= n.
Calculate a and b using the above equation.
test whether (pr, qr) fits with the calculated a and b.
If it fits, we know all three of these must be on the curve, and we have a and b.
If it doesn't fit, we know either point m, n, or r is the outlier. Return to step (1) with two other points, the calculated a and b must be correct, as we've not fitted to the outlier.
Here is some code to implement this:
% Random coeffs, keep things unknown
a = rand*10;
b = rand*10;
% Set up our data
p = 1:20;
q = 1 ./ (a*p + b).^2;
% Create an outlier
q( 3 ) = q( 3 ) + 1;
% Steps as described
% 1.
p1 = p(1); p2 = p(2);
q1 = q(1); q2 = q(2);
% 2.
bGuess = ( p2*sqrt(q2) - p1*sqrt(q1) ) / ( (p2-p1)*sqrt(q1)*sqrt(q2) );
aGuess = ( 1 - bGuess*sqrt(q1) ) / ( p1 * sqrt(q1) );
% 3.
p3 = p(3);
q3Guess = 1 / ( aGuess*p3 + bGuess )^2;
tol = 1e-7; % Use tolerance rather than == comparison to avoid float issues
if abs( q3Guess - q(3) ) < tol
% success
aFit = aGuess;
bFit = bGuess;
else
% p1, p2 or p3 is an outlier! Repeat using other points
% If there's known to be only one outlier, this should give the result
p1 = p(4); p2 = p(5);
q1 = q(4); q2 = q(5);
bFit = ( p2*sqrt(q2) - p1*sqrt(q1) ) / ( (p2-p1)*sqrt(q1)*sqrt(q2) );
aFit = ( 1 - bFit*sqrt(q1) ) / ( p1 * sqrt(q1) );
end
% Validate
fprintf( 'a is valid: %d, b is valid: %d\n', abs(a-aFit)<tol, abs(b-bFit)<tol )
I don't really understand how you were trying to solve this and what do syms (i.e. symbolic variables) have to do with this, so I'll show you how I would solve this problem.
Since we're essentially looking for an outlier, we might as well convert the problem to something that's easier to work with. For this reason, instead of using q as-is, I'm going to invert it: this way, we'd be dealing with an equation of a parabola - which is easy.
Next, knowing that our points should lie on a parabola, we can fit the equation of the parabola (or equivalently - find the coefficients of the polynomial that describes the relation of the input to the output). The polynomial is a^2*x^2+2*a*b*x+b^2, and so the coefficients are {a^2, 2*a*b, b^2}.
Since the majority of the points (19 out of 20) lie on the same parabola, the outlier will always have a larger error, which would make it stand out, no matter how close it is to the parabola (within the limitations of machine precision) - you can see an extreme example of this in the code below.
Fitting of a parabola is performed using polynomial interpolation (see also: Vandermonde matrix).
function I = q55241683()
%% Generate the ground truth:
TRUE_A = 2.3;
TRUE_B = -pi;
IDX_BAD = 5;
p = 1:0.04:1.76;
q = (TRUE_A * p + TRUE_B).^-2;
q(IDX_BAD) = (1-1E-10)*q(IDX_BAD); % notice just how close this is to being valid
%% Visualize dataset:
% figure(); plot(p,q.^-1);
%% Solve
I = findThePair(p, q.^-1);
%% Test
if IDX_BAD == I
disp('Great success!');
else
disp('Complete failure!');
end
end
function I = findThePair(x,y)
% Fit a parabola to {x vs. y^-1}
P = x(:).^(2:-1:0)\y(:); %alternatively: P = polyfit(x,y.^-1,2)
% Estimate {a,b} (or {-a,-b})
est_A = sqrt(P(1));
est_B = P(2)/(2*est_A);
% Compute the distances of the points from the fit (residuals), find the biggest:
[~,I] = max( abs(y - (est_A*x + est_B).^2) );
end

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));

Vector field over a 3D mesh

I am currently writing my own Matlab implementation of a paper from 2003, Fast Texture Synthesis on Arbitrary Mesh.
Everything is going quite well, except for the rotation part of the similarity transform, which implies the creation of a vector field accross the 3D surface. This is a very important part of the algorithm because it gives a more natural and coherent textural aspect all over the 3D surface.
The problem is, I just have no idea how to do this. Litterature I've found on the subject is quite obscur to me, so I'm now looking for a more pragmatic (and programmatic) way to perform this.
Any idea ?
[EDIT] Just in case that may be relevant, I tried this code, which use barycentric interpolation to map a texture image to a 3D mesh. HOWEVER, in the example given texture vertex indices are known beforehand, hence, as far as my understanding goes, I'm still stuck with the rotation part of the similarity transform between the texture image and the 3D mesh. I still need to create a vector field around the surface.
Finally, here is the code I wrote, about the texture preprocessing part of Magda and Kriegman algorithm :
%% Implementation inspired by the work of Magda & Kriegman(2003), "Fast Texture Synthesis on Arbitrary Mesh"
function [TextonImage, LUT, TextonBucket] = GenerateTextons( SampleImage, gaussianSize, nbKmeansCenters )
% Create Gaussian kernel
h = fspecial( 'gaussian', gaussianSize );
% Generate feature vectors
FeatureVectors = ComputeFeatureVectors( h, SampleImage );
% Perform k-mean clustering, classify feature vectors (i.e. assign labels)
[IDX,C] = kmeans( FeatureVectors, nbKmeansCenters );
% Create texton texture
LUT = randi( 255, size( C, 1 ), 3 );
[TextonImage, TextonBucket] = CreateTextonTexture( C, SampleImage, LUT, h );
end
function Vectors = ComputeFeatureVectors( Kernel, Image )
offset = floor( size( Kernel, 1 ) / 2 );
vectorsSize = ( size( Image, 1 ) - 2 * offset ) * ( size( Image, 2 ) - 2 * offset );
Vectors = zeros( vectorsSize, size( Kernel, 1 ) * size( Kernel, 1 ) );
kk = 1;
for ii = ( 1 + offset ):( size( Image, 1 ) - offset )
for jj = ( 1 + offset ):( size( Image, 2 ) - offset )
temp = Kernel .* double( Image( ii - offset:ii + offset, jj - offset:jj + offset ) );
Vectors( kk, : ) = reshape( temp, size( Kernel, 1 ) * size( Kernel, 1 ), 1 )';
kk = kk + 1;
end
end
end
function [ TextonImage, TextonBucket ] = CreateTextonTexture( Centroids, Image, LUT, Kernel )
offset = floor( size( Kernel, 1 ) / 2 );
TextonImage = zeros( size( Image, 1 ), size( Image, 2 ), 3 );
TextonBucket = struct;
IndexTable = zeros( size( Centroids, 1 ), 1 );
for ii = ( 1 + offset ):(size( Image, 1 ) - offset)
for jj = ( 1 + offset ):(size( Image, 2 ) - offset)
temp = Kernel .* double( Image( ii - offset:ii + offset, jj - offset:jj + offset ) );
Vector = reshape( temp, size( Kernel, 1 ) * size( Kernel, 1 ), 1 )';
minDist = 10000;
Index = 0;
for k=1:size( Centroids, 1 )
% Calculate distance of test point to training point.
d = sum( Vector - Centroids( k, : ) ) .^ 2;
% if smaller...
if d < minDist
minDist = d;
Index = k;
end
end
TextonImage( ii, jj, : ) = LUT( Index, : );
cellName = strcat('B',num2str(Index));
IndexTable( Index ) = IndexTable( Index ) + 1;
TextonBucket.(cellName){ IndexTable( Index ) } = [ jj, ii ];
end
end
end
Thank you.

Radon transform matrix representation

I am looking for a MATLAB solution to generate the matrix representation of a discrete Radon transform (DRT). That is, given a vectorized version of an MxN image, X, I'd like to generate the matrix R such that R*X(:) is a DRT of the image. In MATLAB, I am expecting it to look something like the following:
>> X = 2D_Image_Of_Size_MxN;
>> R = DRT_Matrix_Of_Size_LPxMN;
>> DRT = reshape( R * X(:), L, P );
I know there are several ways to define a DRT, so I'll just say that I am looking for a normal or standard or not-too-out-of-the-ordinary implmentation.
function [ R rho theta ] = radonmatrix( drho, dtheta, M, N )
% radonmatrix - Discrete Radon Trasnform matrix
%
% SYNOPSIS
% [ R rho theta ] = radonmatrix( drho, dtheta, M, N )
%
% DESCRIPTION
% Returns a matrix representation of a Discrete Radon
% Transform (DRT).
%
% INPUT
% drho Radial spacing the the DRT.
% dtheta Angular spacing of the DRT (rad).
% M Number of rows in the image.
% N Number of columns in the image.
%
% OUTPUT
% R LP x MN DRT matrix. The values of the L and
% P will depend on the radial and angular spacings.
% rho Vector of radial sample locations.
% theta Vector of angular sample locations (rad).
%
% For each angle, we define a set of rays parameterized
% by rho. We then find the pixels on the MxN grid that
% are closest to each line. The elements in R corresponding
% to those pixels are given the value of 1.
% The maximum extent of the region of support. It's for
% rho = 0 and theta = pi/4, the line that runs caddy-corner.
W = sqrt( M^2 + N^2 );
rho = -W/2 : drho : W/2;
theta = 0 : dtheta : 180 - dtheta;
L = length( rho );
P = length( theta );
R = false( L*P, M*N );
% Define a meshgrid w/ (0,0) in the middle that
% we can use a standard coordinate system.
[ mimg nimg ] = imggrid( 1, 1, [ M N ] );
% We loop over each angle and define all of the lines.
% We then just figure out which indices each line goes
% through and put a 1 there.
for ii = 1 : P
phi = theta(ii) * pi/180;
% The equaiton is rho = m * sin(phi) + n * cos(phi).
% We either define a vector for m and solve for n
% or vice versa. We chose which one based on angle
% so that we never g4et close to dividing by zero.
if( phi >= pi/4 && phi <= 3*pi/4 )
t = -W : min( 1/sqrt(2), 1/abs(cot(phi)) ) : +W;
T = length( t );
rhom = repmat( rho(:), 1, T );
tn = repmat( t(:)', L, 1 );
mline = ( rhom - tn * cos(phi) ) ./ sin(phi);
for jj = 1 : L
p = round( tn(jj,:) - min( nimg ) ) + 1;
q = round( mline(jj,:) - min( mimg ) ) + 1;
inds = p >= 1 & p <= N & q >= 1 & q <= M;
R( (ii-1)*L + jj, unique( sub2ind( [ M N ], q(inds), p(inds) ) ) ) = 1;
end
else
t = -W : min( 1/sqrt(2), 1/abs(tan(phi)) ) : +W;
T = length( t );
rhon = repmat( rho(:)', T, 1 );
tm = repmat( t(:), 1, L );
nline = ( rhon - tm * sin(phi) ) ./ cos(phi);
for jj = 1 : L
p = round( nline(:,jj) - min( nimg ) ) + 1;
q = round( tm(:,jj) - min( mimg ) ) + 1;
inds = p >= 1 & p <= N & q >= 1 & q <= M;
R( (ii-1)*L + jj, unique( sub2ind( [ M N ], q(inds), p(inds) ) ) ) = 1;
end
end
end
R = double( sparse( R ) );
return;
Here is the imggrid function used in the above.
function [ m n ] = imggrid( dm, dn, sz )
% imggrid -- Returns rectilinear coordinate vectors
%
% SYNOPSIS
% [ m n ] = imggrid( dm, dn, sz )
%
% DESCRIPTION
% Given the sample spacings and the image size, this
% function returns the row and column coordinate vectors
% for the image. Both vectors are centered about zero.
%
% INPUT
% dm Spacing between rows.
% dn Spacing between columns.
% sz 2x1 vector of the image size: [ Nrows Ncols ].
%
% OUTPUT
% m sz(1) x 1 row coordinate vector.
% n 1 x sz(2) column coordinate vector.
M = sz(1);
N = sz(2);
if( mod( M, 2 ) == 0 )
m = dm * ( ceil( -M/2 ) : floor( M/2 ) - 1 )';
else
m = dm * ( ceil( -M/2 ) : floor( M/2 ) )';
end
if( mod( N, 2 ) == 0 )
n = dn * ( ceil( -N/2 ) : floor( N/2 ) - 1 );
else
n = dn * ( ceil( -N/2 ) : floor( N/2 ) );
end
image = phantom();
projection = radon(image);
R = linsolve(reshape(image,1,[]), reshape(projection,1,[]));

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!