Laplacian Filter Formula - matlab

I tried Laplacian filter method but i think I did somethings wrong with its formula.
My original matrix (f)
a b
a 1 2
b 3 4
New matrix (g) by padding old matrix and replicating the origial one for using 3x3 filter mask
a b c d e f
a 1 2 1 2 1 2
b 3 4 3 4 3 4
c 1 2 1 2 1 2
d 3 4 3 4 3 4
e 1 2 1 2 1 2
f 3 4 3 4 3 4
The filter (m)
a b c
a 0 1 0
b 1 -4 1
c 0 1 0
Then I start at [c,c] in the new matrix. What I did in the calculation was
g(c,c) = g (c,c) + -1* (m(a,a)*g(b,b) + m(a,b)*g(b,c) + m(a,c)*g(b,d) + m(b,a)*g(c,b) + m(b,b)*g(c,c) + m(b,c)*g(c,d) + m(c,a)*g(d,b) + m(c,b)*g(d,c) + m(c,c)*g(d,d));
After performing the filter on g(c,c) , g(c,d) , g(d,c) , g (d,d), I crop the matrix as filtered these filter point to the new matrix, but the result look really weird. (not like in the book). I tried doing it in matlab by myself.
Can someday help me with this? Thank you very much

To get the same results as Nasser's method using conv2 and filter2 (which are only the same because your filter has symmetric rows), first you can't do it in-place. Previously filtered entries will mess up the subsequent calculations. Second, I'm not sure where that g(c,c) + -1* comes in. A normal filter calculation for g(c,c) would be:
r(c,c) = m(a,a)*g(b,b) + m(a,b)*g(b,c) + m(a,c)*g(b,d) +...
m(b,a)*g(c,b) + m(b,b)*g(c,c) + m(b,c)*g(c,d) +...
m(c,a)*g(d,b) + m(c,b)*g(d,c) + m(c,c)*g(d,d);
where r is the result matrix. This method (repeated for the other 3 values in the original matrix) gives:
r =
c d
c 6 2
d -2 -6
UPDATE
using:
A =
1 2 1 2 1 2
3 4 3 4 3 4
1 2 1 2 1 2
3 4 3 4 3 4
1 2 1 2 1 2
3 4 3 4 3 4
mask =
0 1 0
1 -4 1
0 1 0
imfilter gives:
imfilter(A,mask)
ans =
1 -2 3 -2 3 -3
-6 -6 -2 -6 -2 -9
4 2 6 2 6 1
-6 -6 -2 -6 -2 -9
4 2 6 2 6 1
-7 -8 -3 -8 -3 -11
The function suggested above,
for i=1:2
for j=1:2
r(i,j) = m(1,1)*g(i+1,j+1) + m(1,2)*g(i+1,j+2) + m(1,3)*g(i+1,j+3) +...
m(2,1)*g(i+2,j+1) + m(2,2)*g(i+2,j+2) + m(2,3)*g(i+2,j+3) +...
m(3,1)*g(i+3,j+1) + m(3,2)*g(i+3,j+2) + m(3,3)*g(i+3,j+3);
end
end
gives:
ans =
6 2
-2 -6
Does this match what you expect to see?
Note: The function above is not how I would implement it, but it follows the example that you gave for clarity.

Related

How to generate all possible combinations for the column vectors of a matrix, in MATLAB?

If B=[1; 2] and A=[B B B...(n times B)], how to obtain the matrix C corresponding to all the possible combinations between the column vectors of A .i.e. I want to get the combinations between n copies of the same vector.
For example, for n=3:
A =
1 1 1
2 2 2
So, C can be obtained using the function from File Exchange 'allcomb(varargin)':
C=allcomb(A(:,1),A(:,2),A(:,3))
C =
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2
In my case n is variable. How to obtain C for any value of n?
You can put the repetitions in a cell, and use the {:} syntax to put all cell elements as inputs to allcomb
n = 3;
B = [1,2];
A = repmat( {B}, n, 1 );
C = allcomb( A{:} ); % allcomb is FileExchange.
% combvec is a documented alternative.
Output:
C =
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2
Since the alphabets for each of the places is the same, this is really a base conversion. MATLAB only accepts integer bases, but we can use that integer as an index into the alphabet B:
B=[1; 2];
n = 3;
b = numel(B);
for k = 0:(b^n-1) % loop over all possible combinations
C(k+1,:) = dec2base(k, b, n);
end
C = C - '0' + 1; % convert 0..b-1 (in chars) into 1..b (in ints) for indexing
C = B(C); % index into alphabet B
Results:
>> C
C =
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2
The last line of the script doesn't appear to do much in this case because the alphabet happens to be the same range as our indices, but changing the alphabet to B = [7; 14] will correctly result in:
C =
7 7 7
7 7 14
7 14 7
7 14 14
14 7 7
14 7 14
14 14 7
14 14 14
Funnily enough, allcomb from MATLAB File Exchange seems to be what you want.
allcomb([1; 2],[1; 2], [1; 2])
ans =
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2
To do it for any n, simply construct the matrix with:
>> n = 3;
>> repmat(B, 1, n)
ans =
1 1 1
2 2 2

How to know the if some combination repeats using matlab

Please allow me to post this admin:
ok so this is my problem, i want to generate all combination of a, and b, for example 1 and 2, having a combinations of (1,2), (2,1),(-1,2), and (2,-1), so 4 combination, but i want only one combination as representative of all 4 combination to be display in output for example only (1,2). so this is my draft code:
fprintf(' a b z \n _ _ _ \n');
for a= -1:3
for b=-1:3
z=a^2 + b^2
end
end
ctr=1;
i(:,3) %the position of z in array
for x =1:length(z) %the length of z array
if z = i(1,1)
ctr = ctr +1;
else
fprintf(' %d %d %d\n',a,b,z);
end
end
so this the output i want:
a b z no. of repetitions
1 1 2 4
1 0 1 4
1 2 5 4
1 3 10 4
0 2 4 2
0 3 9 2
2 2 8 1
2 3 13 2
3 3 18 1
0 0 0 1
no. of repetition means how many possible combination of a and b can generate
in=-1:3
%calculate z
[a,b]=meshgrid(in);
z=a.^2+b.^2;
%sort absolute values ascending, which allows to use unique
ac=sort(abs([a(:) b(:)]),2);
%use unique to identify duplicates
[f,g,h]=unique(ac,'rows');
%count
cnt=histc(h,1:max(h));
disp([a(g),b(g),z(g),cnt])
The output is:
0 0 0 1
1 0 1 4
2 0 4 2
3 0 9 2
1 1 2 4
2 1 5 4
3 1 10 4
2 2 8 1
3 2 13 2
3 3 18 1

Plot a matrix, values as colors

I have random matrix with arbitrary dimensions and I want to assign a color for each value (randomly or not) and plot the matrix with numbers like,
So far I've done this,
m = 12;
n = 8;
A = randi(5,[m n]);
Arot = flipud(A);
pcolor(Arot);figure(gcf);
for i = 1 : n -1
for j = 1 : m -1
text(i + .5 , j + .5 ,num2str(Arot(j,i)),'FontSize',18);
end
end
which gives me this,
for
A =
4 4 4 1 2 1 4 2
5 2 2 3 2 1 1 2
1 2 1 4 1 2 5 5
1 3 5 3 1 4 1 3
3 4 4 4 3 3 3 4
2 5 2 2 1 1 2 4
1 3 1 3 5 5 2 4
5 1 2 4 1 4 1 2
2 4 5 5 1 3 5 2
4 2 2 3 4 3 3 4
3 5 3 2 4 3 3 1
1 4 5 3 2 4 3 5
but as you can see I've lost first row and last column of A.
Actually the problem starts bu using pcolor, which gives an (m-1)x(n-1) plot for mxn input.
Any suggestions?
Thanks,
Using imagesc instead of pcolor solves the problem. It also brings some other benefits:
Avoids the need for flipud;
The coordinates of the text objects become integer values;
Axes are automatically set to "matrix" mode, with the origin in the upper right corner.
Code:
m = 8;
n = 6;
A = randi(5,[m n]);
imagesc(A);
for ii = 1:n
for jj = 1:m
text(ii, jj, num2str(A(jj,ii)), 'FontSize', 18);
end
end
For
A =
4 5 4 2 4 4
5 4 3 4 4 2
5 4 1 1 1 3
4 3 5 2 5 4
1 2 2 2 5 3
1 5 2 5 1 3
4 3 1 3 3 1
3 1 2 4 2 3
this produces
I just padded the matrix prior to pcolor and I think it's the effect you wanted. The reason it works comes from the help doc for pcolor, which states that
In the default shading mode, 'faceted', each cell has a constant color
and the last row and column of C are not used.
m = 12;
n = 8;
A = randi(5,[m n]);
Arot = flipud(A);
Arot = [ Arot; Arot(end,:) ];
Arot = [ Arot, Arot(:,end) ];
pcolor(Arot);figure(gcf);
for i = 1 : n
for j = 1 : m
text(i + .5 , j + .5 ,num2str(Arot(j,i)),'FontSize',18);
end
end

How to subtract every nth column in Matlab

If I have an arbitrary n*m matrix called data and I would like to take differences of the matrix using gradually bigger steps.
The first case would have a first column equal to data(:,2)-data(:,1), the next column would be data(:,3)-data(:,2) and so on. This can be done with the following function.
data = diff(data,1,2)
Similarly I would also like to take differences based of every second column, so that the first entry would be data(:,3)-data(:,1) and the next data(:,5)-data(:,3) and so on.
This can't be done with diff, but is there any other function or method that can do it without resorting to looping?
I need to do the same thing for every n value up to 50.
Use column indexing to select the "right" columns and then use your favourite diff -
A = randi(9,4,9) %// Input array
stepsize = 2; %// Edit this for a different stepsize
out = diff(A(:,1:stepsize:end),1,2)
Output -
A =
8 9 9 8 3 2 6 8 7
2 5 5 7 5 3 9 6 3
2 7 7 2 4 1 2 4 1
6 2 1 5 4 9 9 3 7
out =
1 -6 3 1
3 0 4 -6
5 -3 -2 -1
-5 3 5 -2
I just wrote a simple wrapper function for the purpose.
function [ out ] = diffhigh( matrix, offset )
matrix_1 = matrix(:,(offset+1):size(matrix,1));
matrix_2 = matrix(:, 1:(size(matrix,1)-offset));
out = matrix_1 - matrix_2;
end
>> a
a =
3 5 1 2 4
1 2 3 4 5
1 4 5 3 2
1 2 4 3 5
2 1 5 3 4
>> diffhigh(a, 2)
ans =
-2 -3 3
2 2 2
4 -1 -3
3 1 1
3 2 -1
>> diffhigh(a, 3)
ans =
-1 -1
3 3
2 -2
2 3
1 3

MATLAB Plot: modifying point position on y plane

I have this line of code in MATLAB, which sets these vectors:
x = [2 12 3 8 1 9 2; -3 -2 -1 0 1 2 3]
x =
2 12 3 8 1 9 2
-3 -2 -1 0 1 2 3
Considering the first row as points in y-plane and second row as x-axis in MATLAB plot
Now what line of code in MATLAB will take the maximum number in the first row and set at the middle(0) point in x-axis which will make it look like this
x =
9 2 2 12 3 8 1
-3 -2 -1 0 1 2 3
Please any idea is appreciated, I don't know how best to ask this question, I'm actually trying to edit a plot in MATLAB.
Code:
x = [2 12 3 8 1 9 2; -3 -2 -1 0 1 2 3];
[~,idx] = max(x(1,:));
x(1,:) = circshift(x(1,:),[0 (length(x)+1)/2-idx]);
Output:
x =
9 2 2 12 3 8 1
-3 -2 -1 0 1 2 3