how to obtain the eigenfaces using eigenvalues and eigen vectors? - matlab

i want to find eigenfaces from eigen values here is the code for reference.
clc;
clear all;
close all;
% I) READ IMAGES
for i = 1:9
img{i} = imread(['C:\Users\shree\Desktop\archana\target\' num2str(i) '.jpg']);
end
%II) CONVERTING TO GRAY SCALE
gray_img=cellfun(#rgb2gray,img,'uniformoutput',false);
%imshow(gray_img{2});
%III) RESIZING GRAY IMAGES
res_img = cellfun(#(x)(imresize(x, [50, 50])), gray_img, 'UniformOutput', false);
%imshow(res_img{2});
%DISPLAYING ALL IMAGE
D=[res_img{1} res_img{2} res_img{3}
res_img{4} res_img{5} res_img{6}
res_img{7} res_img{8} res_img{9}];
figure, imshow(D);
%MEAN IMAGE
mean_img=(res_img{1}+res_img{2}+res_img{3}+res_img{4}+res_img{5}+res_img{6}+res_img{7}+res_img{8}+res_img{9})/9;
figure,imshow(mean_img);
%III)SINGLE VECTOR CONVERSION
vect_img= cellfun(#(x)((x(:))), res_img, 'UniformOutput', false);
%MEAN OF SINGLE VECTOR
mean_vect=(vect_img{1}+vect_img{2}+vect_img{3}+vect_img{4}+vect_img{5}+vect_img{6}+vect_img{7}+vect_img{8}+vect_img{9})/9;
%DEVIATION MATRIX
dev_mat=cellfun(#(x) ((x)-mean_vect),vect_img,'uniformoutput',false);
%imshow(dev_mat{1})
U=[dev_mat{1} dev_mat{2} dev_mat{3} dev_mat{4} dev_mat{5} dev_mat{6} dev_mat{7} dev_mat{8} dev_mat{9} ]
figure ,imshow(U);
%COVARIENCE MATRIX
C=[double(U')*double(U)]/9;
%VARIENCE
v=var(C);
%EIGEN VALUES
lambda = eig(C);
[V,D] = eig(C) ;% eigenvalues (D) & eigenvectors (V),=> A*V = V*D
size(lambda);
% EXTRACT DIONAL OF MATRIX VECTOR
%V = diag(V);
%SORT VARIENCE ACC.DECREASING ORDER
sort(lambda,'descend');
i reached upto the arranging the eiganvalues into non-increasing order plz help me how to procced in order to get the eigenfaces.regards

Instead of loading each file one by one try this
ImageDatabasePath ='C:\Users\shree\Desktop\final data';
ImageFiles = dir(ImageDatabasePath);
Train_Number = 0;
for i = 1:size(ImageFiles,1)
if not(strcmp(ImageFiles(i).name,'.')|strcmp(ImageFiles(i).name,'..')...
|strcmp(ImageFiles(i).name,'Thumbs.db'))
Image_Number = Image_Number + 1;
end
end
Now to make the images into 1D image vectors
T = [ ];
for i = 1 : Image_Number
str = int2str(i);
str = strcat('\',str,'.jpg');
str = strcat(ImageDatabasePath,str);
imt = imread(str);
[irow icol] = size(imt);
temp = reshape(imt,irow*icol,1);
T = [T temp];
end
Calculates mean value
m = mean(T,2);
Train_Number = size(T,2);
Calculates the deviation of each image from the mean image
A = [ ];
for i = 1 : Image_Number
temp = double(T(:,i)) - m;
A = [A temp];
end
Create covariance matrix
L = A'*A;
Calculate eigen values and eigen vector V-eigen vector D-diagonal matrix with eigen values
[V D] = eig(L);
L_eig_vec = [];
for i = 1 : size(V,2)
if( D(i,i)>1 )
L_eig_vec = [L_eig_vec V(:,i)];
end
end
Eigenvectors of covariance matrix C (or so-called "Eigenfaces") can be recovered from L's eiegnvectors.
Eigenfaces = A * L_eig_vec;

Use double(NEW) * double(NEW');
Besides, do not use mean and cov as variable name. They are built-in functions. I guess you want C = cov(double(NEW) * double(NEW')); in the covariance calculation.

Related

gradient of a volume in 3 dimensions using Gaussian derivative in matlab

I want to compute gradient of a volume in MATLAB using Gaussian derivative. but I could not. can any one help me please? I do this in a 2D image using this code:
k = gaussiankernel(sigma1,1); % first order derivative of a gaussian with std
sigma1
gx = imfilter(I,k','replicate','conv');
gy = imfilter(I,k,'replicate','conv');
please help me. How can I compute gz using kernel k? or How can I extend this code to 3D?
Thank you in advance.
This is the code to generate adaptive ellipsoid using structuretensor3d:
function SE = AESE3(I,M,l1,l2,l3,phi3,theta3)
%I = input('Enter the input 3d volume: ');
%M = input('Enter the maximum allowed semi-major axes length: ');
% determining ellipsoid parameteres from eigen value decomposition of 3d
% structure tensor
row = size(I,1);
col = size(I,2);
hei = size(I,3);
SE = cell(row,col,hei);
padI = padarray(I,[M M M],'replicate','both');
padrow = size(padI,1);
padcol = size(padI,2);
padhei = size(padI,3);
[se_x,se_y,se_z] = meshgrid(-M:M,-M:M,-M:M);
for m = M+1:padrow-M
for n = M+1:padcol-M
for p = M+1:padhei-M
i = m-M;
j = n-M;
k = p-M;
a = (l1(i,j,k)+eps)/(l1(i,j,k)+l2(i,j,k)+l3(i,j,k)+3*eps)*M;
b = (l2(i,j,k)+eps)/(l1(i,j,k)+l2(i,j,k)+l3(i,j,k)+3*eps)*M;
c = (l3(i,j,k)+eps)/(l1(i,j,k)+l2(i,j,k)+l3(i,j,k)+3*eps)*M;
cos(phi3(i,j,k)) = cos_phi3;
sin(phi3(i,j,k)) = sin_phi3;
cos(theta3(i,j,k)) = cos_theta3;
sin(theta3(i,j,k)) = sin_theta3;
% defining structuring element for each pixel of image
se = ((se_x.*cos_theta3 - se_y.*sin_theta3.*cos_phi3 +
se_z.*sin_theta3.*sin_phi3).^2)./a.^2+((se_x.*sin_theta3 +
se_y.*cos_theta3.*cos_phi3 - se_z.*cos_theta3.*sin_phi3).^2)./b.^2+
((se_y.*sin_phi3 + se_z.*cos_phi3).^2)./c.^2 <= 1;
SE{i,j,k} = se;
end
end
end
end
Can I do this without zero padding?

I am trying to implement K-NN algorithm. How can I Vectorise the nested for loops for this particular code in MATLAB

My main problem with this code is efficiency,I want to vectorise this section of my code:
for x = 1:N
for c = 1:L
Z = in(x,1:Ks(c,1);
Cpreds(x,c) = mode(Ctrn(Z));
end
end
Below is my implementation in detail:
function [Cpreds] = my_knn_classify(Xtrn,Ctrn, Xtst, Ks)
% Input:
% Xtrn : M-by-D training data matrix
% Ctrn : M-by-1 label vector for Xtrn
% Xtst : N-by-D test data matrix
% Ks : L-by-1 vector of the numbers of nearest neighbours in Xtrn
% Output:
% Cpreds : N-by-L matrix of predicted labels for Xtst
[N,~] = size(Xtst);
B = Xtrn;
Ctrn = Ctrn';
[L,~] = size(Ks);
Cpreds = zeros(N, L);
DI = myfn(Xtst, B); %Vectorising euclidean distance method
[~,in] = sort(DI,2,'ascend');
for x = 1:N
for c = 1:L
Z = in(x,1:Ks(c,1));
Cpreds(x,c) = mode(Ctrn(Z));
end
end
The outer loop is straightforward to vectorise, but the inner loop changes the number of elements passed to mode on each iteration, so is probably unavoidable.
Here is a vectorised version of the outer loop:
for c = 1:L
Z = in(:,1:Ks(c,1));
Cpreds(:,c) = mode(Ctrn(Z),2);
end

From image to vector and vice versa, rotated image

I read a DICOM image and for a variety of reasons, I had to turn the image matrix in a row vector.
After performing various operations on the bits of the vector, I need to reprocess the vector in a DICOM image of the same size as the original.
I've done all these steps but when I go to display the resulting image, this is rotated.
This is what I get:
That's part of the code:
function [I0, Iw] = watIns(filename, w)
I0 = dicomread(filename);
figure(1);
imshow(I0, []);
title('(1) I0 originale');
info = dicominfo(filename);
width = info.Width;
height = info.Height;
size = info.FileSize;
k = info.BitDepth;
% I extract the first k pixels and memorize their LBS in a variable S.
x = 1 : k;
y = 1;
firstKPixel = I0(x, y);
% convert in binary
firstKPixel2 = 0*firstKPixel;
for i = 1 : length(firstKPixel)
if firstKPixel(i) == 0
firstKPixel2(i) = 0;
else
firstKPixel2(i) = dec2bin(firstKPixel(i), 'left-msb');
end
end
% I take the LSB of each element in firstKPixel2 and concatenate in the string S
S = '';
for i = 1 : k
c = firstKPixel2(i, :);
s = num2str(c(end));
S = strcat(S, s);
end
% I compute the vector corresponding to I0 but without the first 0 pixels and the corresponding histogram
[vecComp, histComp] = histKtoEnd(I0, 0, k);
% I compute the vector corresponding to I0 but without the first k pixels and the corresponding histogram
[vecWithoutKPixel, histWithoutKPixel] = histKtoEnd(I0, k, k);
L = ...; % is a vector of values
% I save l_0 in the LSB of the first k pixels.
% prendo l_0, ovvero il primo elemento di L
l_0 = L(1);
l_02 = fliplr(bitget(l_0, 1:k));
% I take the LSB of each element in firstKPixel2 and I sret it to the i-th element of l0_2
for i = 1 : k
c = firstKPixel2(i, :);
c(end) = l_02(i);
firstKPixel2(i, :) = c;
end
% convert to decimal each element of firstKPixel2
for i = 1 : length(firstKPixel2)
str = int2str(firstKPixel2(i));
firstKPixel2_lsb10(i) = bin2dec(str);
end
% I set first k pixels in the image to those just modified
vecComp(1 : k) = firstKPixel2_lsb10(1 : k);
% Transform the vector image
mat = reshape(vecComp, [width, height]);
dicomwrite(mat, './I1.dcm', 'CompressionMode', 'None');
I1 = dicomread('./I1.dcm');
figure(7);
imshow(I1, []); % ROTATE IMAGE!!!
% ...
end
histKtoEnd function is:
function [vecWithoutKPixel, hist] = histKtoEnd(image, k, colorDepth)
imageVec = reshape(image.', [], 1);
l = length(imageVec);
vecWithoutKPixel = imageVec((k+1) : l-1);
vecWithoutKPixel(end+1) = imageVec(l);
hist = zeros(1, 2^colorDepth);
for i = 0 : (2^colorDepth - 1)
grayI = (vecWithoutKPixel == i);
hist(1, i+1) = sum(grayI(:));
end
end
I read here that Matlab shows images like a matrix with the first coordinates (rows) going top-down and the second (columns) left-right.
I couldn't solve, can anyone help me?
Thank you!
Somehow in the unrolling, processing and rolling of your data it seems to get transposed. You can try to find why that happens, but if you do not care, you can always just transpose the result in the end by
mat = reshape(vecComp, [width, height]).';

Average filter in matlab

I'm trying to compute the average of every pixel with just the left and right neighbors but at the end of my processing I get only a white image, I can't find where my error. Here's my code
imageIn = imread('Prueba.jpg');
imageIn = rgb2gray(imageIn);
imageOut = zeros(size(imageIn));
ny = size(imageIn, 1);
nx = size(imageIn, 2);
imshow(imageIn);
u = [];
v = [];
tic
for i = 1:ny
u = imageIn(i,:);
v = zeros(1, ny);
for k = 2:ny-1
v(k) = (uint32(u(k-1))+uint32(u(k))+uint32(u(k+1)))/3;
end
%Special cases first and last pixel
v(1) = (uint32(u(2))+uint32(u(1))+uint32(u(2)))/3;
v(ny) = (uint32(u(ny-1))+uint32(u(ny))+uint32(u(ny-1)))/3;
imageOut(i,:) = v;
end
toc
imshow(imageOut);
Any ideas?
Change the last line of your code to imagesc(imageOut) and you'll see that the image is not in fact white.
Your code is fine; the reason the image appears white using the imshow() function is because after applying your local average the range of pixel intensities is considerably smaller and the default scaling used by imshow() is insufficient to bring out the contrast of the image.
Read about the difference b/t imshow() and imagesc() and you'll see the confusion.
Why not just create a 2nd matrix which is a clone of the first, shift it over and then averate the two matrices?
imIn = imread('Prueba.jpg');
nx = size(d,1);
ny = size(d,2);
% Create temporary matrices padded with nan
tmp1 = [nan(ny,2), d];
tmp2 = [d, nan(ny,2)];
imOut = tmp1;
imOut(:,:,2) = tmp2;
% use nanmean so the mean is just the value of the 1 column
imOut = nanmean(imOut,3);
out = imOut(2:end-1,:);
Try to use this
imageIn = imread('Prueba.jpg');
imageIn = rgb2gray(imageIn);
imageOut = zeros(size(imageIn));
ny = size(imageIn, 1);
nx = size(imageIn, 2);
imshow(imageIn);
u = [];
v = [];
tic
for i = 1:ny
u = imageIn(i,:);
v = zeros(1, ny);
for k = 2:ny-1
v(k) = (uint32(u(k-1))+uint32(u(k))+uint32(u(k+1)))/3;
end
%Special cases first and last pixel
v(1) = (uint32(u(2))+uint32(u(1))+uint32(u(2)))/3;
v(ny) = (uint32(u(ny-1))+uint32(u(ny))+uint32(u(ny-1)))/3;
imageOut(i,:) = v;
end
toc
imshow(imageOut);

Principal Component Analysis in MATLAB

I'm implementing PCA using eigenvalue decomposition for sparse data. I know matlab has PCA implemented, but it helps me understand all the technicalities when I write code.
I've been following the guidance from here, but I'm getting different results in comparison to built-in function princomp.
Could anybody look at it and point me in the right direction.
Here's the code:
function [mu, Ev, Val ] = pca(data)
% mu - mean image
% Ev - matrix whose columns are the eigenvectors corresponding to the eigen
% values Val
% Val - eigenvalues
if nargin ~= 1
error ('usage: [mu,E,Values] = pca_q1(data)');
end
mu = mean(data)';
nimages = size(data,2);
for i = 1:nimages
data(:,i) = data(:,i)-mu(i);
end
L = data'*data;
[Ev, Vals] = eig(L);
[Ev,Vals] = sort(Ev,Vals);
% computing eigenvector of the real covariance matrix
Ev = data * Ev;
Val = diag(Vals);
Vals = Vals / (nimages - 1);
% normalize Ev to unit length
proper = 0;
for i = 1:nimages
Ev(:,i) = Ev(:,1)/norm(Ev(:,i));
if Vals(i) < 0.00001
Ev(:,i) = zeros(size(Ev,1),1);
else
proper = proper+1;
end;
end;
Ev = Ev(:,1:nimages);
Here's how I would do it:
function [V newX D] = myPCA(X)
X = bsxfun(#minus, X, mean(X,1)); %# zero-center
C = (X'*X)./(size(X,1)-1); %'# cov(X)
[V D] = eig(C);
[D order] = sort(diag(D), 'descend'); %# sort cols high to low
V = V(:,order);
newX = X*V(:,1:end);
end
and an example to compare against the PRINCOMP function from the Statistics Toolbox:
load fisheriris
[V newX D] = myPCA(meas);
[PC newData Var] = princomp(meas);
You might also be interested in this related post about performing PCA by SVD.