Vectorization of bitmaps based on the LSQ method

Vectorization of bitmaps
based on the LSQ method
Doc. RNDr. Stanislav Bartoň, CSc.
[email protected]
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Digital photo, main parameters
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Mathematical background
SoS 2 cos(  ) sin (  ) ( Qy Qx ( N2N11 )2Qy 3Qx 4 )
( ( N2N11 ) Qx 22 Qx 31 ) sin (  ) 2
( ( N2N11 ) Qy 22 Qy 45 ) cos(  ) 2
1

SoS 0
Qx
Qx 

SoS 0
Qy
3
N2N11
, Qy 
N2

i  N1
2
Xi , 2
N2

i  N1
Yi Xi , 3
N2

i  N1
Xi , 4
N2

i  N1
Yi , 5
N2

i  N1

SoS 0

4
N2N11
S2 sin (  )2S1 cos(  ) sin (  )S3 cos(  )20
 S

1
1arctan   
 2

2
2
S12 4 2 1 N12 12 52 5 N22 5 N12 3 2 1 N2,
S22 4 32 2 N22 2 N12 2,
S32 2 N12 22 2 N22 4 3
2
S1 4 S2 S3 


2 S2

S
 1
2arctan  
 2

2
S1 4 S2 S3 


2 S2

Yi
2
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
The best lines and construction of the polygon
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Perimeter’s point extraction
>
>
>
>
>
>
>
>
>
>
FN := "Carot2.jpg"; W1 := ImageTools[Read](FN):
Rd := ImageTools[Width](W1); Cd := ImageTools[Height](W1);
o:=5; A3:=1/o^2*Matrix(o,o,1);
W2:=ToGrayscale(W1):
Laplace:=Matrix([[1,4,1],[4,-20,4],[1,4,1]]):
W1:=Array(map(u->`if`(u>1./o^2,1.0,0.0),Convolution(W2,A3)),datatype=float[8]):
W2:=Array(map(u->`if`(u>(1.-1./o^2),1.0,0.0),Convolution(W1,A3)),datatype=float[8]):
W1:=Clip(Convolution(W2,Laplace)):
ps:=map(u->[lhs(u)],[op(3,W1)[]]): ps:=map(u->[u[2],Cd+1-u[1]],ps):
plot(ps, scaling=constrained);
Vectorization of bitmaps based on the LSQ method
PANM165 Horní Maxov, 7.6.2010
Perimeter’s point ordering
> Ym:=min(sort(map(u->u[2],ps))[]); Xm:=sort(map(u->`if`(u[2]=Ym,u[1],NULL),ps));
> PS:=[[Xm[2],Ym]];
> Dir:=[[1,0],[0,1],[-1,0],[0,-1]];
> ps:=subs(PS[1]=NULL,PS[-1]=NULL,ps):
> lr:=map(u->select(has,ps,[PS[1]+u])[],Dir)[]; l:=lr[1]; r:=lr[2]; PS:=[l,PS[],r];
> ps:=subs(PS[1]=NULL,PS[-1]=NULL,ps):
> while (l<>NULL and r<>NULL) do;
l:=map(u->select(has,ps,[PS[1]+u])[],Dir)[];
r:=map(u->select(has,ps,[PS[-1]+u])[],Dir)[];
PS:=[l,PS[],r]; ps:=subs(PS[1]=NULL,PS[-1]=NULL,ps):
> end do:
> Nu:=nops(PS)-1;  := 1848
> {seq(D2(PS[i],PS[i+1]),i=1..Nu)}; { 1 }
> plot(PS,scaling=constrained);
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
The best line segments estimation
> i:='i': d:=1.; Dist:=0; LPT1:=[]: LPT2:=[]:Lambda:=[]; GO:=true; N1:=1; s:=0;
> while GO do:
N2:=N1+1; Dist:=0; s:=s+1: l:=[]:
while Dist<d and GO do;
Cf0:=Cf: Sf0:=Sf; Qx:=-S4/(-N2+N1-1.); Qy:=-1/(-N2+N1-1.)*S1;
S6:=-2*S1*S4-2*S3*N1+2*S3+2*S3*N2; S8:=2*S3*N1-2*S3+2*S1*S4-2*S3*N2;
S7:=2*S2*N2-2*S1^2+2*S2+2*S5*N1-2*S5+2*S4^2-2*S5*N2-2*S2*N1;
if S8<>0 then
Cf:=2.^(1/2)*S8/(2.*S8^2+S7^2+S7*(S7^2-4.*S8*S6)^(1/2)-2.*S8*S6)^(1/2);
Sf:=-1/2*(S7+(S7^2-4.*S8*S6)^(1/2))*2.^(1/2)/(2.*S8^2+S7^2+S7*(S7^2-4.*S8*S6)^(1/2)
-2.*S8*S6)^(1/2);
df:=map(u->d0(u),PS[N1..N2]); Dist:=max(df[]);
else
Cf:=1; Sf:=0; df1:=map(u->d0(u),PS[N1..N2]); Cf:=0; Sf:=1; df2:=map(u->d0(u),PS[N1..N2]);
Dist1:=max(df1[]); Dist2:=max(df2[]);
if Dist1<Dist2 then Dist:=Dist1; Cf:=1: Sf:=0; else Dist:=Dist2: Cf:=0: Sf:=1: end if:
end if;
N2:=N2+1;
if N2>Nu then GO:=false; end if;
end do:
Sf:=Sf0; Cf:=Cf0;
if GO then N2:=N2-2; print(step=s,'N1'=N1,'N2'=N2,Delta=N2-N1); end if:
LPT1:=[LPT1[],PL(PS[N1])]; LPT2:=[LPT2[],PL(PS[N2])];
Lambda:=[Lambda[],[seq(PS[u],u=N1..N2-1)]]; N1:=N2;
> end do:
step1, N11, N239, 38
step60, N11796, N21819, 23
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Generation of the polygon and visualization
> SP:=[0.5*(LPT1[1]+LPT2[-1]),seq(0.5*(LPT1[i+1]+LPT2[i]),i=1..n-1),0.5*(LPT1[1]+LPT2[n])]:
> for i from 1 to n do: L[i]:=Lambda[i]: p[i]:=SP[i]: end do: L[n+1]:=Lambda[1]: L[0]:=Lambda[-1]:
> p[n+1]:=SP[-1]: p[n+2]:=SP[2]: p[0]:=p[n]:
> symb_opt:=symbol=box,symbolsize=15,thickness=1;
> nu:=35:
> G1:=plot([[LPT1[nu-1],LPT2[nu-1]],L[nu-1]],style=[line,point],symb_opt,color=blue):
G2:=plot([[LPT1[nu],LPT2[nu]],L[nu]],style=[line,point],symb_opt,color=red):
G3:=plot([[LPT1[nu+1],LPT2[nu+1]],L[nu+1]],style=[line,point],symb_opt,color=blue):
G4:=plot([L[nu-1][],L[nu][],L[nu+1][]],color=black):
G5:=plot([p[nu-1],p[nu],p[nu+1],p[nu+2]],color=black,thickness=2):
> display({G1,G2,G3,G4,G5});
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Unification of the parallel line segments
> Colin:=[seq(`if`(Colin[i]<0.5,i,NULL),i=1..n)]:
> while Colin<>[] do;
k:=Colin[-1]: Colin:=subs(k=NULL,Colin);
if k<>1 then
L[k-1]:=[L[k-1][],L[k][]];
for j from k to n do: L[j]:=L[j+1]; p[j]:=p[j+1]: end do: p[n+1]:=p[n+2]:
else
L[0]:=[L[n][],L[1][]];
for j from 1 to n-2 do: L[j]:=L[j+1]: p[j]:=p[j+1]: end do: p[n]:=p[1]:
p[n+1]:=p[2]: p[0]:=p[n-1]: L[n-1]:=L[0]:
end if:
n:=n-1;
end do:
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Visualization of the quality of the vectorization
> D_All:=[seq(map(u->sqrt(S(u,p[i],p[i+1])),L[i]),i=1..n)]:
> L_All:=map(u->u[],D_All):
d := 0.4684686518
> d:=sum(L_All['i'],'i'=1..Nu-1)/(Nu-1);
> sd:=sqrt(sum((L_All['i']-d)^2,'i'=1..Nu-1)/(Nu-1));
sd := 0.3390630388
> Max:=max(L_All[]);
Max := 1.731906050
> plot([seq([i,L_All[i]],i=1..Nu-1)],numpoints=2000);
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Data saving and visualization of the result
> plot([seq([p[i],p[i+1]],i=1..n)],scaling=constrained);
> Lambda:=[seq(L[i],i=1..n)]:
> SP:=[seq(p[i],i=1..n+1)]:
> save PS, SP, Lambda, “Carot_LPS.sav";
Linear_Correlation0.9999918227
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
“Data shaking” using Gauss-Newton method.
Preparation of the Jacobi matrix
S := ( O, P1, P2 )
( P21 P12P21 O2P22 P11P12 O1P11 O2P22 O1 ) 2
( P22P12 ) 2( P21P11 ) 2
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Example of the Jacobi matrix for the “Global shaking”
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
“Local shaking” – Example of the Jacobi matrix
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
“Local shaking” – Visualization
N4, TEST1, krok 25,  1, Perp[ 5.027307431, 1.485579347 ]
Iteration_step:=proc()
local JM, rest, H, eps, LM, h;
global p;
JM:=Matrix([map(u->ColL(u,p[N-1],p[N]),L[N-1])[],
map(u->ColN(u,p[N],p[N+1]),L[N])[],
map(u->ColR(u,p[N+1],p[N+2]),L[N+1])[]]):
rest:=Vector([map(u->rf(u,p[N-1],p[N]),L[N-1])[],
map(u->rf(u,p[N],p[N+1]),L[N])[],
map(u->rf(u,p[N+1],p[N+2]),L[N+1])[]]):
H:=LeastSquares(JM,rest):
eps:=Norm(H,2); LM:=sqrt(4+eps^2);
h:=1/LM*convert(H,list);
p[N]:=p[N]-h[1..2]; p[N+1]:=p[N+1]-h[3..4];
end proc;
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Visualization of the final result
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Visualization of the quality of the vectorization
0.4208302475, 0.3054510866, 1.385200645
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Visualization of the quality of the vectorization
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Visualization of the quality of the vectorization
Displacement 20× enlarged
1-0.9999918227
1-.9999933135
1.222956704
Linear_Correlation := 0.9999933135
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Visualization of the quality of the vectorization
Displacement 20× enlarged
Vectorization of bitmaps based on the LSQ method
PANM15, Horní Maxov, 7.6.2010
Conclusions:
1. Data reduction:
53
0.02867965368
1848
2. Accuracy:
1. Quadratic displacement
0.4208302475
2. Max. displacement
1.385200645
3. Sharpness of the original digital photo = ±1 pixel
Result: Usefull tool
Thank you for your patience!