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
Related
I'm trying to write a matlab program to calculate an integral by means of trapezoidal and simpsons rule. The program for trapezoidal is as follows:
function [int, flag, stats] = trapComp(f, a, b, tol, hMin)
% Initialise variables
h = b - a;
n = 1;
int = h / 2 * (f(a) + f(b));
flag = 1;
if nargout == 3
stats = struct('totalErEst', [], 'totalNrIntervals', [], 'nodesList', []);
end
while h > hMin
h = h / 2;
n = 2 * n;
if h < eps % Check if h is not "zero"
break;
end
% Update the integral with the new nodes
intNew = int / 2;
for j = 1 : 2 : n
intNew = intNew + h * f(a + j * h);
end
% Estimate the error
errorEst = 1 / 3 * (int - intNew);
int = intNew;
if nargout == 3 % Update stats
stats.totalErEst = [stats.totalErEst; abs(errorEst)];
stats.totalNrIntervals = [stats.totalNrIntervals; n / 2];
end
if abs(errorEst) < tol
flag = 0;
break
end
end
end
Now simpsons rule I cant really quite get around. I know its very similar but I cant seem to figure it out.
This is my simpson code:
function [int, flag, stats] = simpComp(f, a, b, tol, hMin)
% Initialise variables
h = b - a;
n = 1;
int = h / 3 * (f(a) + 4 * f((a+b)/2) + f(b));
flag = 1;
if nargout == 3
stats = struct('totalErEst', [], 'totalNrIntervals', [], 'nodesList', []);
end
while h > hMin
h = h / 2;
n = 2 * n;
if h < eps % Check if h is not "zero"
break;
end
% Update the integral with the new nodes
intNew = int / 2;
for j = 1 : 2 : n
intNew = intNew + h * f(a + j * h);
end
% Estimate the error
errorEst = 1 / 3 * (int - intNew);
int = intNew;
if nargout == 3 % Update stats
stats.totalErEst = [stats.totalErEst; abs(errorEst)];
stats.totalNrIntervals = [stats.totalNrIntervals; n / 2];
end
if abs(errorEst) < tol
flag = 0;
break
end
end
end
Using this, however, gives an answer for an integral with a larger error than trapezoidal which i feel it shouldnt.
Any help would be appreciated
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
I have a vector. I want to remove outliers. I got bin and no of values in that bin. I want to remove all points based on the number of elements in each bin.
Data:
d1 =[
360.471912914169
505.084636471948
514.39429429184
505.285068055647
536.321181755858
503.025854206322
534.304229816684
393.387035881967
396.497969729985
520.592172434431
421.284713703215
420.401106087984
537.05330275495
396.715779872694
514.39429429184
404.442344469518
476.846474245118
599.020867750031
429.163139144079
514.941744277933
445.426761656729
531.013596812737
374.977332648255
364.660115724218
538.306752697753
519.042387479096
1412.54699036882
405.571202133485
516.606049132218
2289.49623498271
378.228766753667
504.730621222846
358.715764917016
462.339366699398
512.429858614816
394.778786157514
366
498.760463549388
366.552861126468
355.37022947906
358.308526273099
376.745272034036
366.934599077274
536.0901883079
483.01740134285
508.975480745389
365.629593988233
536.368800360349
557.024236456548
366.776498701866
501.007025898839
330.686029339009
508.395475983019
429.563732174866
2224.68806802212
534.655786464525
518.711297351426
534.304229816684
514.941744277933
420.32368479542
367.129404978681
525.626188464768
388.329756778952
1251.30895065927
525.626188464768
412.313764019587
513.697381733643
506.675438520558
1517.71183364959
550.276294237722
543.359917550053
500.639590923451
395.129864728041];
Histogram computation:
[nelements,centers] = hist(d1);
nelements=55 13 0 0 1 1 1 0 0 2
I want to remove all points apearing less than 5 (in nelements). It means only first 2 elements in nelements( 55, 13 ) remains.
Is there any function in matlab.
You can do it along these lines:
threshold = 5;
bin_halfwidth = (centers(2)-centers(1))/2;
keep = ~any(abs(bsxfun(#minus, d1, centers(nelements<threshold))) < bin_halfwidth , 2);
d1_keep = d1(keep);
Does this do what you want?
binwidth = centers(2)-centers(1);
centersOfRemainingBins = centers(nelements>5);
remainingvals = false(length(d1),1);
for ii = 1:length(centersOfRemainingBins )
remainingvals = remainingvals | (d1>centersOfRemainingBins (ii)-binwidth/2 & d1<centersOfRemainingBins (ii)+binwidth/2);
end
d_out = d1(remainingvals);
I don't know Matlab function for this problem, but I think, that function with follow code is what are you looking for:
sizeData = size(data);
function filter_hist = filter_hist(data, binCountRemove)
if or(max(sizeData) == 0, binCountRemove < 1)
disp('Error input!');
filter_hist = [];
return;
end
[n, c] = hist(data);
sizeN = size(n);
intervalSize = c(2) - c(1);
if sizeData(1) > sizeData(2)
temp = transpose(data);
else
temp = data;
end
for i = 1:1:max(sizeN)
if n(i) < binCountRemove
a = c(i) - intervalSize / 2;
b = c(i) + intervalSize / 2;
sizeTemp = size(temp);
removeInds = [];
k = 0;
for j = 1:1:max(sizeTemp)
if and(temp(j) > a, less_equal(temp(j), b) == 1)
k = k + 1;
removeInds(k) = j;
end
end
temp(removeInds) = [];
end
end
filter_hist = transpose(temp);
%Determines when 'a' less or equal to 'b' by accuracy
function less_equal = less_equal(a, b)
delta = 10^-6; %Accuracy
if a < b
less_equal = 1;
return;
end
if abs(b - a) < delta
less_equal = 1;
return;
end
less_equal = 0;
You can do something like this
nelements=nelements((nelements >5))
I'm trying to make a B-Spline Function
first i set the variables and made the Knot vector
# cmpp.m
% Set variables
k = 3; % (8 mod 2 + 2 + 1)
p = k - 1; % Order = 2
n = 2*k - 1; % Control points = 5
l = n + p + 1; % Vector size n + p + 1 = 8
% Create the Knot vector
% Kv = [0 0 0 1 2 3 3 3] size = 8
knoten = 0; % set all knots to 0
Kv = [];
for j=1:1:l
Kv = [ Kv 0 ];
end
for i=1:1:l
if (i > n)
if (i <= n)
Kv(i) = knoten + 1;
knoten = knoten + 1;
else
Kv(i) = knoten;
end
else
Kv(i) = knoten;
end
end
then i worte a function to create the basic function
# f.m
function N = f(N,t,i,k,u,x,s)
if (u < x)
N(i,k) = ((((u-t(i)).*f(t,i,k-1,u+s,x,s)) / (t(i+k-1) - t(i))) + (((t(i+k)-u).*f(t,i+1,k-1,u+s,x,s)) / (t(i+k) - t(i+1))));
if ((u >= t(i)) && (u < t(i+1)))
N(i,1) = 1;
else
N(i,1) = 0;
end
end
end
and called it in cmpp.m
# cmpp.m
...
...
...
N = zeros(l,k);
x = (n+1) - (k-1);
s = 1;
N = [N f(N,Kv,1,k,0,x,s)];
but i get always this error in Matlab
>> cmpp
Subscripted assignment dimension mismatch.
Error in f (line 3)
N(i,k) = ((((u-t(i)).*f(t,i,k-1,u+s,x,s)) / (t(i+k-1) - t(i))) +
(((t(i+k)-u).*f(t,i+1,k-1,u+s,x,s)) / (t(i+k) - t(i+1))));
Error in cmpp (line 32)
N = [N f(N,Kv,1,k,0,x,s)]
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!