Implementing IMFILTER in matlab - matlab

I am trying to filter an image with out using imfilter. I should get the same results as imfilter but I keep getting diffrent results. Can someone tell me where I went wrong?
orignal=imread('obj6__17.png');
filter=1/9*[-1 -1 -1 ; -1 17 -1 ; -1 -1 -1];
s=size(orignal);
r=zeros(s(1));
temp = zeros(3);
for i= 2: s(1)-1
for j = 2: s(2)-1
for n= 1: 3
for m= 1:3
temp(n,m)=orignal(i+2-n,j+2-m)*filter(n,m);
end
end
r(i,j)=sum(single(sum(temp)));
end
end

The size of r should be the same as the original I think. And I don't understand why you convert to single precision using single. Anyway, I think you want to do the following:
%# Let's first create a small test image from the built-in peppers image
original = im2double(imread('peppers.png'));
original = original(1:5,1:8,1);
filter = 1/9 * [-1 -1 -1 ; -1 17 -1 ; -1 -1 -1];
s = size(original);
r = zeros(s);
for i = 2:s(1)-1
for j = 2:s(2)-1
temp = original(i-1:i+1,j-1:j+1) .* filter;
r(i,j) = sum(temp(:));
end
end
The result is as follows:
r =
0 0 0 0 0 0 0 0
0 0.2336 0.2157 0.2514 0.2436 0.2257 0.2344 0
0 0.2453 0.2444 0.2671 0.2693 0.2418 0.2240 0
0 0.2741 0.2728 0.2397 0.2505 0.2375 0.2436 0
0 0 0 0 0 0 0 0
And with imfilter, it is:
r2 = imfilter(original, filter)
r2 =
0.3778 0.3325 0.3307 0.3442 0.3516 0.3312 0.3163 0.3856
0.3298 0.2336 0.2157 0.2514 0.2436 0.2257 0.2344 0.3386
0.3434 0.2453 0.2444 0.2671 0.2693 0.2418 0.2240 0.3512
0.3272 0.2741 0.2728 0.2397 0.2505 0.2375 0.2436 0.3643
0.3830 0.3181 0.3329 0.3403 0.3508 0.3272 0.3412 0.4035
As you see, the results are the same except the ones on the borders. There are a few strategies to compute the ones on the borders as mirroring the image to the out of the borders, keeping them the same, etc. Please read the documentation of imfilter and choose one strategy.
Note that I didn't flipped filter here since the filter is symmetric in both directions. And I recommend you to avoid loops! There are nested loops of depth four in your code!
Lastly, you can use 2-D convolution to do the same as imfilter:
r3 = conv2(original, filter, 'same');
r3 =
0.3778 0.3325 0.3307 0.3442 0.3516 0.3312 0.3163 0.3856
0.3298 0.2336 0.2157 0.2514 0.2436 0.2257 0.2344 0.3386
0.3434 0.2453 0.2444 0.2671 0.2693 0.2418 0.2240 0.3512
0.3272 0.2741 0.2728 0.2397 0.2505 0.2375 0.2436 0.3643
0.3830 0.3181 0.3329 0.3403 0.3508 0.3272 0.3412 0.4035

This is modifies code and gives the exact same result as imfilter....
%# Let's first create a small test image from the built-in peppers image
original = im2double(imread('peppers.png'));
original = original(1:5,1:8,1);
filter = 1/9 * [-1 -1 -1 ; -1 17 -1 ; -1 -1 -1];
s = size(original);
r = zeros(s);
original=padarray(original,[1,1]);
for i = 2:s(1)
for j = 2:s(2)
temp = original(i-1:i+1,j-1:j+1) .* filter;
r(i-1,j-1) = sum(temp(:));
end
end
This gives the result matrix which is exactly same as with the
function...

Related

Modeling LQR for 2 dimensional system does not print eigenvalues and dcgain

I am new to Matlab and LQR controller. I tried to simulate a 2-dimensional system, which was modeled using state space model, using the following code, but it does not show eigenvalues and dcgain for this system. I am not sure whether I implemented the code correctly or not. Any help would be appreciated.
mc=10;
mr=10;
ml=10;
Jc=1/(12*(mc+mr+ml));
g = 9.8;
Fe=0.1;
d=0.5;
mu=0.02;
A_lat=[0 0 1 0;0 0 0 1;0 -Fe/(mc+mr+ml) -mu/(mc+mr+ml) 0;0 0 0 0];
B_lat=[0;0;0;1/(Jc+mr*d^2+ml*d^2)];
C_lat=[1 0 0 0];
D_lat=0;
A_lon=[0 1;0 0];
B_lon=[0;1/(mc+mr+ml)];
C_lon=[1 0];
D_lon=0;
sys_lat = ss(A_lat,B_lat,C_lat,D_lat);
sys_lon=ss(A_lon,B_lon,C_lon,D_lon);
Co_lat = ctrb(sys_lat);
Co_lon = ctrb(sys_lon);
constQ=0.1;
constR=1;
Q_lat = Co_lat'*Co_lat;%constQ*eye(4);
R_lat = constR;
Q_lon = Co_lon'*Co_lon;%constQ*eye(2);
R_lon = constR;
K_lat = lqr(sys_lat,Q_lat,R_lat);
K_lon = lqr(sys_lon,Q_lon,R_lon);
sys_K_lat = ss(A_lat-B_lat*K_lat,B_lat,C_lat,D_lat);
sys_K_lon = ss(A_lon-B_lon*K_lon,B_lon,C_lon,D_lon);
sys_K=append(sys_K_lat,10,sys_K_lon);
disp("*******");
eig(A_lat-B_lat*K_lat);
eig(A_lon-B_lon*K_lon);
DCGAIN = dcgain(sys_K);
bode(sys_K);
input = #(t,x) -K_lat*x;
The semicolon will suppress output display. Just remove semicolon for the code solving eigenvalues and dcgain
disp('*******');
eig(A_lat-B_lat*K_lat)
eig(A_lon-B_lon*K_lon)
DCGAIN = dcgain(sys_K)
Output:
*******
ans =
-0.1411 + 0.1411i
-0.1411 - 0.1411i
-0.0409 + 0.0409i
-0.0409 - 0.0409i
ans =
-0.0236 + 0.0236i
-0.0236 - 0.0236i
DCGAIN =
-5.0028 0 0
0 10.0000 0
0 0 30.0000

Compute matrix with symbolic variable

I have the following MATLAB script:
var_theta = sym('theta', [1,7]);
matrix_DH = computeDH(var_theta);
T_matrix = zeros(4,4,7);
for i = 1:7
T_matrix(:,:,i) = computeT(matrix_DH(i,1), matrix_DH(i,2), matrix_DH(i,3), matrix_DH(i,4));
end
function matrixT = computeT(alpha, d, r, theta)
matrixT = zeros(4,4);
matrixT(1,:) = [cos(theta) -1*sin(theta) 0 r]; % first row
matrixT(2,:) = [sin(theta)*cos(alpha) cos(theta)*cos(alpha) -sin(alpha) -d*sin(alpha)]; % 2n row
matrixT(3,:) = [sin(theta)*sin(alpha) cos(theta)*sin(alpha) cos(alpha) d*cos(alpha)]; % 3rd row
matrixT(4,:) = [0 0 0 1]; % last row
end
function DH = computeDH(theta)
DH = zeros(7,4);
L = 0.4;
M = 0.39;
DH(1,:) = [0.5*pi 0 0 theta(1,1)];
DH(2,:) = [-0.5*pi 0 0 theta(2)];
DH(3,:) = [-0.5*pi L 0 theta(3)];
DH(4,:) = [0.5*pi 0 0 theta(4)];
DH(5,:) = [0.5*pi M 0 theta(5)];
DH(6,:) = [-0.5*pi 0 0 theta(6)];
DH(7,:) = [0 0 0 theta(7)];
end
I would like to obtain the desired array of T_matrix without evaluating the theta's. My objective is that after getting the matrices, derivate each position by each theta in order to compute the Jacobian. So at the end I would like the resulting matrices as a function of the thetas. The problem is that whenever I insert the symbolic variable into the matrix it says:
The following error occurred converting from sym to double:
Unable to convert expression into double array.
Error in computeT_robotics>computeDH (line 21)
DH(1,:) = [0.5*pi, 0, 0, theta(1)];
As Anthony stated, the matrices that my theta is included in, need to be declared as sym as well in order to be able to save symbolic results.
Final code:
var_theta = sym('theta', [1,7]);
matrix_DH = computeDH(var_theta);
T_matrix = sym('T_matrix',[4 4 7]);
for i = 1:7
T_matrix(:,:,i) = computeT(matrix_DH(i,1), matrix_DH(i,2), matrix_DH(i,3), matrix_DH(i,4));
end
function matrixT = computeT(alpha, d, r, theta)
matrixT = sym('matrixT', [4 4]);
matrixT(1,:) = [cos(theta) -1*sin(theta) 0 r]; % first row
matrixT(2,:) = [sin(theta)*cos(alpha) cos(theta)*cos(alpha) -sin(alpha) -d*sin(alpha)]; % 2n row
matrixT(3,:) = [sin(theta)*sin(alpha) cos(theta)*sin(alpha) cos(alpha) d*cos(alpha)]; % 3rd row
matrixT(4,:) = [0 0 0 1]; % last row
end
function DH = computeDH(theta)
DH = sym('DH',[7 4]);
L = 0.4;
M = 0.39;
DH(1,:) = [0.5*pi 0 0 theta(1,1)];
DH(2,:) = [-0.5*pi 0 0 theta(2)];
DH(3,:) = [-0.5*pi L 0 theta(3)];
DH(4,:) = [0.5*pi 0 0 theta(4)];
DH(5,:) = [0.5*pi M 0 theta(5)];
DH(6,:) = [-0.5*pi 0 0 theta(6)];
DH(7,:) = [0 0 0 theta(7)];
end

unexpected output from a for loop in matlab

am trying to execute the following code on matlab i've a for loop inside a function and it's supposed to store a result at every iteration ,, but when it executes it just gives me the result of the last iteration,, is there something wrong with the sequence of the code ?
the inpit data1 is a data vector of size (33167*1)
i doubt that there is sometnig wrong with the foor loop.. there is the code i wrote :
function [vectorDominant] = processData(data1 , samplingRate , startRange, endRange)
%(length(data)/1000)
data = data1;
windowSize = 10;
samplingRate = samplingRate;
frame_len = samplingRate*windowSize;
l = length(data);
num_frames = floor(l/frame_len);
t = 1;
for i = 1 : num_frames
frame = data( (i-1)*frame_len+1 : frame_len*i);
% --- haming window ------
hammingData=frame.*hamming(length(frame));
%---- remove dc offset from data ----
dataWindowed = detrend(hammingData);
% ---- apply fft ----
fourierTransform_data=fft(dataWindowed);
y = fourierTransform_data ;
%plot(abs(fourierTransform_data))
%------- find dominant-----
len = (length(frame)/2) -1;
y = y(1:len);
[v,k] = max(y);
fftLength = length(frame);
freq = (0:(samplingRate/fftLength) :(samplingRate/2));
%plot(freq,abs(y)), grid('on'), title('dominant freq')
freq = freq(find(freq>=startRange & freq<=endRange));
dominantFrequency = freq(k);
%array[(length(data)/1000)];
%var = 1;
%while var<= length(num_frames)
n = (length(data)/1000);
vectorDominant = zeros(n,1); % to preallocate it first as it changes size every iterartion
vectorDominant(i) = dominantFrequency;
%var = var+1;
%end
end
end
the argument i give it is processData(ax, 100, 0.1, 2) where ax is the
data vector and it returns the following ans =
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0.2000
the whole result must have numbers like the last one (0.2000) not zeros
Every time through the loop you recreate vectorDominant to be a vector of zeros and then set one element of it to be the newly calculated value. Presumably the first 2 of the following lines should be done once before entering the loop.
n = (length(data)/1000);
vectorDominant = zeros(n,1);
vectorDominant(i) = dominantFrequency;
Presumably n should also be num_frames not the value calculated above.

A bug in Matlab comparison?

I write my own version ismember(find_element) in Matlab to check whether a row array a in matrix b or not, by comparing a with each row in b. If each element in a 'equals' each element of a row in b(if the absolute error is less than Tol), then return logic value 1 and row number.
However, when I test my code, I find that Matlab will return t=[1 1] when compare a=1.0e-11*[0.9063 0.0838] with B=[-1 0](B is the second row of b). Actually it gives correct absolute error error=[1.0000 0.0000], and clearly error(1) is greater than Tol=1e-6. Did I find a bug in Matlab? Or is there any error in my code?
The following is my find_element code:
function [Lia,Locb] = find_element(a,b)
%decide whether a is in b or not(compare each row); if in, return row number
%INPUT:
%a: salar or row array
%b: column array or matrix
%OUTPUT:
%Lia: 1 if a is in b, 0 if not
%Locb: location of a in b, row number if b is a matrix
Tol = 1e-6; %set tolerance when compare elements
Lia = 0;%initialization
Locb = 0;
t = zeros(size(a));%compare result of each element,logical array
for i = 1:size(b,1) %loop through each row
for j = 1:size(b,2) %compare each element in each row
if abs(a(j)-b(i,j))<Tol
t(j) = 1;
end
end
if t %all 1's
Lia = 1;%find a in b
Locb = i;%return row number
%%%%%%%%%%%%%%%%%%%%%%%%
%test outputs
a
B=b(i,:)
error = abs(a-b(i,:))
t
%%%%%%%%%%%%%%%%%%%%%%%%
break
end
end
The test code is :
a = [9.06319429228031e-12 8.37879678833309e-13];
b = [0 1;-1 0;1 0;0 1];
[Lia Locb] = find_element(a,b)
the output is:
a =
1.0e-11 *
0.9063 0.0838
B =
-1 0
error =
1.0000 0.0000
t =
1 1
Lia =
1
Locb =
2
After converting # to %, I find that your code works in Matlab for the following examples. Please provide a clear reproducible answer or edit your question if your problem occurs in Octave.
>> a=1.0e-11*[0.9063 0.0838];
>> b=[-1 0];
>> [Lia, Locb] = find_element(a,b)
Lia =
0
Locb =
0
>> [Lia, Locb] = find_element([-1.000001 0],b)
a =
-1 0
B =
-1 0
error =
1e-06 0
t =
1 1
Lia =
1
Locb =
1
I find the problem in my code now: t need to be initialized before checking each row. By putting t = zeros(size(a)) inside the i loop, it works now.
...
for i = 1:size(b,1) %loop through each row
t = zeros(size(a));%compare result of each element,logical array
for j = 1:size(b,2) %compare each element in each row
....
Test and output:
>> a = [9.06319429228031e-12 8.37879678833309e-13];
>> b = [0 1;-1 0;1 0;0 1];
>> [Lia Locb] = find_element(a,b)
Lia =
0
Locb =
0

How to set up a matrix with a fixed pattern

I need to write a script to automatically setup a matrix A. The size of this matrix is linked to the value of another variable in the workspace, N. In general, A will have N + N*(N-1)/2 rows and N columns.
The first N rows and N columns are basically just a diagonal matrix, which is easy to setup using diag.
I'm having problems setting up the lower part of the matrix. Basically, it needs to have the following form:
-1 0 0 0
0 -1 0 0
0 0 -1 0
0 0 0 -1
1 -1 0 0
1 0 -1 0
1 0 0 -1
0 1 -1 0
0 1 0 -1
0 0 1 -1
I'm sure the pattern is clear.
How do I code this so that Matlab sets up this matrix for ANY value of N?
Thanks
With some algebraic manipulation:
L=(N*(N+1)/2):-1:1;
R=ceil((sqrt(8*L+1)-1)/2);
A=bsxfun(#eq, N-1:-1:0, R')-bsxfun(#eq, N:-1:1, (L-(R.*(R-1))/2).');
UPDATE
Performance version including preallocation.
N=4;
result = zeros(N*(N+1)/2,N+1);
t = N;
endpos = 0;
for t = N:-1:1
result(endpos+1:endpos+t,:) = [zeros(t, N-t) ones(t,1) -eye(t)];
endpos = endpos + t;
end
result = result(:,2:end);
Note that I have replaced the while loop as you seem to prefer a for.
I will leave the original here as well for comparison:
Here you go:
result = [];
N = 4;
t = MaxN;
while t > 0
block = [zeros(t, N-t) ones(t,1) -eye(t)];
result = [result; block];
t = t-1;
end
result = result(:,2:end);
Thank everyone! I will post my own solution here (doesn't pre-allocate though). Might adjust it to #Dennis's solution.
N = max(size(a));
P = N*(N-1)/2;
A = zeros(N+P,N);
A(1:N,1:N) = diag(-a);
B=[];
for i = N-1:-1:1
Block = [zeros(i,N-1-i) ones(i,1) -eye(i)];
B = [B; Block];
clear Block
end
A(N+1:end,:) = B;
clear N P B i