face recognition using surf features and knn search tree - matlab

i have been working on a project on face recognition using surf features and knn search tree using matlab 2014A the problem i am facing is that i am not able to match the results from knn search tree to manually with each file in data base so i can specify which face resembles the sample the most. Can anybody help me how to find the three nearest neighbours in data base?
this is my code
% Combine all features into dataset
i have 128 surf features for each face in database
featureDataset = double(vertcat(imageCollection.featureVectors));
% instantiate a kd tree
imageFeatureKDTree = KDTreeSearcher(featureDataset);
query.wholeImage = imread('F\:trio.jpg');
faceDetector = vision.CascadeObjectDetector();
bbox = step(faceDetector, query.wholeImage)
Out=query.wholeImage;
for k = 1:size(bbox,1)
figure; axesHandle=axes; imshow(query.wholeImage); title('Query Image');
rectangleHandle=imrect(axesHandle,bbox(k,:)) ;
% Consider only selected region
query.image=imcrop(query.wholeImage,getPosition(rectangleHandle));
query.image=rgb2gray(query.image);
% Detect SURF features
query.points = detectSURFFeatures(query.image);
% Extract SURF descriptors
[query.featureVectors,query.points] = ...
extractFeatures(query.image,query.points,'SURFSize',128);
[matches, distance] = knnsearch(imageFeatureKDTree,query.featureVectors,'Distance','euclidean','K',3);
indexIntervals = [0, cumsum([imageCollection.featureCount])] + 1;
counts = histc(matches(:, 1), indexIntervals);
counts1=histc(matches(:, 2), indexIntervals);
counts2=histc(matches(:, 3+), indexIntervals);
if max(counts)==0
disp('No Features Matched')
else
for i = 1:numel(imageCollection) % Scale each image
if (counts(i)==max(counts))
name=srcFiles(i).name;
end
if (counts(i)==max(counts1))
name1=srcFiles(i).name;
end
if (counts(i)==max(counts2))
name2=srcFiles(i).name;
end
end
t1 = strcmpi(name(1:10),name1(1:10));t2=strcmpi(name(1:10),name2(1:10));
t3=strcmpi(name1(1:10),name2(1:10));
if((t1==1)||(t2==1)||(t3==1))
Out = insertObjectAnnotation(Out,'rectangle',bbox(k,:),name(1:length(name)-1));
else if (t3==1)
Out = insertObjectAnnotation(Out,'rectangle',bbox(k,:),name1(1:length(name)-1));
else
Out = insertObjectAnnotation(Out,'rectangle',bbox(k,:),'not matched');
end
end
end
end
imshow(Out)

Related

What is the better way to change the percentages of the training and the testing during the splitting process?

With using the PCA technique and the Yale database, I'm trying to work on face recognition within Matlab by randomly splitting the training process to 20% and the testing process to 80%. It is given an
Index in position 2 exceeds array bounds (must not exceed 29)
error. The following is the code, hoping to get help:
dataset = load('yale_FaceDataset.mat');
trainSz = round(dataset.samples*0.2);
testSz = round(dataset.samples*0.8);
trainSetCell = cell(1,trainSz*dataset.classes);
testSetCell = cell(1,testSz*dataset.classes);
j = 1;
k = 1;
m = 1;
for i = 1:dataset.classes
% training set
trainSetCell(k:k+trainSz-1) = dataset.images(j:j+trainSz-1);
trainLabels(k:k+trainSz-1) = dataset.labels(j:j+trainSz-1);
k = k+trainSz;
% test set
testSetCell(m:m+testSz-1) = dataset.images(j+trainSz:j+dataset.samples-1);
testLabels(m:m+testSz-1) = dataset.labels(j+trainSz:j+dataset.samples-1);
m = m+testSz;
j = j+dataset.samples;
end
% convert the data from a cell into a matrix format
numImgs = length(trainSetCell);
trainSet = zeros(numImgs,numel(trainSetCell{1}));
for i = 1:numImgs
trainSet(i,:) = reshape(trainSetCell{i},[],1);
end
numImgs = length(testSetCell);
testSet = zeros(numImgs,numel(testSetCell{1}));
for i = 1:numImgs
testSet(i,:) = reshape(testSetCell{i},[],1);
end
%% applying PCA
% compute the mean face
mu = mean(trainSet)';
% centre the training data
trainSet = trainSet - (repmat(mu,1,size(trainSet,1)))';
% generate the eigenfaces(features of the training set)
eigenfaces = pca(trainSet);
% set the number of principal components
Ncomponents = 100;
% Out of the generated components, we keep "Ncomponents"
eigenfaces = eigenfaces(:,1:Ncomponents);
% generate training features
trainFeatures = eigenfaces' * trainSet';
% Subspace projection
% centre features
testSet = testSet - (repmat(mu,1,size(testSet,1)))';
% subspace projection
testFeatures = inv(eigenfaces'*eigenfaces) * eigenfaces' * testSet';
mdl = fitcdiscr(trainFeatures',trainLabels);
labels = predict(mdl,testFeatures');
% find the images that were recognised and their respect. labels
correctRec = find(testLabels == labels');
correctLabels = labels(correctRec);
% find the images that were NOT recognised and their respect. labels
falseRec = find(testLabels ~= labels');
falseLabels = labels(falseRec);
% compute and display the recognition rate
result = length(correctRec)/length(testLabels)*100;
fprintf('The recognition rate is: %0.3f \n',result);
% divide the images into : recognised and unrecognised
correctTest = testSetCell(correctRec);
falseTest = testSetCell(falseRec);
% display some recognised samples and their respective labels
imgshow(correctTest(1:8),correctLabels(1:8));
% display all unrecognised samples and their respective labels
imgshow(falseTest(1:length(falseTest)), falseLabels(1:length(falseTest)));
it would be nice, if you provide also the line-number and the full message of the error and if you would strip your code to the essential. I guess, the PCA-stuff is not necessary here, as the error is raised probably in your loop. That is because you are incrementing j by j = j+dataset.samples; and take this in the next loop-set for indexing j:j+trainSz-1, which now must exceed dataset.samples...
Nevertheless, there is no randomness in the indexing. It is easiest if you use the built-in cvpartition-function:
% split data
cvp = cvpartition(Lbl,'HoldOut',.2);
lgTrn = cvp.training;
lgTst = cvp.test;
You may provide the number of classes as first input (Lbl in this case) or the actual class vector to let cvpartition pick random subsets that reflect the original distribution of the individual classes.

How to improve the OCR accuracy rate of Neural Network in Matlab

I'm working on OCR for Arabic character. I want to try glcm as a features extraction method. I've got the code here: http://www.mathworks.com/matlabcentral/fileexchange/22187-glcm-texture-features
Example of input images (character images):
and I've made a code to get the GLCM output based on needed features. Here it is:
function features = EkstraksiFitur_GLCM(x)
glcm = graycomatrix(x,'offset',[0 1; -1 1; -1 0; -1 -1], 'NumLevels', 2);
stats = GLCM_Features1(glcm, 0);
autocorrelation = double(mean (stats.autoc));
if isnan(autocorrelation)
autocorrelation=0;
else
autocorrelation=autocorrelation;
end
contrast = double(mean(stats.contr));
if isnan(contrast)
contrast=0;
else
contrast=contrast;
end
Correlation = double(mean (stats.corrm));
if isnan(Correlation)
Correlation=0;
else
Correlation=Correlation;
end
ClusterProminence = double(mean (stats.cprom));
if isnan(ClusterProminence)
ClusterProminence=0;
else
ClusterProminence=ClusterProminence;
end
ClusterShade = double(mean (stats.cshad));
if isnan(ClusterShade)
ClusterShade=0;
else
ClusterShade=ClusterShade;
end
Dissimilarity = double(mean (stats.dissi));
if isnan(Dissimilarity)
Dissimilarity=0;
else
Dissimilarity=Dissimilarity;
end
Energy = double(mean (stats.energ));
if isnan(Energy)
Energy=0;
else
Energy=Energy;
end
.
.
.
features=[autocorrelation, contrast, Correlation, Dissimilarity, Energy, Entropy, Homogeneity, MaximumProbability, SumAverage, SumVariance, SumEntropy, DifferenceVariance, DifferenceEntropy, InverseDifferenceMomentNormalized];
Using loop to get the features of all the images (data train):
srcFile = dir('D:\1. Thesis FINISH!!!\Data set\0 Well Segmented Character\Advertising Bold 24\datatrain\*.png');
fetrain = [];
for a = 1:length(srcFile)
file_name = strcat('D:\1. Thesis FINISH!!!\Data set\0 Well Segmented Character\Advertising Bold 24\datatrain\',srcFile(b).name);
A = imread(file_name);
[gl] = EkstraksiFitur_GLCM2 (A);
[fiturtrain] = reshape (gl, [56,1]) ;
fetrain = [fetrain fiturtrain];
% vectorname = strcat(file_name,'_array.mat');
end
save ('fetrain.mat','fetrain');
I've got the features.
And then run the training process using Neural Network, but I get a very low accuracy rate. This is the code:
% clc;clear;close all;
% function net1 = pelatihan (input, target)
net = newff(fetrain,target,[10 2],{'tansig','tansig'},'trainscg');
% net.trainParam.mem_reduc = 2;
net.performFcn = 'mse';
net.divideFcn = 'dividetrain';
% [trainInd,valInd,testInd] = dividetrain(601);
net.trainParam.show = 10; % Frequency of progress displays (in epochs).
net.trainParam.epochs = 1000; %default 1000
net.trainParam.goal = 1e-6;
net = train(net,fetrain,target);
output = round(sim(net,fetrain));
save net1.mat net
% net2 = output;
data = fetest;
[target; output];
prediksi = round(sim (net, data));
[targetx; prediksi];
%% Calculate the accuracy %
y = 1;
j = size (prediksi, 2);
% x = size (targetx, 2);
for i = 1:j
if prediksi (i) == targetx (i)
y =y+1;
else
y;
end
end
% y all correct data
% j all data
s = 'The accuracy is %.2f%%';
acc = 100 *(y/j);
sprintf (s,acc)
I've tried several times, but the accuracy rate (NN test result) wasn't improve. It's contantly give output 1.96%. Is there something wrong with the process flow, or with the code that i've made?
Any help would be very helpful and appreciated
First I can see from the feature you extracted that they are nnot normalized and they vary in range. which means some of the fetaure wil dominate the rest. try to normalize or standarize the features. is the accuracy you measure on training set only or you are some test set or cross validation methods? is it true what I see you are using 601 features? did you try features selection methods to decide which features belong better to the data and the model?
Second I would like to know what you are implementing for the structure instead of reading the full code to understand what you have done.
third would be intersting to look at the input image to understand the enviremoent you are dealing with.

Extracting feature points from flow lines and clustering them?

I'm trying to make a reliable passenger counting system using matlab, the camera will be fixed and above the door. I a able to get flow lines using Lucas Kanade optical flow, the lines represent the people's motion. I want to:
extract from these lines only the end points, if the line is long enough (the lines matrix contains all the points, even say a point on some random part of floor which will not have changed)
Cluster these 'good points' and get the centroids of the clustsers, representing people
Create bounding boxes of a fixed size on those cluster centers and send them to the multiple object KLT tracking program.
Would anyone happen to show me a good way to extract the points I want from the line matrix? My matlab syntax is atrocious and I'm running out of time to get this done, its for a uni project. Thanks in advance!
%example
videoReader = vision.VideoFileReader('5Converted.avi','ImageColorSpace','Intensity','VideoOutputDataType','uint8');
converter = vision.ImageDataTypeConverter;
opticalFlow = vision.OpticalFlow('ReferenceFrameDelay', 1);
opticalFlow.OutputValue = 'Horizontal and vertical components in complex form';
shapeInserter = vision.ShapeInserter('Shape','Lines','BorderColor','Custom', 'CustomBorderColor', 255);
videoPlayer = vision.VideoPlayer('Name','Motion Vector');
while ~isDone(videoReader)
frame = step(videoReader);
im = step(converter, frame);
of = step(opticalFlow, im);
[lines, trackedPoints] = getFlowLines(of, 20);
if ~isempty(lines)
out = step(shapeInserter, im, lines);
end
end
release(videoPlayer);
release(videoReader);
And this is the GetFLowLines Function (slightly modified version of an example):
> function [vel_Lines, allTrackedPoints] = getFlowLines(vel_Values,
> scaleFactor) %Modified function based on Matlab's
> 'videooptflowlines.m' helper function
>
> persistent first_time; persistent X; persistent Y; persistent RV;
> persistent CV; if isempty(first_time)
> first_time = 1;
> %% user may change the following three parameters
> borderOffset = 5;
> decimFactorRow = 5;
> decimFactorCol = 5;
> %%
> [R C] = size(vel_Values);
> RV = borderOffset:decimFactorRow:(R-borderOffset);
> CV = borderOffset:decimFactorCol:(C-borderOffset);
> [Y X] = meshgrid(CV,RV); end
>
> tmp = vel_Values(RV,CV); tmp = tmp.*scaleFactor; vel_Lines = [Y(:)
> X(:) Y(:)+real(tmp(:)) X(:)+imag(tmp(:))]; allTrackedPoints =
> [Y(:)+real(tmp(:)) X(:)+imag(tmp(:))];

Matlab GUI for array of spots

I need to create a GUI in Matlab. It requires me to identify the spots for two images, and calculate the distance between them.
I have obtained the code for finding and encircling a single spot. It is as follows:
function [meanx,meany] = centroid(pic)
[x,y,z] = size(pic);
if(z==1)
;
else
pic = rgb2gray(pic);
end
% N=2;
% image = interp2(double(pic),N,'spline');
image = sort(sort(pic,1),2);
image =reshape(image,1,numel(image));
i=0;
while(i<3)
if(image(end)==image(end-1))
image(end)=[];
else
image(end)=[];
i=i+1;
end
end
threshold = image(end);
pic2 =(pic>=threshold);
pic=(pic-threshold).*uint8(pic2);
% % image=(pic-threshold+1).*uint8(image); %minus threshold
[rows,cols] = size(pic);
x = ones(rows,1)*[1:cols];
y = [1:rows]'*ones(1,cols);
area = sum(sum(pic));
if area ~= 0
meanx = sum(sum(double(pic).*x))/area;
meany = sum(sum(double(pic).*y))/area;
else
meanx = cols/2;
meany = rows/2;
end
However, I need it to work for multiple spots as shown below :
http://imgur.com/oEe0mRV,UAnbH5y#0
http://imgur.com/oEe0mRV,UAnbH5y#1
So far, I have come up with this, but it only circles separate spots and not all together.
PLEASE HELP - I need to encircle at least 10X10 spots and store their values, and do this for two images as shown above, and find the distance between them!
img1 = imread('r0.bmp');
centroidmat=zeros(10,10,2);
for numx=1:2
for numy=1:2
single_spot=img1((numx*220+780):((numx+1)*220+780),(numy*220+1272):((numy+1)*220+1272),:);
figure
imshow(single_spot);
figure
[cx,cy] = centroid(single_spot);
centroidmat(numx,numy,1)=cx;
centroidmat(numx,numy,2)=cy;
imshow(single_spot);
hold on;
plot(cx,cy,'og')
end
end
Please HELP GUYS! Any help is appreciated!
Would this work ? -
centroidmat=zeros(10,10,2);
for numx=1:2
for numy=1:2
single_spot=img1((numx*220+780):((numx+1)*220+780),(numy*220+1272):((numy+1)*220+1272),:);
[cx,cy] = centroid(single_spot);
centroidmat(numx,numy,1)=cx;
centroidmat(numx,numy,2)=cy;
figure,
imshow(single_spot);
hold on;
plot(cx,cy,'og')
end
end
I have only removed the redundant figure and imshow(single_spot); at the start of the loop, as they appear again later on inside the same loop.

Kmean plotting in matlab

I am on a project thumb recognition system on matlab. I implemented Kmean Algorithm and I got results as well. Actually now I want to plot the results like here they done. I am trying but couldn't be able to do so. I am using the following code.
load training.mat; % loaded just to get trainingData variable
labelData = zeros(200,1);
labelData(1:100,:) = 0;
labelData(101:200,:) = 1;
k=2;
[trainCtr, traina] = kmeans(trainingData,k);
trainingResult1=[];
for i=1:k
trainingResult1 = [trainingResult1 sum(trainCtr(1:100)==i)];
end
trainingResult2=[];
for i=1:k
trainingResult2 = [trainingResult2 sum(trainCtr(101:200)==i)];
end
load testing.mat; % loaded just to get testingData variable
c1 = zeros(k,1054);
c1 = traina;
cluster = zeros(200,1);
for j=1:200
testTemp = repmat(testingData(j,1:1054),k,1);
difference = sum((c1 - testTemp).^2, 2);
[value index] = min(difference);
cluster(j,1) = index;
end
testingResult1 = [];
for i=1:k
testingResult1 = [testingResult1 sum(cluster(1:100)==i)];
end
testingResult2 = [];
for i=1:k
testingResult2 = [testingResult2 sum(cluster(101:200)==i)];
end
in above code trainingData is matrix of 200 X 1054 in which 200 are images of thumbs and 1054 are columns. actually each image is of 25 X 42. I reshaped each image in to row matrix (1 X 1050) and 4 other (some features) columns so total of 1054 columns are in each image. Similarly testingData I made it in the similar manner as I made testingData It is also the order of 200 X 1054. Now my Problem is just to plot the results as they did in here.
After selecting 2 features, you can just follow the example. Start a figure, use hold on, and use plot or scatter to plot the centroids and the data points. E.g.
selectedFeatures = [42,43];
plot(trainingData(trainCtr==1,selectedFeatures(1)),
trainingData(trainCtr==1,selectedFeatures(2)),
'r.','MarkerSize',12)
Would plot the selected feature values of the data points in cluster 1.