Need help for Diploma thesis: calculating preferred direction of gradient vector - fortran90

i am currently writing my Diploma thesis in Fortran 90. At a certain stage of my code, i simply want to calculate an Integer (should give a direction in a cartesian grid of mesh cells as a result).
There are no error messages, but the result is wrong. What can it be? The value i am looking for is that of the variable idirhf (see below). it should always be either 1, 2, or 3. Depending on the calculated preferred direction. However, it is often idirhf = 0 or maybe even idirhf = 1195 or whatever...the values fcdx, fcdy and fcdz are Real values. they represant the components of a gradient.
All variables are declared in a previous step which is not shown.
Can anybody help? i have already spent hours on that little issue now...
Here is a part of the code:
distz = ( dr ( k ) + dr ( k - 1 ) + dr ( k + 1) ) / 2.
fcdx = ( fv ( i + 1, j, k ) - fv ( i - 1, j ,k ) ) &
& / ( 2. * dz )
fcdy = ( fv ( i, j + 1, k ) - fv ( i, j - 1, k ) ) &
& / ( 2. * dp )
fcdz = ( fv ( i, j, k + 1 ) - fv ( i, j ,k - 1 ) ) &
& / ( distz )
gradf ( 1 ) = ABS ( fcdx )
gradf ( 2 ) = ABS ( fcdy )
gradf ( 3 ) = ABS ( fcdz )
!
! Prüfung in welche der 3 Kooridnatenrichtung x,y,z
! die HF gebildet werden soll:
!
IF ( gradf(1) > gradf(2) ) THEN
IF ( gradf(1) > gradf(3) ) THEN
idirhf = x
x = 1
ider1 = y
ider2 = z
nsten1 = 5
nsten2 = 5
END IF
END IF
!
IF ( gradf(2) > gradf(1) ) THEN
IF ( gradf(2) > gradf(3) ) THEN
idirhf = y
y = 2
ider1 = x
ider2 = z
nsten1 = 4
nsten2 = 5
END IF
END IF
!
IF ( gradf(3) > gradf(1) ) THEN
IF ( gradf(3) > gradf(2) ) THEN
idirhf = z
z = 3
ider1 = x
ider2 = y
nsten1 = 4
nsten2 = 5
END IF
END IF
! WRITE(*,*)'###Nach gradf-Vergleich.idirhf = ', idirhf

Your post doesn't show us the values of x,y,z before they are first used to update idirhf inside your double IF statements. Should the sequence
idirhf = x
x = 1
really be
x = 1
idirhf = x
etc ?

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.

Image Transformation Without Loop

I am writing image transformation function in matlab instead of using predefined functions like 'imwarp or imtransform'. I am done with writing the code roughly but it is taking too long due to the use of loop.
Please suggest me a solution which can achieve the same result without loops
function I2 = f_transform(A, I1)
%A is an affine transformation matrix
%I1 is original image to be transformed
s=size(A);
if(s(1)~=3 || s(2)~=3)
disp("Invalid Transforming Matrix");
I2=0;
return;
end
if(det(A)==0)
disp("The given Transforming Matrix is Singular");
I2=0;
return;
end
[r, c]=size(I1);
extremeValues = [1 1 r r ; 1 c 1 c; 1 1 1 1];
newExtremeValues = A * extremeValues;
minRow = floor( min( newExtremeValues(1,:) ) );
maxRow = ceil( max( newExtremeValues(1,:) ) );
minCol = floor( min( newExtremeValues(2,:) ) );
maxCol = ceil( max( newExtremeValues(2,:) ) );
I2 = zeros(maxRow - minRow + 1, maxCol - minCol + 1);
for i = minRow:maxRow
for j=minCol:maxCol
b = A \ [i j 1]';
p = b(1) / b(3);
q = b(2) / b(3);
if(p >= 1 && p <= r && q >= 1 && q <= c)
I2(i - minRow + 1, j - minCol + 1) = I1(round(p),round(q));
end
end
end
I2 = uint8(I2);
return;
end

about Clamped cubic spline code in Matlab

I did the program, but for some reason it marks a mistake (c = tridiagonal ( hi(1:n-1), dd, hi(1:n-1), ri ); ) and I don't know why, I'm sure it's correct so please somebody help.
Here is the code:
function csc = cubic_clamped ( xi, fi, fpa, fpb )n = length ( xi );
m = length ( fi );
if ( n ~= m )
disp ( 'number of ordinates and number of function values must be equal' )
return
end
for i = 1 : n-1
hi(i) = xi(i+1) - xi(i);
end
dd(1) = 2.0*hi(1); dd(n) = 2.0*hi(n-1);
ri(1) = (3.0/hi(1))*(fi(2)-fi(1)) - 3.0 * fpa;
ri(n) = 3.0 * fpb - (3.0/hi(n-1))*(fi(n)-fi(n-1));
for i = 1 : n-2
dd(i+1) = 2.0 * ( hi(i) + hi(i+1) );
ri(i+1) = (3.0/hi(i+1))*(fi(i+2)-fi(i+1))-(3.0/hi(i))*(fi(i+1)-fi(i));
end
disp ( [dd' ri'] )
c = tridiagonal ( hi(1:n-1), dd, hi(1:n-1), ri );
d = zeros ( n,1 );
b = d;
for i = 1 : n-1
d(i) = (c(i+1)-c(i))/(3.0*hi(i));
b(i) = (fi(i+1)-fi(i))/hi(i) - hi(i)*(c(i+1)+2.0*c(i))/3.0;
end
if ( nargout == 0 )
disp ( [ xi' fi' b c' d ] )
else
csc = [ xi' fi' b c' d ];
end
tridiagonal code (error is: w = a(i) - b(i)*v(i-1); )
function y = tridiagonal( a, b, c, f )
n = length(f);
v = zeros(n,1);
y = v;
w = a(1);
y(1) = f(1)/w;
for i=2:n
v(i-1) = c(i-1)/w;
w = a(i) - b(i)*v(i-1);
y(i) = ( f(i) - b(i)*y(i-1) )/w;
end
for j=n-1:-1:1
y(j) = y(j) - v(j)*y(j+1);
end

how to remove unwanted colors from a Matlab RGB image frame, without using a loop [duplicate]

This question already has answers here:
How can I convert an RGB image to grayscale but keep one color?
(3 answers)
Closed 6 years ago.
I have an RGB image frame and I want to remove all pixels that are NOT a desired color.
How can do this without a for loop?
% Desired color: R 105, G 112, B 175
% I want to zero all pixels that are not this color (plus a tad).
red_target = 105;
green_target = 112;
blue_target = 175;
tad = 4;
red_low = red_target - tad;
red_hi = red_target + tad;
green_low = green_target - tad;
green_hi = green_target + tad;
blue_low = blue_target - tad;
blue_hi = blue_target + tad;
% Filter out non-target colors:
% Pixel redness is within target; greenness is within target; and blueness within:
% Reset pixel if wrong redness OR wrong greenness OR wrong blueness:
raw_frame_size = size( raw_frame )
rows = raw_frame_size( 1 );
columns = raw_frame_size( 2 );
for row = 1:rows
for column = 1:columns
% Reset RGB pixel value if pixel is outside desired range:
pixel_redness = raw_frame(row,column,1);
pixel_greenness = raw_frame(row,column,2);
pixel_blueness = raw_frame(row,column,3);
if ( ( pixel_redness < red_low ) | ( pixel_redness > red_hi ) ...
| ( pixel_greenness < green_low ) | ( pixel_greenness > green_hi ) ...
| ( pixel_blueness < blue_low ) | ( pixel_blueness > blue_hi ) )
raw_frame( row, column, 1 ) = 0;
raw_frame( row, column, 2 ) = 0;
raw_frame( row, column, 3 ) = 0;
end
end
end
From what I can tell is your objective, this is definitely achievable without for loops using logical indexing.
% Prepare Filter Arrays.
imageSize = size ( raw_frame );
filterArray = zeros ( imageSize ( 1 ) , imageSize ( 2 ) );
% Identify filter pixels.
% This step utilizes logical indexing.
filterArray ( raw_frame(:,:,1) < red_low ) = 1;
filterArray ( raw_frame(:,:,1) > red_high ) = 1;
filterArray ( raw_frame(:,:,2) < green_low ) = 1;
filterArray ( raw_frame(:,:,2) > green_high ) = 1;
filterArray ( raw_frame(:,:,3) < blue_low ) = 1;
filterArray ( raw_frame(:,:,3) > blue_high) = 1;
% Replicate the array to 3D.
filter3d = repmat ( filterArray , [ 1 1 3 ]);
% Filter the image.
% This step also uses logical indexing.
raw_frame ( filter3d ) = 0;
Also, it is a generally bad practice to perform color filtering using an RGB image given the inability to isolate color from saturation and darkness using RGB values alone.
For instance, the RGB values [100,80,40] and [50,40,20] are the same color (hue) but different intensity (lightness or value). A better alternative may be to:
targetRgb(1,1,1) = 105;
targetRgb(1,1,2) = 112;
targetRgb(1,1,3) = 175;
targetHsv = rgb2hsv(targetRgb);
frameHsv = rgb2hsv(raw_frame);
frameSize = size(raw_frame);
hTad = 0.05;
% Values must be in the range [0,1] inclusive.
% Because "hue" is a "colorwheel", -0.3 would be the same value as 0.7.
targetHLow = ( targetHsv(1) - hTad + 1 ) - floor ( targetHsv(1) - hTad + 1);
% A value like 1.3 is the same as 0.3
targetHHigh = ( targetHsv(1) + hTad ) - floor ( targetHsv(1) + hTad );
% Create the filter.
hFilter = zeros(frameSize(1),frameSize(2));
hFilter(hFilter<targetHLow) = 1;
hFilter(hFilter>targetHHigh) = 1;
% Zero out the value channel.
frameV = framHsv(:,:,3);
frameV(hFilter) = 0;
frameHsv(:,:,3) = frameV;
% Convert the modified HSV back to RGB.
frameFiltered = hsv2rgb(frameHsv);
I think there is a much simpler, and computationally efficient implementation. The filter is a 2D logical array.
myrgb = rand(100,100,3);
imagesc(myrgb)
floatNorm = 2^8 - 1;
tad = repmat(4, [100, 100, 3]);
target = repmat([105,112,175], 100*100, 1);
target = reshape(target, [100, 100, 3]);
threshold = (target + tad)/floatNorm;
myFilt = abs(myrgb - 1/2) <= threshold;
myrgb(myFilt) = 0;
imagesc(myrgb)
Can't be done without for loop.
So here is my solution using for loops....
% blue: R 105, G 112, B 175
red_target = 105;
green_target = 112;
blue_target = 175;
tad = 20;
red_low = red_target - tad;
red_hi = red_target + tad;
green_low = green_target - tad;
green_hi = green_target + tad;
blue_low = blue_target - tad;
blue_hi = blue_target + tad;
% Filter out non-target colors:
% Pixel redness is within target; greeness is within target; and blueness within:
% Reset pixel if wrong redness OR wrong greenness OR wrong blueness:
raw_frame_size = size( raw_frame )
rows = raw_frame_size( 1 );
columns = raw_frame_size( 2 );
for row = 1:rows
for column = 1:columns
% Reset RGB pixel value if pixel is outside desired range:
pixel_redness = raw_frame(row,column,1);
pixel_greenness = raw_frame(row,column,2);
pixel_blueness = raw_frame(row,column,3);
if ( ( pixel_redness < red_low ) | ( pixel_redness > red_hi ) ...
| ( pixel_greenness < green_low ) | ( pixel_greenness > green_hi ) ...
| ( pixel_blueness < blue_low ) | ( pixel_blueness > blue_hi ) )
raw_frame( row, column, 1 ) = 0;
raw_frame( row, column, 2 ) = 0;
raw_frame( row, column, 3 ) = 0;
end
end
end

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!