I'm trying to find eigenvalues and vectors of a grayscale image and getting error "Matrix dimensions must agree" - matlab

The code is giving error "matrix dimension must agree". So what changes should i make?
%reading a image
I =imread('C:\Program Files\MATLAB\R2013a\New folder\fac.jpg');
m = mean(I,2);
I = double(I)- double(repmat(m,10,1));
%calculating covariance matrix
c=cov(I);
%calculating eigenvalues and eigenvectors
[eigenvalue,eigenvector]=eig(c);

First, make sure that I is a 2D matrix. This is necessary for cov to work. Secondly, use repmat(m,n,p), where n and p are such that size(repmat(m,n,p))==size(I).
Example
I =imread('myImg.jpg'); % 63x83x3 matrix containing 3D RGB information.
I = rgb2gray(I); % 3D RGB to 2D gray scale. Now I is a 63x83 matrix.
m = mean(I,2);
I = double(I)- double(repmat(m,1,83));
c=cov(I);
[eigenvalue,eigenvector]=eig(c);

Related

Dimension of Filter in 3-D Convolution in MATLAB

The function to perform an N-dimensional convolution of arrays A and B in matlab is shown below:
C = convn(A,B) % returns the N-dimensional convolution of arrays A and B.
I am interested in a 3-D convolution with a Gaussian filter.
If A is a 3 x 5 x 6 matrix, what do the dimensions of B have to be?
The dimensions of B can be anything you want. There is no set restriction in terms of size. For the Gaussian filter, it can be 1D, 2D or 3D. In 1D, what will happen is that each row gets filtered independently. In 2D, what will happen is that each slice gets filtered independently. Finally, in 3D you will be doing what is expected in 3D convolution. I am assuming you would like a full 3D convolution, not just 1D or 2D.
You may be interested in the output size of convn. If you refer to the documentation, given the two N dimensional matrices, for each dimension k of the output and if nak is the size of dimension k for the matrix A and nbk is the size of dimension k for matrix B, the size of dimension of the output matrix C or nck is such that:
nck = max([nak + nbk - 1, nak, nbk])
nak + nbk - 1 is straight from convolution theory. The final output size of a dimension is simply the sum of the two sizes in dimension k subtracted by 1. However should this value be smaller than either of nak or nbk, we need to make sure that the output size is compatible so that any of the input matrices can fit in the final output. This is why you have the final output size and bounded by both A and B.
To make this easier, you can set the size of the filter guided by the standard deviation of the distribution. I would like to refer you to my previous Stack Overflow post: By which measures should I set the size of my Gaussian filter in MATLAB?
This determines what the output size of a Gaussian filter should be given a standard deviation.
In 2D, the dimensions of the filter are N x N, such that N = ceil(6*sigma + 1) with sigma being the desired standard deviation. Therefore, you would allocate a 3D matrix of size N x N x N with N = ceil(6*sigma + 1);.
Therefore, the code you would want to use to create a 3D Gaussian filter would be something like this:
% Example input
A = rand(3, 5, 6);
sigma = 0.5; % Example
% Find size of Gaussian filter
N = ceil(6*sigma + 1);
% Define grid of centered coordinates of size N x N x N
[X, Y, Z] = meshgrid(-N/2 : N/2);
% Compute Gaussian filter - note normalization step
B = exp(-(X.^2 + Y.^2 + Z.^2) / (2.0*sigma^2));
B = B / sum(B(:));
% Convolve
C = convn(A, B);
One final note is that if the filter you provide has any of its dimensions that are beyond the size of the input matrix A, you will get a matrix using the constraints of each nck value, but then the border elements will be zeroed due to zero-padding.

Determinant of hessian matrix of a grayscale image is too small in matlab

I am trying to find determinant of hessian matrix of a 50x50 grayscale image. Determinant of matrix I am getting is a very small value i.e 4.7612e-134. I think I am missing something. My code is below. Thanks
% computing second derivatives in each direction first
[gx, gy] = gradient(double(sliceOfImageK2));
[gxx, gxy] = gradient(gx);
[gyx, gyy] = gradient(gy);
hessianMatrix = [gxx gxy; gxy gyy];
determinantHessianMatrix = det(hessianMatrix)
I don't think you should assemble a 100x100 matrix if you want to call it Hessian. Assemble instead a 2x2 matrix per each of the 50x50 (2500) pixels where you are sampling your derivatives.
These are the 2500 hessians, expressed in a 2500x4 matrix:
H = [gxx(:) gxy(:) gyx(:) gyy(:)]
Here expressed as 2500 2x2 matrices:
H_ = reshape(H', 2, 2, length(H))
And these are the determinants of each 2x2 matrix:
D = H(:,1).*H(:,4) - H(:,2).*H(:,3)
Here as a 50x50 matrix with the determinant of the Hessian at each pixel, if that is what you are after:
reshape(D, 50, 50)

Eigen faces using PCA

I am trying to implement Principal Component Analysis (PCA) to extract the features from the image in MATLAB. I have implemented the following code.
[Rows, Columns] = size(x); % find size of input matrix
m=mean(x); % find mean of input matrix
y=x-ones(size(x,1),1)*m; % normalise by subtracting mean
c=cov(y); % find covariance matrix
[V,D]=eig(c); % find eigenvectors (V) and eigenvalues (D) of covariance matrix
[D,idx] = sort(diag(D)); % sort eigenvalues in descending order by first diagonalising eigenvalue matrix, idx stores order to use when ordering eigenvectors
D = D(end:-1:1)';
V = V(:,idx(end:-1:1)); % put eigenvectors in order to correspond with eigenvalues
V2d=V(:,1:200); % (significant Principal Components we use, OutputSize is input variable)
prefinal=V2d'*y';
final=prefinal'; % final is normalised data projected onto eigenspace
imshow(final);
I want to know that how can I check the 1st Eigen faces,2nd Eigen faces.. etc
EDIT:
Here is the Input Image and the Eigen Image is Eigen Image
The first eigenface is the first eigenvector!
My guess, is that with your code:
eigenface1=reshape(V(:,1),rows,cols);
as, if your code is right, each eigenvector should be the same size as your input images, but unrolled. I am assuming that rows and cols are the size of the image.

2D convolution of slices of 3D matrix

I'm trying to do a bunch of rolling sums over matrices in MATLAB. In order to avoid loops I've used repmat to layer my 2D matrices into a 3D structure. However, now the fast convolution function conv2 can no longer be used for the accumulator. However, the N-dimensional convolution function (convn) is not what I'm looking for either as it literally convolves all 3 dimensions. I want something that will do a 2D convolution on each slice and return a 3D matrix.
Tiling the matrices in 2D instead of layering them in 3D won't work because it will corrupt the convolution edge cases. I could pad with zeros in between but then it starts getting kind of messy.
In other words, without a for-loop, how can I perform the following:
A = ones(5,5,5);
B = zeros(size(A));
for i = 1 : size(A, 3)
B(:,:,i) = conv2(A(:,:,i), ones(2), 'same');
end
Thanks in advance for the help!
convn will work with an n-dimensional matrix and a 2-dimensional filter. Simply:
A = ones(5,5,5);
B = convn(A, ones(2), 'same');
You can use some padding with zeros and reshaping like so -
%// Store size parameters
[m,n,r] = size(A)
[m1,n1] = size(kernel)
%// Create a zeros padded version of the input array. We need to pad zeros at the end
%// rows and columns to replicate the convolutionoperation around those boundaries
Ap = zeros(m+m1-1,n+n1-1,r);
Ap(1:m,1:n,:) = A;
%// Reshape the padded version into a 3D array and apply conv2 on it and
%// reshape back to the original 3D array size
B_vect = reshape(conv2(reshape(Ap,size(Ap,1),[]),kernel,'same'),size(Ap))
%// Get rid of the padded rows and columns for the final output
B_vect = B_vect(1:m,1:n,:);
The basic idea is to reshape the input 3D array into a 2D array and then apply the 2D convolution on it. Extra step is needed with padding so as to have the same behavior as you would see with conv2 around the boundaries.

Finding Image EigenVector and Eigenvalue

I am new to the concept of feature detection. I calculated eigenvectors and eigenvlues of a matrix simply by using lambda=eig(Matrix). I want to know how to calculate eigenvalues and eigenvectors of gray scale image. Thank You.
The eig function accepts a square matrix of type double or single as input. First convert the image from grayscale (uint8 or uint16) to double, and then make it square. See the following code example:
%Read in some grayscale image:
Matrix = imread('lena_gray.jpg');
%Convert image to double precision to use eig function:
imtype = class(Matrix);
Matrix = double(Matrix);
%Find a square matrix that fits image for eig operation:
sz = size(Matrix);
m = max(sz);
mx = zeros(m, m);
mx(1:sz(1),1:sz(2)) = Matrix;
%Find eigenvectors and eigenvalues:
[V, D] = eig(mx);
%check that the matrix generates A using matrix factorization and convert back to original
image:
eval(['A = ',imtype,'(abs(V*D*V^(-1)));']);
figure
imshow(A)