Yesterday, I did a little experiment with spline tracing, and I came up with an algorithm that I quite like, which transforms an image into a felt-tip pen drawing, but it’s still a bit messy to make it into a usable filter for G’MIC-Qt.
I’m copying and pasting the code here, along with some of the results I got. I’m not sure I’ll have time to do anything with it in the next few days.
Code:
marker :
sp colorful,1024 => img
+diffusiontensors 0,0.85,0,1,0 channels. 0,3 f. "[ i0,i1,i1,i2 ]" => tensors
+b[img] 1 gradient_norm. n. 0,1 => gnorm
{img,[w,h,1,1]} => shape
+f[img] 255 => canvas
w[canvas]
do {
170,1,1,1,":
spline(_X0,_U0,_X1,_U1) = (
ref(_X0,spline_X0); ref(_U0,spline_U0); ref(_X1,spline_X1); ref(_U1,spline_U1);
spline_C = transpose(solve([ 0,0,0,1,1,1,1,1,0,0,1,0,3,2,1,0 ],[ spline_X0,spline_X1,spline_U0,spline_U1 ],2),2);
spline_N = ceil(norm(spline_X1 - spline_X0) + 0.5*(norm(spline_U0) + norm(spline_U1)))/5;
repeat (spline_N,spline_n,
spline_t = lerp(0,1,spline_n/(spline_N - 1));
spline_X = mul(spline_C,[ spline_t^3, spline_t^2, spline_t, 1 ],1);
spline_U = mul(spline_C,[ 3*spline_t^2, 2*spline_t, 1, 0 ],1);
spline_ang = atan2(spline_U[1],spline_U[0]);
ellipse(#$canvas,round(spline_X),7,4,spline_ang,opac,RGB);
i(#$shape,round(spline_X)) = 1;
);
);
const N = 100;
const opac = max(0.005,0.075*1.001^-$>);
Xs = vector(#2*N,-1);
Us = vector(#2*N,-1);
# Randomly pick a starting location and a starting orientation.
do (
X = X0 = v([w#$img,h#$img] - 1),
i(#$shape,X); # || i(#$gnorm,X)<1.1^-$>;
);
U = U0 = cexp([0,u(360°)]);
RGB = I(#$img,X);
copy(Xs[0],X0);
copy(Us[0],U0);
# Draw streamline.
ind = 1;
nb_cross = 0;
repeat (512,
T = I(#$tensors,X,1,1);
U = T*U;
U/=max(1e-8,abs(U));
nX = X + U;
i(#$shape,nX,1)?++nb_cross;
nb_cross>40?break();
X = nX;
copy(Xs[2*ind],X);
copy(Us[2*ind],U);
ind = (ind + 1)%N;
);
pind = (ind + 1)%N;
Xp = Xs[2*pind,2];
Up = Us[2*pind,2];
Xp[0]>=0?(
spline(Xp,100*unitnorm(Up),X,100*unitnorm(U));
);
" rm.
w[canvas]
# +rs[canvas] 50% on. frame.jpg,$> rm.
} while {*}








