Azzera filtri
Azzera filtri

How to do Image Segmentation on multiple digit?

2 visualizzazioni (ultimi 30 giorni)
I want segment all the image into individual character and i manage to do so but the problem is with number 1 the final product is not what i want. Below is the image that i want to segment it and with the result:
This is the imagae after segmented witch is in the size of 28 by 28
As you can see digit 1 does not process correctly as this will affect CNN to recognize it.
So can anyone tell me how to solve this problem?
Below is the code:
%% Input Image
% Here input image which is a RGB image is preprocessed, converted to
% Binary Image, followed by noise removal
[filename,filepath]=uigetfile({'*.jpg'},'Select and image');
originalImage = imread(strcat(filepath, filename));
% Showing Original image
% figure(1);
imshow(originalImage);
title('Original Image');
% Conversion to grayScale image
grayImage = rgb2gray(originalImage);
% Conversion to binary image
threshold = graythresh(grayImage);
binaryImage = ~im2bw(grayImage,threshold);
% Removes all object containing fewer than 30 pixels
moddedImage = bwareaopen(binaryImage,30);
pause(1)
% Showing binary image
figure(2);
imshow(moddedImage);
title('Modified Image');
% Labelling connected components
[L,Ne] = bwlabel(moddedImage);
% Measuring properties of image regions
propied = regionprops(L,'BoundingBox');
hold on
% Plot Bounding Box
for n=1:size(propied,1)
rectangle('Position',propied(n).BoundingBox,'EdgeColor','g','LineWidth',2)
end
hold off
pause (1)
%% Image Segmentation
%figure; % Create a new figure window.
% Maximize the figure window.
%set(gcf, 'Units','Normalized','OuterPosition',[0 0 1 1]);
for n=1:Ne
[r,c] = find(L==n);
n1 = moddedImage(min(r):max(r),min(c):max(c));
n1 = imresize(n1,[128 128]);
n1 = imgaussfilt(double(n1),1);
n1 = padarray(imresize(n1,[20 20],'bicubic'),[4 4],0,'both');
subplot(3, 4, n);
imshow(n1);
segmentedImages1 = fullfile('segmentedImages1', sprintf('image%d.png', n));
imwrite(n1, segmentedImages1);
pause(1)
end
%% feed image
myFolder = 'D:\CNN test\segmentedImages1';
% Get a list of all files in the folder with the desired file name pattern.
filePattern = fullfile(myFolder, '*.jpg');
theFiles = dir(filePattern);
storedStructure = load('test2.mat');
net = storedStructure.net;
%i = 0;
%outcome = zeros(1,1);
%outcome = [];
for k = 2 : length(theFiles)
baseFileName = theFiles(k).name;
fullFileName = fullfile(theFiles(k).folder, baseFileName);
fprintf(1, 'Now reading %s\n', fullFileName);
I = imread(fullFileName);
subplot(3, 4, k);
imshow(I); % Display image.
drawnow; % Force display to update immediately.
label=(classify(net,I));
title([' Recognized Digit is ' char(label)])
fprintf( 'student id: %s\n',label)
end
%% Displaying Detected Text
fprintf( 'student id: %s\n',label)
  3 Commenti
Muhamad Luqman Mohd Nasir
@Image Analyst Hi Sir its seems that the file is to large to be attach to the comment even after i zip the file. But here is the script of the file. It is bassically a script to train CNN
%CNN program
digitDatasetPath='D:\CNN test\mnisdigitdataset';
digitimages=imageDatastore(digitDatasetPath,'IncludeSubfolders',true,'LabelSource','foldernames');
numTrainFiles=750; %numTrainFiles=0.75 (75%)
[TrainImages,TestImages]=splitEachLabel(digitimages,numTrainFiles,'randomize');
%Building CNN
layers=[
imageInputLayer([28 28 1],'Name','Input')
convolution2dLayer(3,8,'Padding','same','Name','Conv_1')
batchNormalizationLayer('Name','BN_1')
reluLayer('Name','Relu_1')
maxPooling2dLayer(2,'Stride',2,'Name','MaxPool_1')
convolution2dLayer(3,16,'Padding','same','Name','Conv_2')
batchNormalizationLayer('Name','BN_2')
reluLayer('Name','Relu_2')
maxPooling2dLayer(2,'Stride',2,'Name','MaxPool_2')
convolution2dLayer(3,32,'Padding','same','Name','Conv_3')
batchNormalizationLayer('Name','BN_3')
reluLayer('Name','Relu_3')
maxPooling2dLayer(2,'Stride',2,'Name','Maxpool_3')
convolution2dLayer(3,64,'Padding','same','Name','Conv_4')
batchNormalizationLayer('Name','BN_4')
reluLayer('Name','Relu_4')
fullyConnectedLayer(10,'Name','FC')
softmaxLayer('Name','Softmax');
classificationLayer('Name','Output Classification');
];
%Igraph = layerGraph(layers);
%plot(Igraph); %Plotting Network Structure
%-----------------------------------Training Options-----------------
options = trainingOptions('sgdm','InitialLearnRate',0.01,'MaxEpochs',4,'Shuffle','every-epoch','ValidationData',TestImages,'ValidationFrequency',30,'Verbose',false,'Plots','training-progress');
net = trainNetwork(TrainImages,layers,options); %Network Training
Ypred = classify(net,TestImages); %Recognizing Digits
YValidation = TestImages.Labels; %Getting Labels
accuracy = sum(Ypred == YValidation)/numel(YValidation); %Finding %age accuracy
Muhamad Luqman Mohd Nasir
@Image Analyst Hello Sir do you any other suggestion that i can do to solve this problem? Sorry if i have taken your time with my problems.

Accedi per commentare.

Risposta accettata

DGM
DGM il 4 Lug 2021
Don't rescale the characters in a way that changes their aspect ratio. Resize based only on one dimension, then make up for it when you pad.
minpadsize = 4;
outsize = [28 28];
nr = imresize(n1,[outsize(1)-2*minpadsize NaN],'bicubic');
hpad = (outsize(2)-size(nr,2))/2;
np = padarray(nr,[minpadsize floor(hpad)],0,'pre');
np = padarray(np,[minpadsize ceil(hpad)],0,'post');
  4 Commenti
Muhamad Luqman Mohd Nasir
Well i gues you are right, the script you gave solve the problem and work wonders, maybe i should post another question regarding the CNN.Thank You Sir @DGM
DGM
DGM il 5 Lug 2021
What I meant is to isolate the code doing the image transformation and make sure it works by itself.

Accedi per commentare.

Più risposte (0)

Prodotti


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by