Recovery of Drawing Order of Handwritten Image
The following code gives an overview (Ask for full source code of application) to compute static and dynamic features of scanned handwritten image. The dynamic features compute drawing order of a handwritten image as shown in following figure. The code is written in Matlab.
The following function feature_extraction calls static and dynamic features and perform necessary preprocessing.
function v = feature_extraction(im)
v=[];
im=imresize(im,[100 100]); im=im2bw(im);
v=[v more_features(im)];
%%% static features computation
, function written below
im2=im;
%%%% for thin image
fix_no=63; cch_length=12; path=[]; list=[];
im=bwmorph(im,'thin',Inf); im=bwmorph(im,'spur',3);
im1=regionprops(im,'PixelList','Extrema','Area');
for i=1:length(im1)
list1=im1(i).PixelList;
P1=ceil(im1(i).Extrema(1,:)); %P=P1;
P=one_ngh(list1,P1); %find one-ngh point close to (0,0)
x=P(1,1); y=P(1,2); path=[x y];
path=tr_list(list1,x,y,path);
%traverse list as recover drawing order of skeleton image
, function given below
list=[list; path];
end
[m n]=size(list);list=resample(list,fix_no,m); %to resample points
list=list(3:end,:);
ccpath=list_path(list,cch_length); v=[v ccpath];
%%%%%canny chain code
im=im2; fix_no=133; cch_length=12; path=[]; list=[];
im=edge(im,'canny');
im1=regionprops(im,'PixelList','Extrema','Area');
for i=1:length(im1)
list1=im1(i).PixelList;
P1=ceil(im1(i).Extrema(1,:)); %P=P1;
P=one_ngh(list1,P1); %find one-ngh point close to (0,0)
x=P(1,1); y=P(1,2); path=[x y];
path=tr_list(list1,x,y,path); %traverse list as recover drawing order of boundary pixels image, function given below
list=[list; path];
end
[m n]=size(list); list=resample(list,fix_no,m); %to resample points
list=list(3:end,:); list=[list;list(1,:)];
ccpath=list_path(list,cch_length); v=[v ccpath];
end
Static Features (compute pixels density in squares, horizontal, vertical and diagonal styles)
function v = more_features(im)
im=im_crop(im);
im=imresize(im,[100 100]);
[m n]=size(im);
t=10;
k=m/t; part=m/k; im2=[]; v=[]; r=1; c=1;
for i=1:part
for j=1:part
im2=im(r:(r+k-1),c:(c+k-1));
v=[v nnz(im2)];
c=c+k;
end
r=r+k; c=1;
end
ub=100; f=9;
for i=1:10:ub
v=[v nnz(im(i:i+9,:))];
v=[v nnz(im(:,i:i+9))];
end
%}
ub=100; f=9; v=[];
for i=1:10:ub
s=0; m=[];
for j=i:1:i+f
s=s+nnz(diag(im,j));
end
v=[v s];
end
for i=-1:-10:-ub
s=0; m=[];
for j=-i:-1:-(i+f)
s=s+nnz(diag(im,j));
end
v=[v s];
end
im=fliplr(im); [m n]=size(im);
for i=1:10:ub
s=0; m=[];
for j=i:1:i+f
s=s+nnz(diag(im,j));
end
v=[v s];
end
for i=-1:-10:-ub
s=0; m=[];
for j=-i:-1:-(i+f)
s=s+nnz(diag(im,j));
end
v=[v s];
end
end
Dynamic Features (Recover drawing order through skeleton and boundary pixels of image, its a recursive program)
function path=tr_list(list,x,y,path)
[m n]=size(path); [m1 n1]=size(list);
if m>=m1
return;
end
ngh=tr_ngh(x,y,path,list); [m1 n1]=size(path); [m2 n2]=size(ngh);
%
if m1>1 && m2>1
pp2(1,1)=x; pp2(1,2)=y; pp1(1,1)=path(end-1,1); pp1(1,2)=path(end-1,2);
ngh=tr_prev_list(ngh,pp1,pp2);
end
%
[m n]=size(ngh);
for i=1:m
P2=ngh(i,:);
checkp=is_member(P2,path);
if checkp==0
path=[path;P2];
end
x=P2(1,1); y=P2(1,2);
path=tr_list(list,x,y,path);
end
end