How to improve the OCR accuracy rate of Neural Network in Matlab - 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.

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.

Background subtraction And foreground detection using Kalman Filter

I need to separate the background from the foreground in a video using Kalman filter. Can somebody give me some resources or code examples to follow.
Update: i've found a good example here Traffic detection.It worked excellent for Traffic detection but i want to re-adapt it for people extraction. I've found some variables that's need to be adapted for example:
1. alpha = learning constant
2. K= #of guassians in the mixture
3. T = min. portion of background
4. initVariance = initial variance
5. pixelThresh = threshold condition for computing adaptive process on pixel
Here is an overview of the main file (In case just you want an overview)
function foregroundEstimation(movie)
%Load video into memory and prepare output video for writing
v = VideoReader(movie);
numFrames = 150;
foregroundVideo = VideoWriter('foreground.avi');
open(foregroundVideo);
%video constants
initFrame = read(v,1);
global height;
global width;
height = size(initFrame,1);
width = size(initFrame,2);
%initialize GMM parameters: (based upon Stauffer notation)
%http://www.ai.mit.edu/projects/vsam/Publications/stauffer_cvpr98_track.pdf
% alpha = learning constant
% K= #of guassians in the mixture
% T = min. portion of background
% initVariance = initial variance
% pixelThresh = threshold condition for computing adaptive process on pixel
alpha=0.05; % 0.05
K=5; % 5
global T; % T = 0.8
T=0.8;
global initVariance;
initVariance=75; % 75
pixelThresh=45; % 45
referenceDistance = 40; % 40 %shortcut to speed up processing time. Compare current pixel to pixel referenceDistance frames back and skip adaptive process if similar. Downside is doesn't collect background evidence as well.
sideWeight = (K-1)/(1-T);
global matchThres;
matchThres = sqrt(3);
global ccThreshold;
ccThreshold = 9000; % 5000
global deltaT;
deltaT = 1;
global numParticles;
numParticles = 100;
trackingOn = 0; % will superimpose tracking color marker on detected vehicles in output video. tackingOn should equal 1 or 0
prevCentSize = 0;
%structures to pass information between frames for detection purposes.
field = 'f';
filterValue = {[];[];};
prevFilter = struct(field,filterValue);
modelValue = {[];prevFilter};
prevModel = struct(field,modelValue);
%initiailze video process components
initColorBoxes();
foreFrame = zeros(height,width,3);
backFrame = zeros(height,width,3);
%map represents pixels at a given frame to perform adaptive process
pixThreshMap = ones(height,width);
%individual pixel process components
pixel = zeros(3,1);
pixMean = zeros(3,1,K);
pixVar = ones(1,K);
pixWeight = zeros(1,K);
%global pixel process components
globalWeight = (ones(height,width,K)/sideWeight);
globalWeight(:,:,1) = T;
%globalWeight = (ones(height,width,K)/K);
globalMean = zeros(height,width,3,K);
globalVar = ones(height,width,K);
%=====================================================
%Extract Foreground and Background by K-mixture model
%=====================================================
%initialize g-mixture model
globalVar = globalVar*initVariance;
for k=1:K
globalMean(:,:,1,k)=initFrame(:,:,1);
globalMean(:,:,2,k)=initFrame(:,:,2);
globalMean(:,:,3,k)=initFrame(:,:,3);
end;
distVec = zeros(numFrames,1);
%adaptive g-mixture background segmentation
for frameIndex=2:numFrames
%get current frame and the refernece frame
%tic;
frameIndex
currentFrame = double(read(v,frameIndex));
if (frameIndex<=referenceDistance)
referenceFrame= double(read(v,1));
else
referenceFrame= double(read(v,frameIndex-referenceDistance));
end;
frameDifference = abs(currentFrame - referenceFrame);
%creates map of pixel locations where we will perform adaptive process. Based
%upon threshold that detects low change regions based on previous frame in
%order to save computation.
pixThreshMap = min(sum(+(frameDifference(:,:,:)>pixelThresh),3),1);
for index=1:3
backFrame(:,:,index)=(+(pixThreshMap(:,:)==0)).*currentFrame(:,:,index);
end;
%extract the parts considered "stable background" from current frame
%reset foreground frame
foreFrame = ones(height,width,3)*255;
%gaussian mixture matching & model updating
[i,j]=find(pixThreshMap(:,:)==1);
%loop through every pixel location where adaptive process should be performed
for k = 1:size(i,1)
pixel = reshape(currentFrame(i(k),j(k),:),3,1);
pixMean = reshape(globalMean(i(k),j(k),:,:),3,1,K);
pixVar = reshape(globalVar(i(k),j(k),:,:),1,K);
pixWeight=reshape(globalWeight(i(k),j(k),:),1,K);
%update gaussian mixture according to new pix value
match=matchingCriterion(pixMean,pixVar,pixel);
matchWeight = 0;
if(match>0)
%match found so update weights/normalize
pixWeight = (1-alpha)*pixWeight;
pixWeight(match)= pixWeight(match) + alpha;
pixWeight = pixWeight/sum(pixWeight);
matchWeight = pixWeight(1,match);
%NOTE ALPHA SHOULD BE REPACED WITH SOME KIND OF RHO EVENTUALLY
%WHERE RHO IS PRODUCT OF ALPHA AND CONDITIONAL PROBABILITY MEASURE
%update variance
pixVar(:,match) = (1-alpha)*pixVar(:,match) + ...
alpha*(pixel - pixMean(:,:,match))'*(pixel-pixMean(:,:,match));
%update mean
pixMean(:,:,match) = (1-alpha)*pixMean(:,:,match) + alpha*pixel;
else
%no match currently found.
%replace one with lowest sigma value
rankVector = pixWeight./sqrt(pixVar(1,:));
[mini minIndex] = min(rankVector);
pixMean(:,:,minIndex) = pixel;
pixVar(:,minIndex) = initVariance;
end
%rerank all pixel components
rankCriterionVector = pixWeight./sqrt(pixVar(1,1,:));
[rankSort rankIndex] = sort(rankCriterionVector);
pixMean = pixMean(rankIndex);
pixVar = pixVar(rankIndex);
pixWeight = pixWeight(rankIndex);
%repopulate global structures with updated values
globalWeight(i(k),j(k),:) = pixWeight(:,1);
globalMean(i(k),j(k),:,:) = pixMean(:,1,:);
globalVar(i(k),j(k),:,:) = pixVar(:,:,:);
%now need to perform the background segmentation based upon weight
%threshold
bgIndex = segmentBackground(pixWeight);
if(ismember(matchWeight, pixWeight))
matchIndex = find(pixWeight == matchWeight,1);
else
matchIndex = 0;
end
if((matchIndex>=bgIndex) || (matchIndex == 0))
%also check against initFrame for match
%NOTE CHANGE
if(initMatch(initFrame(i(k),j(k),:),pixel) == 0)
foreFrame(i(k),j(k),:) = pixel;
end
end
end
%Now write foreground frame to foreground estimation video
contrastFrame = foreFrame/max(abs(foreFrame(:)));
%remove all connected components associated with foreground objects that are smaller than what we expect a vehicle should be.
[cleanFrame centroids]= connectedComponentCleanup(contrastFrame);
if(trackingOn == 1)
if(size(centroids,1) > prevCentSize)
prevModel = addModel(prevModel, centroids, height, width);
elseif (size(centroids,1) < prevCentSize)
prevModel = removeModel(prevModel, centroids, height, width);
end
if(size(centroids,1) > 0)
%implies there is a car in frame for tracking
[curModel orderedCentroids] = vehicleTracking(centroids, prevModel);
prevModel = curModel;
trackFrame = colorBox(cleanFrame, curModel,orderedCentroids, height, width);
else
trackFrame = cleanFrame;
end
else
trackFrame = cleanFrame;
end
writeVideo(foregroundVideo,trackFrame);
prevCentSize = size(centroids,1);
end
Thanks.
Basically this is not task for kalman filter, look at background subtraction in opencv.
Kalman filter could be used after that to track objects between frames, you could look for example here
http://studentdavestutorials.weebly.com/kalman-filter-with-matlab-code.html

face recognition using surf features and knn search tree

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)

Dimensions issus

Finding maximum values of wave heights and wave lengths
dwcL01 though dwcL10 is arrays of <3001x2 double> with output from a numerical wave model.
Part of my script:
%% Plotting results from SWASH
% Examination of phase velocity on deep water with different number of layers
% Wave height 3 meters, wave peroid 8 sec on a depth of 30 meters
clear all; close all; clc;
T=8;
L0=1.56*T^2;
%% Loading results tabels.
load dwcL01.tbl; load dwcL02.tbl; load dwcL03.tbl; load dwcL04.tbl;
load dwcL05.tbl; load dwcL06.tbl; load dwcL07.tbl; load dwcL08.tbl;
load dwcL09.tbl; load dwcL10.tbl;
M(:,:,1) = dwcL01; M(:,:,2) = dwcL02; M(:,:,3) = dwcL03; M(:,:,4) = dwcL04;
M(:,:,5) = dwcL05; M(:,:,6) = dwcL06; M(:,:,7) = dwcL07; M(:,:,8) = dwcL08;
M(:,:,9) = dwcL09; M(:,:,10) = dwcL10;
%% Finding position of wave crest using diff and sign.
for ii=1:10
Tp(:,1,ii) = diff(sign(diff([M(1,2,ii);M(:,2,ii)]))) < 0;
Wc(:,:,ii) = M(Tp,1,ii);
L(:,ii) = diff(Wc(:,1,ii))
end
The loop
for ii=1:10
Tp(:,1,ii) = diff(sign(diff([M(1,2,ii);M(:,2,ii)]))) < 0;
Wc(:,:,ii) = M(Tp,1,ii);
L(:,ii) = diff(Wc(:,1,ii))
end
Works fine for ii = 1 Getting the following error for ii = 2
Index exceeds matrix dimensions.
Error in mkPlot (line 19)
Wc(:,:,i) = M(Tp,:,i);
Don't have the same number of wave crests for the different set ups, naturally M(Tp,1,ii) will have different dimensions. How do I work around this issue? Can it be done in a for loop? please feel free to email me or other wise ask for further information.
The problem is that Tp is a three dimensional array. I need to call the Tp(:,:,ii) corresponding to the present scenario. Together with this and defining Wc as a cell I solve my issue.
for ii = 1:10
Tp(:,1,ii) = diff(sign(diff([M(1,2,ii);M(:,2,ii)]))) < 0;
Wc{:,:,ii} = M(Tp(:,:,ii),1,ii);
L{:,ii} = diff(cell2mat(Wc(ii)));
end

Rolling window for averaging using MATLAB

I have the following code, pasted below. I would like to change it to only average the 10 most recently filtered images and not the entire group of filtered images. The line I think I need to change is: Yout(k,p,q) = (Yout(k,p,q) + (y.^2))/2;, but how do I do it?
j=1;
K = 1:3600;
window = zeros(1,10);
Yout = zeros(10,column,row);
figure;
y = 0; %# Preallocate memory for output
%Load one image
for i = 1:length(K)
disp(i)
str = int2str(i);
str1 = strcat(str,'.mat');
load(str1);
D{i}(:,:) = A(:,:);
%Go through the columns and rows
for p = 1:column
for q = 1:row
if(mean2(D{i}(p,q))==0)
x = 0;
else
if(i == 1)
meanvalue = mean2(D{i}(p,q));
end
%Calculate the temporal mean value based on previous ones.
meanvalue = (meanvalue+D{i}(p,q))/2;
x = double(D{i}(p,q)/meanvalue);
end
%Filtering for 10 bands, based on the previous state
for k = 1:10
[y, ZState{k}] = filter(bCoeff{k},aCoeff{k},x,ZState{k});
Yout(k,p,q) = (Yout(k,p,q) + (y.^2))/2;
end
end
end
% for k = 2:10
% subplot(5,2,k)
% subimage(Yout(k)*5000, [0 100]);
% colormap jet
% end
% pause(0.01);
end
disp('Done Loading...')
The best way to do this (in my opinion) would be to use a circular-buffer to store your images. In a circular-, or ring-buffer, the oldest data element in the array is overwritten by the newest element pushed in to the array. The basics of making such a structure are described in the short Mathworks video Implementing a simple circular buffer.
For each iteration of you main loop that deals with a single image, just load a new image into the circular-buffer and then use MATLAB's built in mean function to take the average efficiently.
If you need to apply a window function to the data, then make a temporary copy of the frames multiplied by the window function and take the average of the copy at each iteration of the loop.
The line
Yout(k,p,q) = (Yout(k,p,q) + (y.^2))/2;
calculates a kind of Moving Average for each of the 10 bands over all your images.
This line calculates a moving average of meanvalue over your images:
meanvalue=(meanvalue+D{i}(p,q))/2;
For both you will want to add a buffer structure that keeps only the last 10 images.
To simplify it, you can also just keep all in memory. Here is an example for Yout:
Change this line: (Add one dimension)
Yout = zeros(3600,10,column,row);
And change this:
for q = 1:row
[...]
%filtering for 10 bands, based on the previous state
for k = 1:10
[y, ZState{k}] = filter(bCoeff{k},aCoeff{k},x,ZState{k});
Yout(i,k,p,q) = y.^2;
end
YoutAvg = zeros(10,column,row);
start = max(0, i-10+1);
for avgImg = start:i
YoutAvg(k,p,q) = (YoutAvg(k,p,q) + Yout(avgImg,k,p,q))/2;
end
end
Then to display use
subimage(Yout(k)*5000, [0 100]);
You would do sth. similar for meanvalue