Matlab Co-occurrence Matrix - matlab

I'm sure this is a very simple mistake by me somewhere! But when I use Matlab's graycomatrix function, I don't get the expected result. Instead of a matrix output I expect, I always get an 8 x 8 (nearly) zero matrix with one entry in the bottom right - usually equal to 16. I haven't changed the default settings or used 'offset', so I'm not too sure what the problem is.

That's because your image is not normalized!
Your image should be range 0-1, so:
I = [1 1 2; 2 2 3; 1 2 5]; %or any other I
glcm = graycomatrix(I/max(I(:))); % or I/255 , but it would not work for this example
should do the job.
In your case, Matlab interprets that everything avobe 1 is 1, therefore the co-occurrence matrix gives you a unique value in the max position.

Related

Matlab Dimensions Swapped in Meshgrid

In something which made me spent several hours, I have found an inconsistency in how Matlab deals with dimensions. I somebody can explain to me OR indicate me how to report this to Matlab, please enlight me.
For size, ones,zeros,mean, std, and most every other old and common commands existing inside Matlab, the dimension arrangement is like the classical one and like the intended standard (as per the size of every dimension), the first dimension is along the column vector, the second dimension is along the row vector, and the following are the non graphical following indexes.
>x(:,:,1)=[1 2 3 4;5 6 7 8];
>x(:,:,2)=[9 10 11 12;13 14 15 16];
>m=mean(x,1)
m(:,:,1) = 3 4 5 6
m(:,:,2) = 11 12 13 14
m=mean(x,2)
m(:,:,1) =
2.5000
6.5000
m(:,:,2) =
10.5000
14.5000
m=mean(x,3)
m = 5 6 7 8
9 10 11 12
d=size(m)
d = 2 4 2
However, for graphical commands like stream3,streamline and others relying on the meshgrid output format, the dimensions 1 and 2 are swapped!: the first dimension is the row vector and the second dimension is the column vector, and the following (third) is the non graphical index.
> [x,y]=meshgrid(1:2,1:3)
x = 1 2
1 2
1 2
y = 1 1
2 2
3 3
Then, for stream3 to operate with classically arranged matrices, we should use permute(XXX,[2 1 3]) at every 3D argument:
xyz=stream3(permute(x,[2 1 3]),permute(y,[2 1 3]),permute(z,[2 1 3])...
,permute(u,[2 1 3]),permute(v,[2 1 3]),permute(w,[2 1 3])...
,xs,ys,zs);
If anybody can explain why this happens, and can indicate to me why this is not a bug, welcome.
This behavior is not a bug because it is clearly documented as the intended behavior: https://www.mathworks.com/help/matlab/ref/meshgrid.html. Specifically:
[X,Y,Z]= meshgrid(x,y,z) returns 3-D grid coordinates defined by the vectors x, y, and z. The grid represented by X, Y, and Z has size length(y)-by-length(x)-by-length(z).
Without speaking to the original authors, the exact motivation may be a bit obscure, but I suspect it has to do with the fact that the y-axis is generally associated with the rows of an image, while x is the columns.
Columns are either "j" or "x" in the documentation, rows are either "i" or "y".
Some functions deal with spatial coordinates. The documentation will refer to "x, y, z". These functions will thus take column values before row values as input arguments.
Some functions deal with array indices. The documentation will refer to "i, j" (or sometimes "i1, i2, i3, ..., in", or using specific names instead of "i" before the dimension number). These functions will thus take row values before column values as input arguments.
Yes, this can be confusing. But if you pay attention to the names of the variables in the documentation, you will quickly figure out the right order.
With meshgrid in particular, if the "x, y, ..." order of arguments is confusing, use ndgrid instead, which takes arguments in array indexing order.

Understanding Matlab multidimentionnal array

I would like to have a better comprehension of Matlab mutidimensionnal arrays and the : operator with a quick question
So I ran this example
A = zeros(2,3,4,5);
size(A)
% ans = 2 3 4 5
%% 1.
size(A(:,:,1,1))
% ans = 2 3
%% 2.
size(A(1,1,:,:))
% ans = 1 1 4 5
%% 3.
size(reshape(A(1,1,:,:), 4, 5))
% ans = 4 5
1. is the behavior I actually expected for all operations.
I don't understand why do I kept unwanted dimension in 2.
Do I need to reshape like in 3. everytime I need a subarray ?
Matlab removes singleton trailing dimensions only, so what you see is normal.
In 1, you removed a 2D subset from a 4D array, but the first two dimensions were "row" and "column".
In 2, the "row" and "column" are both singleton, and the rest of the array is in the third and fourth dimensions, so Matlab keeps it that way.
Instead of reshapeing, you can squeeze(A(1,1,:,:)) to remove dimensions that have length one (except for dimensions 1 and 2, which are sort of hard-coded into Matlab).
You can use reshape or simply squeeze in this case.
MATLAB always removes trailing singleton dimensions (past the first two):
>> size(zeros(4,4,4,1,1))
ans =
4 4 4
But it also adds them when needed (or as Ander points out in the comment, they are always implicitly there):
>> a = zeros(4,4);
>> a(2,2,1,1); % is OK
>> size(a,100)
ans =
1
On the other hand, other singleton dimensions are kept. squeeze removes them.
For your particular application it makes sense to remove singleton dimensions, but other applications would have problems if this were the default behavior. Imagine code that extracts a certain sub-volume, and changing the direction of the data depending on how many rows or columns are selected. For example:
>> a(1:x,1:y,1:z)
would return an array of size (x,y,z) as long as x and y are larger than one. Make x=1, and now it's an array of size (y,z)? Bad idea!

Average on contiguos segments of a vector

I'm sure this is a trivial question for a signals person. I need to find the function in Matlab that outputs averaging of contiguous segments of windowsize= l of a vector, e.g.
origSignal: [1 2 3 4 5 6 7 8 9];
windowSize = 3;
output = [2 5 8]; % i.e. [(1+2+3)/3 (4+5+6)/3 (7+8+9)/3]
EDIT: Neither one of the options presented in How can I (efficiently) compute a moving average of a vector? seems to work because I need that the window of size 3 slides, and doesnt include any of the previous elements... Maybe I'm missing it. Take a look at my example...
Thanks!
If the size of the original data is always a multiple of widowsize:
mean(reshape(origSignal,windowSize,[]));
Else, in one line:
mean(reshape(origSignal(1:end-mod(length(origSignal),windowSize)),windowSize,[]))
This is the same as before, but the signal is only taken to the end minus the extra values less than windowsize.

Graphing different sets of data on same graph within a ‘for’ loop MATLAB

I just have a problem with graphing different plots on the same graph within a ‘for’ loop. I hope someone can be point me in the right direction.
I have a 2-D array, with discrete chunks of data in and amongst zeros. My data is the following:
A=
0 0
0 0
0 0
3 9
4 10
5 11
6 12
0 0
0 0
0 0
0 0
7 9.7
8 9.8
9 9.9
0 0
0 0
A chunk of data is defined as contiguous set of data, without interruptions of a [0 0] row. So in this example, the 1st chunk of data would be
3 9
4 10
5 11
6 12
And 2nd chunk is
7 9.7
8 9.8
9 9.9
The first column is x and second column is y. I would like to plot y as a function of x (x is horizontal axis, y is vertical axis) I want to plot these data sets on the same graph as a scatter graph, and put a line of best fit through the points, whenever I come across a chunk of data. In this case, I will have 2 sets of points and 2 lines of best fit (because I have 2 chunks of data). I would also like to calculate the R-squared value
The code that I have so far is shown below:
fh1 = figure;
hold all;
ah1 = gca;
% plot graphs:
for d = 1:max_number_zeros+num_rows
if sequence_holder(d,1)==0
continue;
end
c = d;
while sequence_holder(c,1)~=0
plot(ah1,sequence_holder(c,1),sequence_holder(c,num_cols),'*');
%lsline;
c =c+1;
continue;
end
end
Sequence holder is the array with the data in it. I can only plot the first set of data, with no line of best fit. I tried lsline, but that didn't work.
Can anyone tell me how to
-plot both sets of graphs
-how to draw a line of best fit a get the regression coefficient?
The first part could be done in a number of ways. I would test the second column for zeroness
zerodata = A(:,2) == 0;
which will give you a logical array of ones and zeros like [1 1 1 0 1 0 0 ...]. Then you can use this to split up your input. You could look at the diff of that array and test it for positive or negative sign. Your data starts on 0 so you won't get a transition for that one, so you'd need to think of some way to deal with that or the opposite case, unless you know for certain that it will always be one way or the other. You could just test the first element, or you could insert a known value at the start of your input array.
You will then have to store your chunks. As they may be of variable length and variable number you wouldn't put them into a big matrix, but you still want to be able to use a loop. I would use either a cell array, where each cell in a row contains the x or y data for a chunk, or a struct array where say structarray(1).x and structarray)1).y hold your data values.
Then you can iterate through your struct array and call plot on each chunk separately.
As for fitting you can use the fit command. It's complex and has lots of options so you should check out the help first (type doc fit inside the console to get the inline help, which is the same as the website help in content). The short version is that you can do a simple linear fit like this
[fitobject, gof] = fit(x, y, 'poly1');
where 'poly1' specifies you want a first order polynomial (i.e. straight line) and the output arguments give you a fit object, which you can do various things with like plot or interpolate, and the second gives you a struct containing among other things the r^2 and adjusted r^2. The fitobject also contains your fit coefficients.

Questions about matlab median filter commands

This is a question about Matlab/Octave.
I am seeing some results of the medfilt1(1D Median filter command in matlab) computation by which I am confused.
EDIT:Sorry forgot to mention:I am using Octave for Windows 3.2.4. This is where i see this behavior.
Please see the questions below, and point if I am missing something.
1] I have a 1D data array b=[ 3 5 -8 6 0];
out=medfilt1(b,3);
I expected the output to be [3 3 5 0 0] but it is showing the output as [4 3 5 0 3]
How come? What is wrong here?
FYI-Help says it pads the data at boundaries by 0(zero).
2] How does medfilt2(2D median filter command in matlab) work.
Help says "Each output pixel contains the median value in the m-by-n neighborhood around the corresponding pixel in the input image".
For m=3,n=3, So does it calculate a 3x3 matrix MAT for each of input pixels placed at its center and do median(median(MAT)) to compute its median value in the m-by-n neighbourhood?
Any pointers will help.
thank you. -AD
I was not able to replicate your error with Matlab 7.11.0, but from the information in your question it seems like your version of medfilt1 does not differentiate between an odd or even n.
When finding the median in a vector of even length, one usually take the mean of the two median values,
median([1 3 4 5]) = (3+4)/2 = 3.5
This seems to be what happens in your case. Instead of treating n as odd, and setting the value to be 3, n is treated as even and your first out value is calculated to be
median([0 3 5]) = (3+5)/2 = 4
and so on.. EDIT: This only seems to happen in the endpoints, which suggest that the padding with zeros is not properly working in your Octave code.
For your second question, you are almost right, it calculates a 3x3 matrix in each center, but it does not do median(median(MAT)), but median(MAT(:)). There is a difference!
A = [1 2 3
14 5 33
11 7 13];
median(median(A)) = 11
median(A(:)) = 7