Dear @David_Tschumperle, I want to bother you again with the “Mixer [PCA]” filter
.
In some cases it would be useful to have the option to “invert” only one or two axes of the PCA-ellipsoid.
I did a lot of experiments with the “Transfer Color [PCA]” filter. Often it gives nice results. But I noticed that this filter sometimes “inverts” an axis of the PCA-ellipsoid. Therefore I wanted to be able to invert an axis in the “Mixer [PCA]” filter. in other cases this may also be useful.
I have the following solution; invert the value(s) for “gamma”.
nI[0] = (do_gamma(nI[0],vmax0,gamma0))*-1;
This works the way I want it.
I am not a programmer. Surely there will be a much more elegant way to do this, but maybe this is helpful to others?
#@gui Mixer [PCA_invert]:fx_mix_pca_invert,fx_mix_pca_invert_preview(1)+
#@gui :Primary Factor=float(0,-1.5,1.5)
#@gui :Primary Shift=float(0,-255,255)
#@gui :Primary Twist=float(0,-180,180)
#@gui :Primary Gamma=float(0,-100,100)
#@gui :Primary Invert=int(1,-1,1)
#@gui :_=separator()
#@gui :Secondary Factor=float(0,-1.5,1.5)
#@gui :Secondary Shift=float(0,-255,255)
#@gui :Secondary Twist=float(0,-180,180)
#@gui :Secondary Gamma=float(0,-100,100)
#@gui :Secondary Invert=int(1,-1,1)
#@gui :_=separator()
#@gui :Tertiary Factor=float(0,-1.5,1.5)
#@gui :Tertiary Shift=float(0,-255,255)
#@gui :Tertiary Twist=float(0,-180,180)
#@gui :Tertiary Gamma=float(0,-100,100)
#@gui :Tertiary Invert=int(1,-1,1)
#@gui :_=separator()
#@gui :Display Color Axes=bool(1)
#@gui :_=value(-1,-1,-1,-1)
#@gui :_=value(0,0,0,0,0,0,0,0,0,0,0,0)
#@gui :_=separator()
#@gui :Preview Type=choice("Full","Forward Horizontal","Forward Vertical","Backward Horizontal","Backward Vertical","Duplicate Top","Duplicate Left","Duplicate Bottom","Duplicate Right","Duplicate Horizontal","Duplicate Vertical","Checkered","Checkered Inverse")
#@gui :Preview Split=point(50,50,0,0,200,200,200,0,10)_0
#@gui :_=separator()
#@gui :_=note("<small>Author: <i><a href="https://bit.ly/2WeKVPv">David Tschumperlé</a></i>.      Latest Update: <i>2018/07/18</i>.</small>")
fx_mix_pca_invert :
repeat $! l[$>] split_opacity l[0] to_rgb
if [${14-17}]==round(stats()[0,4],0.1) _avg=${18-20} C=${21-29} status=
else
+rr2d 256,256,0,2 C=${"covariance_colors. _avg"} rm.
__status="{$1}{$2}{$3}{$4}{$5}""{$6}{$7}{$8}{$9}{$10}""{$11}{$12}{$13}{$14}{$15}""${16}""{"{round(stats()[0,4],0.1)}"}""{"$_avg,$C"}""{$33}{${34,35}}"
fi
if "$4 || $9 || $14" +l
f "begin(avg = ["$_avg"]; eig = eig(["$C"]); Pt = eig[3,9]); Pt*(I-avg)"
s c repeat $! vmax$>={$>,1.1*max(abs(im),abs(iM))} done
rm
endl else vmax0,vmax1,vmax2=1 fi
f "begin(
do_gamma(val,vmax,gamma) = (vmax*sign(val)*(abs(val)/vmax)^gamma);
const gamma0 = 10^-($4%);
const gamma1 = 10^-($9%);
const gamma2 = 10^-($14%);
const vmax0 = "$vmax0";
const vmax1 = "$vmax1";
const vmax2 = "$vmax2";
avg = ["$_avg"];
eig = eig(["$C"]);
for (k = 3, k<12, k+=3, eig[k]<0?copy(eig[k],eig[k,3]*=-1,3));
Pt = eig[3,9];
P = transp(Pt,3);
T = mul(P,diag(10^[$1,$6,$11]),3);
R1 = rot(eig[3,3],$3);
R2 = rot(eig[6,3],$8);
R3 = rot(eig[9,3],$13);
T = mul(R1,mul(R2,mul(R3,T,3),3),3);
avg_shift = avg + $2*eig[3,3] + $7*eig[6,3] + $12*eig[9,3];
if ("0$_is_preview",
L = [ 2,5,10]*sqrt(1e-5 + eig[0,3]);
run('__cols=',vtos(round([
avg - L[0]*eig[3,3],
avg + L[0]*eig[3,3],
avg - L[1]*eig[6,3],
avg + L[1]*eig[6,3],
avg - L[2]*eig[9,3],
avg + L[2]*eig[9,3] ])));
);
);
nI = Pt*(I - avg);
nI[0] = (do_gamma(nI[0],vmax0,gamma0))*$5;
nI[1] = (do_gamma(nI[1],vmax1,gamma1))*$10;
nI[2] = (do_gamma(nI[2],vmax2,gamma2))*$15;
avg_shift + T*nI"
c 0,255
endl a c endl done u $__status
fx_mix_pca_invert_preview :
_is_preview=1
__status=
repeat $! l[$>]
gui_split_preview "fx_mix_pca_invert $*",${-3--1}
if $16
rr2d ${-gui_preview_wh},0,1
($__cols) r. 3,6,1,1,-1 permute. yzcx s. x,3
r[-3--1] {w#0/2},13,1,3,3 c[-3--1] 0,255
frame[-3--1] 1,1,0
to[0] Primary,4,2,13,1 j[0] ...,64,4
to[0] Secondary,4,17,13,1 j[0] ..,64,19
to[0] Tertiary,4,32,13,1 j[0] .,64,34
k[0]
fi
endl done
u $__status