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 ( N2N11 )2Qy 3Qx 4 ) ( ( N2N11 ) Qx 22 Qx 31 ) sin ( ) 2 ( ( N2N11 ) Qy 22 Qy 45 ) cos( ) 2 1 SoS 0 Qx Qx SoS 0 Qy 3 N2N11 , 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 N2N11 S2 sin ( )2S1 cos( ) sin ( )S3 cos( )20 S 1 1arctan 2 2 2 S12 4 2 1 N12 12 52 5 N22 5 N12 3 2 1 N2, S22 4 32 2 N22 2 N12 2, S32 2 N12 22 2 N22 4 3 2 S1 4 S2 S3 2 S2 S 1 2arctan 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: step1, N11, N239, 38 step60, N11796, N21819, 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_Correlation0.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 P12P21 O2P22 P11P12 O1P11 O2P22 O1 ) 2 ( P22P12 ) 2( P21P11 ) 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 N4, TEST1, 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!
© Copyright 2026 Paperzz