Optical Mark Recognition using MATLAB

Optical Marking Recognition (OMR)

Optical Marking Recognition using MATLAB Software is for marking tests or extract data from documents such as survey. This software obtained marked data from specific sheet designed for this, called as OMR sheet.

 

Basically, this recognition software falls in category of image processing.  We are going to write our own code to mark a sheet with multiple choice questions.  (A very simple one just to give head start). MATLAB tool for image processing will be used.

A Sample Sheet used here to explain main approach to pin point the attempted option out of available options.

Optical Mark Recognition Sheet. (Optical Mark recognition using MATLAB)
A Sample Sheet

First of all somethings to remember before start.

  • Scanned Sheet Must be Straight
  • No Cross over checking Part
  • Circle must be filled completely.

Basic Concept:

Basic concept of obtaining marked circle out of others is the finding the 'co-ordinates' (pixel locations) in the scanned photo. We will use simplest approach just for understanding. Here is a quick review of algorithm:

  1. First step is importing the saved photo from computer into MATLAB. (imread command is used for this).
  2. Mostly for sake of convenience, image is converted into gray scale from colored. This give edge in sense that blackest pixel have 255 value and of white is 0. (rgb2gray command is used)
  3. Values of each pixel along with locations are stored into a matrix. This matrix is key to the program of OMR.
  4. Pixels at specific locations are checked. if they have value below a certain value, mark it 1, otherwise zero. (using imshow command we can find pixels of specific location)
  5. Location of each question is stored in an array and compared accordingly.

 

For basic program the actual answers are stored into the program but for more advance programs this comes from database connected with MATLAB.

 

Coding:

clear all % clearing all variables in workspace of MATLAB
clc       % clearing command window
%%
%% ---------Initialization -----------------%%

pixel_2=[];  P=[]; y=[];  x=[];
out=[]; out1=[];
 Y_1=[]; y_1=[]; x_1=[];
K_1=[]; Q=[];
Paper_2=[];
x_p=[]; y_p=[]; pixel_p=[];
out11=['1000';'0100';'0010';'0001'];
pixel_1=[];
 S='ABCD';  % String for choices (A,B, C,D)
Paper=[0 1 2 3 4 5 6 7 8 9];
%% ----- X-axis pixels location of each answer of question------------%%
xx=[645:650,730:735,815:820,900:905,985:990,1070:1075,1155:1160,1240:1245,1325:1330,1410:1415,1495:1500,1580:1585];
%% ------ y-axis location of each---------- %
yy=[225:230;275:280;325:330;375:380]; 
yy_1=[820:825;870:875;920:925;970:975];
 %%
 
 %% ----------Getting image from folder-------%%
d='C:\Users\Asad_Ullah\Desktop\OMR\OMR_Images\new.jpg';
 %%
 
 %% ----- reading image (fox pixels) -------- %%

I=rgb2gray(imread(d));
imtool(I) 
%P=imshow(I)
% correct answers of each question (in future extension this can come from data base)
Actual=['A'; 'A' ;'D'; 'B'; 'C' ;
 'B' ;'C' ;'B' ;'B'; 'B' ;
 'D' ;'D'; 'C';'D';'D';'C';'B']; 

%% ---------------- For 1st Column of Questions----------%%
for question=1:12 
 X=648+(85*(question-1));
 for option=1:4
 Y=228+(50*(option-1)); 
 y=[y,Y];
 end
 x=[x,X];
end
y; x;
n1=size(x); n2=size(y);
for n3=1:n1(1,2)
 x_value=x(n3);
 for n4=(((n3-1)*4)+1):(((n3-1)*4)+4)
 y_value=y(n4);
 P=[P;[x_value,y_value]];
 K=I(x_value,y_value);
 if K<100
 pixel_2=[pixel_2;K];
 if(ismember(x_value,xx)&& (ismember(y_value,yy(1,:))))
 
 out= S(1);
 out111= out11(1,:);
 elseif (ismember(x_value,xx)&& (ismember(y_value,yy(2,:))))
 out= S(2);
 out111=out11(2,:);
 elseif (ismember(x_value,xx)&& (ismember(y_value,yy(3,:))))
 out= S(3);
 out111=out11(3,:);
 elseif (ismember(x_value,xx)&& (ismember(y_value,yy(4,:))))
 out= S(4);
 out111=out11(4,:);
 end
 out1=[out1;out];
 out11=[out11;out111];
 end
 

 pixel_1=[pixel_1;I(x_value,y_value)];
 end
 
end
%%
%% ----------For 2nd Column of Questions--------------%
for question_1=1:12 
 X_1=648+(85*(question_1-1));
 for option_1=1:4
 Y_1=822+(50*(option_1-1)); 
 y_1=[y_1,Y_1];
 end
 x_1=[x_1,X_1];
end
y_1; x_1;
n1_1=size(x_1); n2_1=size(y_1);
for n3_1=1:n1_1(1,2)
 x_value_1=x_1(n3_1);
 for n4_1=(((n3_1-1)*4)+1):(((n3_1-1)*4)+4)
 y_value_1=y_1(n4_1);
 P=[P;[x_value_1,y_value_1]];
 K_1=I(x_value_1,y_value_1);
 if K_1<100
 pixel_2=[pixel_2;K_1];
 if (ismember(x_value_1,xx)&& (ismember(y_value_1,yy_1(1,:))))
 out= S(1);
 out111=out11(1,:);
 elseif (ismember(x_value_1,xx)&& (ismember(y_value_1,yy_1(2,:))))
 out= S(2);
 out111=out11(2,:);
 elseif (ismember(x_value_1,xx)&& (ismember(y_value_1,yy_1(3,:))))
 out= S(3);
 out111=out11(3,:);
 elseif (ismember(x_value_1,xx)&& (ismember(y_value_1,yy_1(4,:))))
 out= S(4);
 out111=out11(4,:);
 end
 out1=[out1;out];
 out11=[out11;out111];
 end
 

 pixel_1=[pixel_1;I(x_value,y_value)];
 end
 
end

 P;
% pixel_1
 pixel_2 ; 
Given_Answer=(out1);
t=size(pixel_2);
total_attempted_answers=t(1,1);
s=size(Given_Answer);
%% ----- End of Question Portion------------%%
%%
for u=1:size(Actual)
 Q=[Q;u];
end
Marks= Actual==Given_Answer;
table(Q,Given_Answer,Actual,Marks)
total_attempted_answers

Marks_Obtained=sum(Marks)

%% -----------------PAPER CODE------------%
for rows_p=1:10
 X_p=(700+(50*(rows_p-1)):705+(50*(rows_p-1)));
 x_p=[x_p;X_p];
end
 for column_p=1:4
 Y_p=(1440+(50*(column_p-1)):1445+(50*(column_p-1))); 
 y_p=[y_p;Y_p];
 end
 y_p;x_p;pixel_p_1=[];out_p_1=[];
 for uu=1:4
 y_value_p=y_p(uu);
 for vv=1:10
 x_value_p=x_p(vv);
 K_P=I(x_value_p,y_value_p);
 if K_P<100
 pixel_p=[pixel_p;K_P];
 if (ismember(x_value_p,x_p(1,:))&& (ismember(y_value_p,y_p)))
 out_p=Paper(1,1);
 elseif (ismember(x_value_p,x_p(2,:))&& (ismember(y_value_p,y_p)))
 out_p=Paper(1,2);
 elseif (ismember(x_value_p,x_p(3,:))&& (ismember(y_value_p,y_p)))
 out_p=Paper(1,3);
 elseif (ismember(x_value_p,x_p(4,:))&& (ismember(y_value_p,y_p)))
 out_p=Paper(1,4);
 elseif (ismember(x_value_p,x_p(5,:))&& (ismember(y_value_p,y_p)))
 out_p=Paper(1,5);
 elseif (ismember(x_value_p,x_p(6,:))&& (ismember(y_value_p,y_p)))
 out_p=Paper(1,6);
 elseif (ismember(x_value_p,x_p(7,:))&& (ismember(y_value_p,y_p)))
 out_p=Paper(1,7);
 elseif (ismember(x_value_p,x_p(8,:))&& (ismember(y_value_p,y_p)))
 out_p=Paper(1,8);
 elseif (ismember(x_value_p,x_p(9,:))&& (ismember(y_value_p,y_p)))
 out_p=Paper(1,9);
 elseif (ismember(x_value_p,x_p(10,:))&& (ismember(y_value_p,y_p)))
 out_p=Paper(1,10);
 end
 out_p_1=[out_p_1,out_p];
 end
 end
 end
 Paper_code=out_p_1
 %% ---------end Paper code-------------------%

MATLAB Output:

OMR using MATLAB output.
MATLAB Output

 

Feel Free to contact regarding this code and OMR using MATLAB. 🙂 like our facebook page for more and for contact us 

Asad Ullah

I am MSc Electrical Scholar under a fellowship program. Working with Modeling and Simulation software related to my field are my activities in leisure.

What do you think?