I am imitating the following MATLAB code. actually, this code implement the eigenface method for face recognition.
%You are free to use, modify or distribute this code
loaded_Image=load_img();
random_Index=round(400*rand(1,1));
random_Image=loaded_Image(:,random_Index);
rest_of_the_images=loaded_Image(:,[1:random_Index-1 random_Index+1:end]);
image_Signature=20;
white_Image=uint8(ones(1,size(rest_of_the_images,2)));
mean_value=uint8(mean(rest_of_the_images,2));
mean_Removed=rest_of_the_images-uint8(single(mean_value)*single(white_Image));
L=single(mean_Removed)'*single(mean_Removed);
[V,D]=eig(L);
V=single(mean_Removed)*V;
V=V(:,end:-1:end-(image_Signature-1));
all_image_Signatire=zeros(size(rest_of_the_images,2),image_Signature);
for i=1:size(rest_of_the_images,2);
all_image_Signatire(i,:)=single(mean_Removed(:,i))'*V;
end
subplot(121);
imshow(reshape(random_Image,112,92));
title('Looking for this Face','FontWeight','bold','Fontsize',16,'color','red');
subplot(122);
p=random_Image-mean_value;
s=single(p)'*V;
z=[];
for i=1:size(rest_of_the_images,2)
z=[z,norm(all_image_Signatire(i,:)-s,2)];
if(rem(i,20)==0),imshow(reshape(rest_of_the_images(:,i),112,92)),end;
drawnow;
end
[a,i]=min(z);
subplot(122);
imshow(reshape(rest_of_the_images(:,i),112,92));
title('Recognition Completed','FontWeight','bold','Fontsize',16,'color','red');
Do you know why it uses single-precision format? what is the applications of this format? as far as I know, the the difference between single-precision format and double-precision format is the number of bits used for exponential, mantissa and etc.
The loaded_Image
, rest_of_the_images
, random_Image
, etc. are all stored as type uint8
for saving space because pixel values range from [0 0 0]
(black) to [255 255 255]
(white) and 8-bits are sufficient for that (0:255). But some mathematical operations are not supported for integer classes. For example, if I try to multiply two uint8
matrices I get this error:
>> uint8(ones(5)) * uint8(ones(5))
Error using *
MTIMES (*) is not fully supported for integer classes.
At least one argument must be scalar.
Same for eig
:
>> eig(uint8(ones(5)))
Error using eig
Invalid data type. Input matrix must be double or single.
So, one has to convert to a supported datatype before the operation and re-convert back to uint8
when storing the image. The author chose single
because it saves 50% of memory compared to double
, but the speed difference will be negligible on modern architectures.
The authors makes unnecessary conversions, though. For example, the following line could be written without any conversions:
mean_Removed = rest_of_the_images - uint8(single(mean_value)*single(white_Image))
% could be written
mean_Removed = rest_of_the_images - mean_value
Other places where single
would be the right choice is when dealing with specific architectures like GPUs, because GPUs fully support single
datatypes but not double
s yet.