How to do data dimensionailty reduction? - matlab

I have a set of 25 images of label 'Infected' and 25 images of label 'Normal'.
I am trying to extract the dual-tree complex wavelet transform based coefficients as features for each of the images.
My code to obtain coefficients using DT-CWT ia as follows:
I = imread('infected_img1.jpg'); %read image
I = rgb2gray(I); %rgb ro gray-scale
L = 6; %no. of levels for wavelet decomposition
I = reshape(I',1,size(I,1)*size(I,2)); %change into a vector
I = [I,zeros(1,2^L - rem(length(I),2^L))]; %pad zeros to make dim(I) a multiple of 2^L
I = double(I);
dt = dddtree('cplxdt',I,L,'dtf3'); %perform DT-CWT
dt_Coeffs = (dt.cfs{L}(:,:,1) + 1i*dt.cfs{L}(:,:,2)); %extract coefficents at Level 6
Now, since I have 24 more images to extract coefficients from, I do this block for each of the images. My ultimate aim is to append all coefficient vectors generated in each iteration to form a matrix. But each image tends to give a different sized coefficient vector.
I want to know about some dimension reduction method that can reduce each vector to a uniform size and at the same time preserve its information.
Can anyone suggest methods with a good amount of clarity?

As I mentioned in my comment,
You can't shrink something (i.e. remove information) and still preserve all of the information.
Instead you can pad all of the vectors to the length of the largest vector and then concatenate them to create a matrix. You could program your own method but in the spirit of not reinventing the wheel I've previously used padcat(). It is very easy to use and pads with NaN but you can easily change this to 0.
Here's an example usage which also contains a handy conversion from NaN to 0.
>> a = [1 2 3 4];
>> b = [1 2 3];
>> c = padcat(a, b);
c =
1 2 3 4
1 2 3 NaN
>> c(isnan(c)) = 0
c =
1 2 3 4
1 2 3 0

Related

Angles between n vectors - Matlab

Consider a set of points (just an example)
x = [0 1 2 5 4 8 5 6];
y = [5 8 4 2 5 6 4 5];
and another reference point:
xc=1;
yc=1;
In which I use to represent these points as vectors:
vec=[x-xc y-yc];
I wish to obtain a matrix with all the angles between all vectors which is obtained by the calculation (for single vectors)
angle = acosd(dot(v,u)/norm(u)*norm(v));
How can I obtain this calculation in a few lines without going vector by vector in a loop? In my calculation the number of points is very very large.
I think you mean vec = [x-xc; y-yc];. To calucate the dotproduct between all rows, you can use
vec.'*vec
The norm (Euclidean) of each vector can be determined as
no = sqrt(sum(vec.*vec,1))
The product of the different norms can be calculated the same as for vec:
no.'*no
The angles can thus be found as
no = sqrt(sum(vec.*vec,1));
angles = acosd(vec.'*vec./(no.'*no));

Variance of elements in matrices (element-by-element) in MATLAB

I am trying to compute the variance of elements which are organised in matrices (in MATLAB). As an example, let's be A and B two matrices 2x2.
My goal is to find the matrix V (2x2 as well), being the variance of each element of A and each element of B, that is:
Can somebody help me on this?
This is a very simple use case of the var function:
A = [1 2;
3 4];
B = [5 6;
7 8];
V0 = var(cat(3,A,B),0,3);
V1 = var(cat(3,A,B),1,3);
This results in:
V0 =
8 8
8 8
V1 =
4 4
4 4
What happens is that you concatenate your matrices along some unused dimension and then compute the variance along that dimensions.
NOTE: The example of 2 matrices is not very meaningful, but I'm assuming your actual dataset is larger, in which case you could use this method.

Check element wise equality of a 3D matrix Matlab

I have a 3D matrix say for eg. A(10x5x8). I need to get a 2D matrix (Boolean) out of it of size 10x5.
True if its elemental 3 Dimensional values are all same. i.e. Result(1,1) = 1 if A(1,1,1) == A(1,1,2) == A(1,1,3) etc..
False if at least one is different.
I expect a vectored approach which is fast and efficient.
Sample input:
A(:,:,1) = 1 2
2 2
A(:,:,2) = 1 1
2 3
Expected Output:
Result = 1 0
1 0
Use bsxfun with the eq function and use the first slice as the first input and compare with the other slices for the second input. Allow the first input to broadcast itself over the multiple slices.
Once you do that, use all and check the third dimension:
ind1 = bsxfun(#eq, A(:,:,1), A(:,:,2:end);
ind2 = all(ind1, 3);
The logic behind the above is very simple. How the first line of code works is that you would create a temporary matrix that would take the first slice of A and let it duplicate itself for as many slices as you have in A, without the first slice. Once you do this, you would do an element-by-element equality with this temporary matrix and the other slices. If you had a 3D column that was all equal, the one element from the first slice would be compared with every single value that corresponds to the same 3D column. Should they all equal to each other, then you would get a 3D column of all logical 1s. Therefore, to have a 3D column that is all equal to each other, all of the values should be 1, which is why all is used - to check if all values in a 3D column are equal to 1. Should all of the 3D column be a logical 1, we have matched your criteria.
Example run
>> A1 = [1 2; 2 2];
>> A2 = [1 1; 2 3];
>> A3 = [1 3; 2 4];
>> A4 = [1 5; 2 6];
>> A = cat(3, A1, A2, A3, A4);
>> ind1 = bsxfun(#eq, A(:,:,1), A(:,:,2:end);
>> ind2 = all(ind1, 3)
ind2 =
1 0
1 0
I made a matrix of 4 slices where the 3D column at the top left corner and the bottom left corner have all of the same values. Once you run through the code at the beginning of the post, we get what you expect.
Here's with short and sweet diff and must be quite memory efficient -
out = ~any(diff(A,[],3),3)
So, basically with diff along the third dimension diff(..[],3), you would calculate differences between the same (i,j) but on different 3D slices. Thus, if all such diff outputs are zeros, that would indicate that all dim3 elements for the same (i,j) are the same. This all zeros information is then picked up by ~any() also along dim3 with ~any(.,3) for the desired 2D array output.

Sliding window for matlab

The intention is to estimate in a [3 3] sliding window. 0.5*[(A(i)-A(5))^2] is computed where a(i) is the pixels around center pixel a(5).
The mean of each of these 8 half square differences is stored in the center pixel's location.
To tackle this conv2 and nlfilter were used on a training example matrix as follows.
clc;
close all;
clear all;
A = [1 2 3 4 5 6;5 4 6 3 2 1;2 3 2 1 4 5];
kernel = [-1 -1 -1; -1 8 -1; -1 -1 -1];
outputImage = conv2(A, kernel);
fun = #(x) mean(x(:));
B= nlfilter (outputImage,[3 3],fun);
The initial idea was to calculate the difference and store it in the location of the pixels instead of the center pixel. Then use a sliding window to take mean of those differences and replace the center pixel.
It was apparent that my logic was flawed.
Though i was able to calculate the difference(i first tried to see simple difference was possible for me) i had to deal with data being overwritten. moreover this method will create a matrix larger than the original which is also wrong.
the function mean and the kernel you are using are both linear and do not represent the non-linear operation you are trying to achieve.
One way of using conv and mean is by computing the 8 differences as different output channels
ker = cell(1,8);
for ii=1:8
ker{ii} = zeros(3);
ker{ii}(2,2) = 1; %// for a(5)
if ii < 5
ker{ii}(ii) = -1;
else
ker{ii}(ii+1) = -1;
end
end
interim = zeros( [size(A,1) size(A,2), numel(ker)] ); % allocate room for intermidiate results
for ii=1:numel(ker)
interim(:,:,ii) = conv2(A, ker{ii}, 'same' ); %//'same' takes care of output size for you
end
Now interim holds each of the different a(5)-a(i) we are ready for the non-linear operation
interim = interim.^2;
B = 0.5 * interim;

Method to sum of the elements of different sized matrix in Matlab

Can anybody help me to find out the method to sum of the elements of different sized matrix in Matlab ?
Let say that I have 2 matrices with numbers.
Example:
A=[1 2 3;
4 5 6;
7 8 9]
B=[10 20 30;
40 50 60]
I wanna create matrix C filling with sum(absolute subtract of matrix A and B).
Example in MS Excel.
D10=ABS(D3-I3)+ABS(E3-J3)+ABS(F3-K3)
E10=ABS(D4-I3)+ABS(E4-J3)+ABS(F4-K3)
F10=ABS(D5-I3)+ABS(E5-J3)+ABS(F5-K3)
And then (Like above)
D11=ABS(D3-I4)+ABS(E3-J4)+ABS(F3-K4)
E11=ABS(D4-I4)+ABS(E4-J4)+ABS(F4-K4)
F11=ABS(D5-I4)+ABS(E5-J4)+ABS(F5-K4)
Actually A is a 30x8 matrix and B is a 10x8 matrix.
How can i write this in Matlab?
Code
%%// Spread out B to the third dimension so that the singleton
%%// second dimension thus created could be used with bsxfun for expansion in
%%// that dimension
t1 = permute(B,[3 2 1])
%%// Perform row-wise subtraction and then summing of their absolute values
%%// as needed
t2 = sum(abs(bsxfun(#minus,A,t1)),2)
%%// Since the expansion resulted in data in third dimension, we need to
%%// squeeze it back to a 2D data
out = squeeze(t2)'