Determinant of hessian matrix of a grayscale image is too small in matlab - 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)

Related

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

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);

Filtering in Frequency Domain

I have to apply prewit filter to an image in the frequency domain.Here is the procedure I am following.
1) Convert the NxN matrix of image to 2*Nx2*N matrix by padding zeros
2) Center the image transform by multiplying image with (-1)^(x+y)
3) Compute DFT of image matrix
4) Create the filter of dimensions 2Nx2N and the center at coordinates (N,N)
5) Multiply image matrix with filter matrix
6) Calculate inverse DFT of it and extract the real part of result.
7) Decentralize the result by multiplying with (-1)^(x+y)
8) Finally extract the upper left NxN part of the resultant matrix
My code is below:
% mask=[-1,0,1;-1,0,1;-1,0,1];
%read image
signal=imread('cman.pgm');
signal=double(signal);
% image has NxN dimensions
l=size(signal,1);
pad_signal=zeros(2*l,2*l);
pad_signal(1:l,1:l)=signal;
m=size(mask,1);
mask_f=zeros(2*l,2*l);
for i=-1:1
mask_f(l+i,l-1)=-1;
mask_f(l+i,l+1)=1;
end
x=1:2*l;
[x y]=meshgrid(x,x);
% Multiply each pixel f(x,y) with (-1)*(x+y)
pad_signal=pad_signal.*((-1).^(x+y));
mask_f=myDFT(mask_f);
%find the DFT of image
signal_dft=myDFT(pad_signal);
%multiply the filter with image
res=mask_f*signal_dft;
% find the inverse DFT of real values of result
res=real(myIDFT(res));
res=res.*((-1).^(x+y));
%extract the upper left NxN portion of the result
res=res(1:l,1:l);
imshow(uint8(res));
The method above is from an image processing book. What I am confused about is should I be using a window of 3x3 as prewitt filter is of 3x3 or is my current way of using the filter correct? (i.e. by placing the filter values at centre of 2Nx2N filter matrix and setting all other index values to 0) .
If not either of them, then how should the filter be formed to be multiplied with the dft of image.
Your current way of padding the filter to be the same size as the image is basically correct. We often speak loosely about filtering a length M signal with a length 3 filter, but the implicit assumption is that we are padding both to length M, or maybe length M+3-1.
Some details of your approach complicate things:
1) The multiplication by (-1)^(x+y) just translates the DFT and isn't needed. (See Foundations of Signal Processing Table 3.7 "Circular shift in frequency" for the 1D case. In that notation, you are letting k_0 be N/2, so the W_N term in the left column is just toggling between -1 and 1.)
2) Because the Prewitt filter only has a 3x3 non-zero support, your output only needs to be of size N+2 by N+2. The formula to remember here is length(signal) + length(filter) - 1.
Here's how I would approach this:
clear
x = im2double(imread('cameraman.tif'));
[M, N] = size(x);
h = [-1 0 1;
-1 0 1;
-1 0 1];
P = M + size(h,1) - 1;
Q = N + size(h,2) - 1;
xPadded = x;
xPadded(P, Q) = 0;
hPadded = h;
hPadded(P,Q) = 0;
hShifted = circshift(hPadded, [-1 -1]);
H = fft2(hShifted);
X = fft2(xPadded);
Y = H .* X;
y = ifft2(Y);
yCropped = y(1:M, 1:N);
imshow(yCropped,[]);
Here is how I have solved my problem. I first removed step 2 and 7 from the algorithm. Then centered the transform by swapping the first half of the indices with the second half, in both horizontal and vertical direction. I did this to center the transform of the image. Then I undid this after calculating the inverse DFT of the resultant matrix. I am not sure why my above method does not work but it does so now.
1) Convert the NxN matrix of image to 2*Nx2*N matrix by padding zeros
2) Compute DFT of image matrix
3) Centre the transform of the image by swapping the first and second half of rows and columns.
4) Create the filter of dimensions 2Nx2N and the center at coordinates (N,N)
5) Multiply image matrix with filter matrix
6) Calculate inverse DFT of it and extract the real part of result.
7) Decentralize the result by reapplying step 3 on the resultant matrix
8) Finally extract the upper left NxN part of the resultant matrix
The above is the modified version of steps that I have followed when applying my filtering.
Here is my code (edited/new version)
function res=myFreqConv(signal,mask)
signal=double(signal);
l=size(signal,1);
% padding the image matrix with zeros and making it's size equal to
% 2Nx2N
pad_signal=zeros(2*l,2*l);
pad_signal(1:l,1:l)=signal;
m=size(mask,1);
mask_f=zeros(2*l,2*l);
% Creating a mask of 2Nx2N dims where the prewitt filter values are
at
% the center of the mask i.e. the indices are like this
% [(N-1,N-1), (N-1,N), (N-1,N+1);(N,N-1), (N,N), (N,N+1); (N+1,N-1),
(N+1,N), (N+1,N+1)]
for i=-1:1
mask_f(l+i,l-1)=-1;
mask_f(l+i,l+1)=1;
end
% calculate DFT of mask
mask_f=myDFT(mask_f);
signal_dft=myDFT(pad_signal);
% shifting the image transform to center
indices=cell(1,2);
indices{1}=[2*l/2+1:2*l 1:2*l/2];
indices{2}=[2*l/2+1:2*l 1:2*l/2];
signal_dft=signal_dft(indices{:});
%multiply mask with image
res=mask_f.*signal_dft;
res=real(myIDFT(res));
% shifting the image transform back to original
res=res(indices{:});
res=res(1:l,1:l);
end

Calculating the degree matrix having the sparse representation of the adjacency matrix

I am trying to calculate the laplacian matrix of a graph. I ve calculated the sparse representation of the adjacency matrix which is stored in a text file with dimension Nx3. N the size of nodes (ith-node jth node weight). I open in Matlab this file with adj = spconvert(adj);. The next step is to calculate the degree matrix of this sparse matrix in order to perform the operation L = D - adj. How is it possible to calculate the degree matrix having as an input the sparse adjacency matrix of the graph? In order to calculate the degree matrix I calculate the degree for every node:
for i=1:n % size of the node
degree(i) = length(find(adj(:,1) == i & adj(:,3) == 1));
end
However, how can I perform the subtraction of D and A?
Use the spdiags function to convert the degree vector to a sparse diagonal matrix. Then subtract the adjacency matrix from diagonal matrix to get the Laplacian. Example using your code:
adj = spconvert(adj);
for i=1:size(adj, 1)
degree(i) = CalcDegree(adj, i)
end
D = spdiags(degree, 0, size(adj, 1), size(adj, 2));
L = D - adj;
By the way, your code for calculating the node degree may be incorrect.

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)

How to normalize a matrix of 3-D vectors

I have a 512x512x3 matrix that stores 512x512 there-dimensional vectors. What is the best way to normalize all those vectors, so that my result are 512x512 vectors with length that equals 1?
At the moment I use for loops, but I don't think that is the best way in MATLAB.
If the vectors are Euclidean, the length of each is the square root of the sum of the squares of its coordinates. To normalize each vector individually so that it has unit length, you need to divide its coordinates by its norm. For that purpose you can use bsxfun:
norm_A = sqrt(sum(A .^ 2, 3)_; %// Calculate Euclidean length
norm_A(norm_A < eps) == 1; %// Avoid division by zero
B = bsxfun(#rdivide, A, norm_A); %// Normalize
where A is your original 3-D vector matrix.
EDIT: Following Shai's comment, added a fix to avoid possible division by zero for null vectors.