From e92303705387a0bc8728236cba3ed27ea8105ff3 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Wed, 16 Nov 2016 09:31:35 +0100 Subject: [PATCH] Commited current state to allow tests. Expect colour casts when changin demosaic method or pixelshift frame. In this case, just reload the image --- rtdata/languages/default | 5 + rtdata/rt_splash_5.png | Bin 0 -> 78671 bytes rtdata/rt_splash_5.svg | 1772 ++++++++++++++++++++++++++++++++++++ rtengine/pixelshift.cc | 199 +++- rtengine/procevents.h | 1 + rtengine/procparams.cc | 39 + rtengine/procparams.h | 3 + rtengine/rawimagesource.cc | 38 +- rtengine/rawimagesource.h | 8 +- rtengine/refreshmap.cc | 3 +- rtengine/rt_math.h | 7 + rtgui/bayerprocess.cc | 86 ++ rtgui/bayerprocess.h | 8 +- rtgui/paramsedited.cc | 18 + rtgui/paramsedited.h | 3 + 15 files changed, 2132 insertions(+), 58 deletions(-) create mode 100644 rtdata/rt_splash_5.png create mode 100644 rtdata/rt_splash_5.svg diff --git a/rtdata/languages/default b/rtdata/languages/default index c66c3a64d..9399982d8 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1654,6 +1654,11 @@ TP_RAW_IMAGENUM;Some raw files might embed several sub-images (HDR, Pixel-Shift, TP_RAW_LABEL;Demosaicing TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +TP_RAW_PIXELSHIFTMOTION;Pixelshift motion detection +TP_RAW_PIXELSHIFTMOTION_TOOLTIP;No tooltip available atm +TP_RAW_PIXELSHIFTMOTIONCORRECTION;Pixelshift motion correction +TP_RAW_PIXELSHIFTMOTIONCORRECTION_TOOLTIP;1 = 2 pixels\n3 = 3x3 grid\n5 = 5x5 grid +TP_RAW_PIXELSHIFTSHOWMOTION;Show motion TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix diff --git a/rtdata/rt_splash_5.png b/rtdata/rt_splash_5.png new file mode 100644 index 0000000000000000000000000000000000000000..be996e1197805b83afb2b264a826671de829a341 GIT binary patch literal 78671 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 z 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

k?dC+o zMe&GJ@ptn9A4VS5R^XuMOo*vtrKfTSZhHqLo(jA|o89eqyjKvzuw2 z1Uk6{dSJPHCrSB(D0VxgDmHrpom7RpNQUEMmaCvQIF&;4C++Y|gOA|Ah6Pdg`>MjZ zZ`gWqg62ALW9M;$96nU$Qi3J^{wufrf%)Sgz3!83`Y&UFNoQS?m9^l}yOHMtt=-y+ zkVxFxxRelYu1Nz!aF%^h>u>pY{dSv?UE8?fL<09VBfE2EDR1`&7U*|%7cPw5?^emcoz7jL0Ew3j5a&zb&z9bI)?lU*B@l14hD$6y2LPN@N- z8>EpG5Tv_%fOJa3=x#wWdEn-*YFO3_m$K_TYEW8t%cFWE2>jG7F)HG5m>U>P0 zR+rTQqfLnqyp4AJ538{{O@&sLxY05mZNR)iU;(4COsDbig0fzdg=!TQulORB`D|~L z0!T^x_Kq?BM110_5i`eMc|o&fSxyRY8#a-6=kl1YrBXO(vFkXs%xE>+{dHvi+CRx|{uvB+9T-MB~_;CfEvluLf=u2%v6q&kg z%@q`*Nsnp@ook7fS*n3I#_js=qN7e+Ppb|?DaKSZ6iic1ptb@ ztH7c(qZab!vt9Y&KqHk@j9HLqVJG?E0zF4Z6yz30vbU4tE&Ru@`hp;4(V*aGB4EaG zEnEZiuaCB-c#R-?06=qFJfqkEN-pKpJP9wrBiT$vK|}&-_CEncd87^tgRCl-`i9;? zE_Gl%jd_)00u%}uDAGn!mjfQ|pWcloQz>pAFff2cI(I>IpcDVD5g2&`I)B{my9Rcx z!rWk)CHdKpTvZEo7MBCo>}G2+JOY5SFML`Kc_hKTTxu7O+7H4P2iP}3*c}~4OTXit zTq9_-b~B;7=?AuZzE^ou;vL^9DfcJm(M`4-kugy4c;8I!i_0h;c6t2;$Chwh>l!$6lNTd+z@BnAX%6bGX2rlMm>^b88W z5fQr|6b6TQ=*{{1ct$4WN|pf8if+vmRx0tY9DULHantoN$!dJ#W1N_R36(HyDA!uT zG^w~fws2Ky?t;`f$CnvH3cR{tuRhw9GOWCNNcR-Q!7vY;fJ!V{Z64rZ=J}-kTHEfr z|Ay{^ljG$B!tc+)UZ%tZw$!E=s~P|ktp^!l?rKWBgXjXXAA3ZSDhm6KEZ%HF^m-Ka zl(bqBR*;y8#WS?l1SMO5G_H;ljAsf6Qfr;~gUGeQsY0uJ#bJpFQ|5rJ>l{A3HgSt2ub3fic?GT*)1ES zdQD@ox#A;lhPC{A!pX3MdW-fmNhsCZkK`E4PFdM^UtW+8a=-xDe#uz7VBtc0nd%Xr z|E{AOjg92tmivB8dq>a_)U~xS)dEjhZ!=Y_^&&t!-NRy=75f*l)%o@d4KqJ3 z-{d%Vi*3x|hc9+K z9UcccNr$k#VSE9PV+7)Div}?A(&@1?W3e(uPlB$b!(LdCqQUS8c~L6{xD?}iSEC}IHV9B{DVlv)8O+bg49D$F$@Yc z*r%peq+Dc^3M7X96IAkm`C>)%sH-NSMz}h_=o?U_ry=$(!vWrh z4mga3H&P};dmoqaOI+gYQ691v$liA~vf{e3^|o=ETE}Xhf*t;R+&F021T0 zB&K4#M}|RIS-~euJQl36gB(i!E!q-AZ)TErTfct1)(Icy;epksIa?ISAy{5REQUNl zCT^~3T0y2ZYtLI{qu=@?s;mp5@Atr2eJ|+LuAmzOX^#@_D|XYk@+?TU^~eNGDK_-% zlq{kDw91R2Ejl4kC$~2YAgar**DN?f*ZSV~=7G}hhAOmV6ng_nHc`6{QFkLjl7eCu zA=CtGNbX_r8HEqD(PysXCghzvnLFKUQzdV+4Y`Xls92Y8CyVhiUQ({`jeozrjO!+x z>8yyb&R(%}8yn`3{+UCB&j4fmp;qLe2OZ2Egn+)=L#L&Z=_8c>gZV1h{zL`i{cBh zy<#cLCn60SnX8JTdb;Mc(njJZLNLK^x$%28qDZt3aR)fo)0v)&$Nb=b9#nDmHHRa) z{-T1FGsw@4CGMb+*ZFFbU%`yV#@jxVM9h2>C7K2OO`BJ}m34}&fSM^(G)o}uH``~E z?XmkWFDPw;SlN1oeb+pcnp29TAqdu<<(J5VS)Jrx!i2@;x|s3=>a!m=hCQs#GSW7t zq}Ld=`?5*A1jErU=9Bsu>8}%0msDX^;v)*E=+WTTRmOEi^gqq_GDnBkXoN&Edt0nG z*1^%?uKMBF*9_Orwjo&P;{gHu97ak$uAvS4be8u&I;o7@-WF$c=db=^au?V+=sIxR z(QmO*_->P5J|-!m>~R9QF6?LGv%Wc}v=M)8aka~f_6j{t0&QIR^}B~s&o4hO8Mdj+ zxW-A_A2fp0;aVf}Dg0n=hTWu0<1{lfgSOD=mXE zGx%OgI}^;T0*5u&H&7itN#n8v3?-65Q6TMAB)ydZykNBuhPi2P(aB@2&GwmFxLUwP z)n2OP6GNUND>X+E1R;(Nk?pZn(U1J(zl zuQ7YEg8dUp=s#w1_feygaB1lx6UAhoUGP+X!d8=uE43P;oI328f)WCiusK z?ePB-!?X8b>Tt{z<3u#ordX>Y9t;Cyg!pEw>k;7A&l8dj$AUs~`;Ax-PKo@O`iDar z3J|7T1~%E=k1k@gbkw49@zJ|H{Y>9o2Hp)R=O21SxEn9KsSm;AcDOcnhzsp#QQU>I_L) zNp3R42-C)xyMj{i;|fzmNaBb;3GZ5}cW-E9-ih#^lH5P|rjxpVE<~w!Q2LK)rYj;+ zz2_rHe@VsUG0Bx1lVKXFIK||is7A9>YI=|r6y1{GxPGL=5xHh*)-Go0Y^f(Eno!|u zIA_qtOc=;L9r1|1^vzoHl|+d+>Bv(9hbQz@MC8QNb(DP zHYJ69%|z-eJJrS;Y*!TJ1%71D5tXl*v6nDoBpF`O2)wCAIvk9qa)tJ&^}<5oSK=xc z3QJE1KhXed1to8Fh+L(3dAN46y9P3Wb+7+_`7_3h7$DJ9eAZIfap@*->Lsi5G*jRh z+zGfwN}+{%+y#`z7!<%Ju2n?UnPc6$>^CoZFGtLXiX8$ONvtSFQ#q9!Ir$Cd4}M3* z@W9k_SvK5~VK>}11&-lw71T7=hQD`2BduKPodsi$^_+Y)upyY>mU!FWobw)#!|<9* zdntv9%nu)i(NpI5uYmFg ziN8{Z&@+KHA@hW23j&H!ZaE(Hnm=Ov^lFBJs{C@%kie!#{Goshj<8fw&`C_3=G$e) ze0Vmo?B_^wG&&n#VtqUgSi^;u6jO(|zGyLx1Zcr99ZcLC(_9Y#z@ro2!wxN(ROqQ} zJk9Y~We;B52hS7MuoJaRYJL1zz_SRICIv@}M_7dT8|BHEq5UoSdv`c`xa=^i78lt5 z`9DvX)C6>7a3nQ;LhJP#?L1b^WNW3yK6l~qlPf$#L-6X47cS5q%|s9b2wk-szq$G& zyrnLQfeVY&9}9+&1Rb~74i5EH=TF7*dhNri5?OrzCw{vilNX;EK=e~un310Glz3>#geVDx9D>J@Oc)Lqf7^euDaBk9V4#FDU=d=48jCxy6Hana%R_;hq(sA5GKtKJ zP5`MKLUc>iNFZJqO>(pyk(rI@)Y7b!rFzmp-piO8pG3CPci%W@OSOM9(twEw+S{#N zIAJeIjrK#M+-cI;xszr*R6m9~oTMTz3i$gPhlx{kJLJn-sQx5>5C!vztjfSf(VcFWSCQN9&&Ss>^X3k+FQA>l_^tLlC78kfO$OgQ9 zVJG^JfufI*)QuWLnulQ{m1!}RX(PS3uvR@ zErlLUB6lrJB{XVS!Nq()m~8;1;SBrmM$|vWRh2lUnhL8TX9I|vd&HCXwjJk4m_?71LTU%I~-VaS9WBT3n6=NInaznuug5X69$3dz8@u7qe&+Bd9e%F&DN?lmVe8m(x{EkP4;(Hrtq^#@ zNb%S(G3piTH+K>bx`-&`uR1UQLWcrsp=pB1-cAZSu|I2J+6mf`^=gSpUaDQDQHG?! zuKi^C&ZjMl7m-3;A!lb!J=|8#&WR6aoe5lle_}tbcV+pVA)+Wuy+a)8y3@5PQkVWY zm_59HxIN#;HM>K-UH9X9_4baz?7xeQHxo$inZFtAMy+v@PqUIWeyS!WCdOWC9>y;H zWYq>ukroX@b91Da1T>qI|D8-Ob$W4aJe_$hH(JLo+uGPfcAkIDUUBOD%#HW=e(~D` zj0AKS`|U0^<*N|=!_r{;N#p3j*_n;Gc`&V*r}H2!vdfQ%&&;6zQ#lADCCpU|uyq`F z)p}IIv}=ro3q(J%{YvtZc)$R*(Wc=P_f=qTU4%0lUqX1t<}CLxbX-ja*xs)dG0T&! zI0!7Yd^IOA?;Kjuv{iWwdGUhCLlGja^PUEczT?u%nBds+omYRP4TLSK4|^FbBrmTh z%xey)k+q;rxhtwdu-r%5OgdP!MO^NucbVx5b$3k|a0nOpU!>&k$kN{v2K~DYn&fC( z?MY%%0F&ZWn|6P>K3)X7yi3%%zjOXouh9iD|7yO{`-3fn*YAoh6wXwqu;Glp8thnWK@&^!j(Dyey(ik zYk=6ZoYjW^Oa{z{rn-0E>vF)v-0?xBv(ftO{(TD24ptncIj#?kS6qSbH<{1cb1JT6 zZOt@lV+oiGYt_p&K11E@dH5A~3kqmbmv#w5&gRK-Amke1Xso5GsK!_G<&FXLSB@Hs zhf2T&t4d=QKfOWxncE?MbZq(N-0qirO|=OWBDX*kuv)bIe82N{xKF*4B54KnYwTVh z;Wm8y!h4#R5cW)JB70x1DjZE_R9&2s0_!gE53R_NY0A%V%7?k`>%Bdl z??E9FXq_?fTI=6VkeonTqKvlofaRuo$o<0u(qnOh9@>JkgHsUYZEYF&)PlczaJl9j z-<0e`Qaf!9P=8WM{dOL3zCD}&A3u_pKI_2|8AvG1{HJ?|yLN8~b&ss=SKJ%aCX2-6 zFJJd6(u`=f4Y`U;D8ghQlp#M^;*Pg2 z+SSr!!GnWLafI)~!GpMkI?7h$L?hm;D-n%x`K|gard$=L#L>K1Pn9dFb49I=xxvZY z9x`nlxVDUl^46JUGtpCcQ>JA&fR3{|fe7{eV;3#e050Q@M!D?~R#9WzD1eAwU83-v zWcQLv2p5bV^+T%%ag8cmbu6ODghWDcH6$H9=R-jy$xIT}Je^vXDVL!JruD<;ubFp|jd#K&6-Vm;9r+bWp31-Fu&bZ!c7N(wuNpg48(&jQ#l8M7WddfI+fE-lA;y#Y6~6)Ti{{jm!KH^cGvFhV zc7UIj&*jT;JY*(^>GUUXWbC?PyXx1TuA6E-LF}tTZ=d;vP*Lz-|2$Vj4w#yj)_O3W z_GA^2@+#=A*WJqtbQBdC+5UGg8*%f~0r7Y-s{U7C*A)>1G!C}S4@gIb|Eby8Ua^h8 zYT9qb#mDj_{3z+@_MUBR(JV+}c6JsiFWFZTeaK|nNLuaj#B@PQY`dtity03NDu_9&3p_miY z0<@xaHK6bkb zJEpJn69p_rlzNV zAk(YLUnFT2%J&Eg)1kfbY?A%X{XD-TIw9rvl&;8TU(VwKi@$s6|4V!o_&e+oX;U`N z&fL>y$X*%(#~H@1*w2Ya^6#)ZGLN4t<}Tvei?OOn%sFejJ1Lc@*R2tbZ4^5%=nj@9 zn~o1rhHp2UyXiI`1FB=U;FW#WNv3VswXLR|tZY6DxgqJPqcV+Z-{k!Afn>KTV&W4L zgcJX2ayRK@fU6`zT+F9{CDvn}_el^_g&qUV4HO%(z|T2t`)6<50~JT8hTT=_A3A(k zvSg!j9iR4-v00qN*s3Zie0_2skbb%Q1CxH|i$iT;Rh7f~!@B2+ql$`(^X0e@Xyg@* z@bm89O~1uLf-fBex^cWCAQER4gFjG2{{QGrF{UaxNt zYhO;yd=Ht!3E9oQKE@euAUFn}%Jt0pRT~~sj#?U5NwZva0K4UzJLST=ydy)}4Qk3K z1%2JMa|mFPsZLgxXO=QC}sLMC1 z6yV=dx1zVGILOE-gJ5wovdDm_50GPTH!oqL>UA(fz)^B(B7cEd@vvIHc!LpD#UHQU zQS@_vh;#t(Rj&FXZKaBwR0G+Q;gie36rFW0Ovim%s?#xB<-`~k>^o7<|LG8tb zg@G8dH+$D~xDlwQr>8LHjHXwdBEDDP1c@8U{J&$igfjJ(g9O@()6>#sX8Fq#yRNIw zz4&-|c=Zm8wLT_M`m|J%Z<}~^>-2L>6~baxlq>X8*pgq6VNh>|2X4tl`4Iog*N~0n zOz<;ew0>C)Z2_CRkXRLa!xONW+u!GEgoW}K5*x(hWny{pNEP+)+cEGAS5*X<)Puzs zw32Zmq2Uf6u@qW9pYT|VU;{fG0n78M-W~t?qvhwow?vLyC6aG6$xI6y#pF>AS2PG91(vV`cD*BLu;d_aR zX@^Yl?(Y0a!Z^QI-6sF+as_1}*?T1g6-&ju&UQMEYqz)Q{|P@k3MD;#SxwDnPEO3^pue|1>Cg<>p8J2bFfTUOp2Mzh3?UI1<~6`L3Eg?8xH=PQV#69DUv!W zb4C;T?l$xOGIp55FjhyW*JK8qH2k^Ss!4QWYE9k*?)@cYrt-sfR88Iu7 zH!;M-+(l-{@{csDH`hLFH_9yCdTz>N{~Zb*I^;2B!Z&PAWw^Mw-l1!+A!oL?bNI$q z24$0f$jn=RQq04763#V{qXbR!C=W_EyvLbqb>>p-kdgtATB+C7M9v}jOsxTt$uS3s z>*WixdOgshl2mj6HmawDNIukfYn8&;#)}z+T}H^|yIlD`H9~t2G*Oize`TQC1pF8d^>bo`2bg|F z1E)z9sVC1j>8(?qJ^{JF^H9;*AIxWAxE!rz8Jtw@1TnRX8p)_%`mm^P6P*Had&K_; zlbDYQlw107BWJ96o>9Pd97Tuih?Y2s7XuVpO$hDkl#sS~ONPn*@tu6;#LAAVo^h!} z0)I+q`DoAbpv2oFl!(R|)e7$oH_rZ0xuW-t`WZtpAO?NlwANvAd6nRb-BkTbgR(#w zcYG(;^$%dT!?RfH?EgR6C&eT63#1~G<9-7DdhP3FF8FUKBnecYAUsG9Z8TSJPej3M zODvV-YBw!6xh(CaPLH(3FXB=^6^Dh>zm8pz{>G*(+!E!z)X6FJw5522TyX1t2R;$y zl4j0T|Gv1WWI=-Xrl1mEriPk;^|bnx+cnz6<$8w zEaMnDdoyatD5^+&V5#0vq01njHn6 z`}x@Xn$}{SPKA&OOeL+;YNKRn%KwiU{XAwa@i>JJ)PU8lv*$F^8sp;G&TDVPpVTFCIl3qJYvAJ4d_MGQ^W)Hq)Zk&-;+sx>w z!`o*;dngI$YcOtuI+r!(C;ZvYc;5IP?;JL%oubBy$dWfFvMY}nY()kgRZe7Q-00e* z*`^y9^1L!1`&l;PDe%E(+(~gw38}OcWOX<4;~7BPelBLUFb}C0JT@!v?HUnFkJMRf zcU-vkmJD|JuYO*t376b2b4HaFF*#`>m9Gnjb|j$fN^W@bIu0qBI;U1^$sz(s?T8v6 z%b6}jPb8ryhc9zAs%1(&H$>J4idiATS zFo6b+m8-2j`75KN$IU}%G04gXR;Ft0?wTgk#n$ra%Z1Q%1gdJ}3U66}n(hkQwMPgf zZ9JAwJQZ2!lKHF_j%MCoQ2{K5QPv6r?x?$d|F!g#Y5xSXvM1wU_{geP-C>uhsj00z zvRJN*JY`0NnQR1HeN;OKCI$MP{{?=ZC<%}lxBS;q7*iMHODIe3bg~sY; zsVUavHIJ~@7)$}GbTzQKuGRc-bjW0)>q?FeB@&TV(e!^swwBjwYt@8Jf~&}sDlxb& zXI5FI7GnEza0-5FAoZ*_{JgW}@(v%c+nS`q-RL9Ne(He^YIqb8S6!3o^V%jb#s!+) z8V3zeM5*hRM@Oql|8I0vqG?l&?{=j7Mvp!Izot6SxL5Op%#dt!Mh3<6gI&fx!bq(d b0`LC`dr8$8Cv7*pK>ifv)F8Do=Ar)s@QPk} literal 0 HcmV?d00001 diff --git a/rtdata/rt_splash_5.svg b/rtdata/rt_splash_5.svg new file mode 100644 index 000000000..d5f7ac4f3 --- /dev/null +++ b/rtdata/rt_splash_5.svg @@ -0,0 +1,1772 @@ + + + + + RawTherapee logo white font white glow + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + RawTherapee logo white font white glow + + + RawTherapee + + + + + rawtherapee + logo + white + + + www.rawtherapee.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Select the desired element and apply one of the effects in the Filter Editor. You might need to ungroup the element before applying. For example to set the RT ring to have a colorful glow, select it and enable the "ring glow". You can change the flood color of the "ring shadow" effect to make it white if you want to make the logo usable on a dark background.For logo specifics, refer to rt_logo.svg Raw + Therapee + "Raw" font Eras-UltraBlk, 69px, -3px spacing between characters, skewed 2° to the right."Therapee" font Eras-Medium, 68px, 4px spacing between characters, skewed 2° to the right.Both have a dropshadow with an opacity of 0.40 and Gaussian blur standard deviation of 3.5.Version number Eras bold 64 or less.Eras font from "freefonts-0.10":ftp://ftp.gimp.org/pub/gimp/fonts/ RawTherapee splash screen design version 1.0 from 2014-05-03 | www.rawtherapee.com + GNU GPLv3 + 5 + + + diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index a68157b65..7e25f907f 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -1,6 +1,13 @@ //////////////////////////////////////////////////////////////// // -// simple pentax pixelshift algorithm +// pentax pixelshift algorithm with motion detection +// +// derived from dcrawps (https://github.com/tomtor/dcrawps), but with additional motion correction methods and adapted for RawTherapee data structures +// +// If motion correction is enabled only the pixels which are not detected as motion are set +// That means for a complete image you have to demosaic one of the frames with a bayer demosaicer to fill red, green and blue +// before calling pixelshift in case motion correction is enabled. +// // copyright (c) Ingo Weyrich 2016 // // @@ -23,58 +30,184 @@ #include "rawimagesource.h" #include "../rtgui/multilangmgr.h" #include "procparams.h" -#include "opthelper.h" #define BENCHMARK #include "StopWatch.h" + +namespace +{ + +float greenDiff(float a, float b) +{ + // calculate the difference between to green samples + // add a small epsilon to avoid division by zero + return std::fabs(a - b) / (std::max(a, b) + 0.0001f); + +} + +} + using namespace std; using namespace rtengine; -void RawImageSource::pixelshift_simple(int winx, int winy, int winw, int winh) +void RawImageSource::pixelshift_simple(int winx, int winy, int winw, int winh, bool detectMotion, int motion, bool showMotion, unsigned int frame, unsigned int gridSize) { -BENCHFUN - double progress = 0.0; - const bool plistenerActive = plistener; + BENCHFUN if (plistener) { plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::pixelshift_simple])); - plistener->setProgress (progress); + plistener->setProgress(0.0); } - const int bord = 4; + // If the values of two corresponding green pixels differ my more then motionThreshold %, the pixel will be treated as a badGreen pixel + const float motionThreshold = 1.f - (motion / 100.f); + + unsigned int offsX = 0, offsY = 0; + if(detectMotion && !showMotion) { + // if motion correction is enabled we have to adjust the offsets for the selected subframe we use for areas with motion + switch (frame) { + case 0: + offsX = offsY = 0; + break; + + case 1: + offsX = 0; + offsY = 1; + break; + + case 2: + offsX = offsY = 1; + break; + + case 3: + offsX = 1; + offsY = 0; + } + } #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = bord; i < winh - bord; ++i) { - float *greenDest = green[i]; - float *nonGreenDest0 = red[i]; - float *nonGreenDest1 = blue[i]; - int j = bord; - int c = FC(i,j); - if (c == 2 || ((c&1) && FC(i,j+1) == 2)) { + + for(int i = winy + border - offsY; i < winh - (border + offsY); ++i) { + float *greenDest = green[i + offsY]; + float *nonGreenDest0 = red[i + offsY]; + float *nonGreenDest1 = blue[i + offsY]; + int j = winx + border - offsX; + int c = FC(i, j); + + if (c == 2 || ((c & 1) && FC(i, j + 1) == 2)) { + // row with blue pixels => swap destination pointers for non green pixels std::swap(nonGreenDest0, nonGreenDest1); } - if(c&1) { - greenDest[j] = (riFrames[0]->data[i][j] + riFrames[2]->data[i+1][j+1]) / 2.f; - nonGreenDest0[j] = riFrames[3]->data[i][j+1]; - nonGreenDest1[j] = riFrames[1]->data[i+1][j]; - j++; + + // offset to keep the code short. It changes its value between 0 and 1 for each iteration of the loop + unsigned int offset = (c & 1); + + + float greenDifMax[gridSize]; + // motion detection checks the grid around the pixel for differences in green channels + if(detectMotion) { + if(gridSize == 3) { + // compute maximum of differences for first two columns of 3x3 grid + greenDifMax[0] = max(greenDiff(riFrames[0 + offset]->data[i + offset][j - 1], riFrames[2 + offset]->data[i - offset + 1][j]), + greenDiff(riFrames[1 - offset]->data[i - offset][j - 1], riFrames[3 - offset]->data[i + offset - 1][j]), + greenDiff(riFrames[1 - offset]->data[i - offset + 2][j - 1], riFrames[3 - offset]->data[i + offset + 1][j]) + ); + greenDifMax[1] = max(greenDiff(riFrames[1 - offset]->data[i - offset + 1][j], riFrames[3 - offset]->data[i + offset][j + 1]), + greenDiff(riFrames[0 + offset]->data[i + offset - 1][j], riFrames[2 + offset]->data[i - offset][j + 1]), + greenDiff(riFrames[0 + offset]->data[i + offset + 1][j], riFrames[2 + offset]->data[i - offset + 2][j + 1]) + ); + } else if(gridSize == 5) { + // compute maximum of differences for first four columns of 5x5 grid + greenDifMax[0] = max(greenDiff(riFrames[1 - offset]->data[i - offset - 1][j-2], riFrames[3 - offset]->data[i + offset -2][j - 1]), + greenDiff(riFrames[1 - offset]->data[i - offset + 1][j-2], riFrames[3 - offset]->data[i + offset][j - 1]), + greenDiff(riFrames[1 - offset]->data[i - offset + 3][j-2], riFrames[3 - offset]->data[i + offset +2][j - 1]), + greenDiff(riFrames[0 + offset]->data[i + offset - 1][j-2], riFrames[2 + offset]->data[i - offset][j - 1]), + greenDiff(riFrames[0 + offset]->data[i + offset + 1][j-2], riFrames[2 + offset]->data[i - offset + 2][j - 1]) + ); + greenDifMax[1] = max(greenDiff(riFrames[0 + offset]->data[i + offset-2][j - 1], riFrames[2 + offset]->data[i - offset - 1][j]), + greenDiff(riFrames[0 + offset]->data[i + offset][j - 1], riFrames[2 + offset]->data[i - offset + 1][j]), + greenDiff(riFrames[0 + offset]->data[i + offset+2][j - 1], riFrames[2 + offset]->data[i - offset + 3][j]), + greenDiff(riFrames[1 - offset]->data[i - offset][j - 1], riFrames[3 - offset]->data[i + offset - 1][j]), + greenDiff(riFrames[1 - offset]->data[i - offset + 2][j - 1], riFrames[3 - offset]->data[i + offset + 1][j]) + ); + greenDifMax[2] = max(greenDiff(riFrames[1 - offset]->data[i - offset - 1][j], riFrames[3 - offset]->data[i + offset -2][j + 1]), + greenDiff(riFrames[1 - offset]->data[i - offset + 1][j], riFrames[3 - offset]->data[i + offset][j + 1]), + greenDiff(riFrames[1 - offset]->data[i - offset + 3][j], riFrames[3 - offset]->data[i + offset +2][j + 1]), + greenDiff(riFrames[0 + offset]->data[i + offset - 1][j], riFrames[2 + offset]->data[i - offset][j + 1]), + greenDiff(riFrames[0 + offset]->data[i + offset + 1][j], riFrames[2 + offset]->data[i - offset + 2][j + 1]) + ); + greenDifMax[3] = max(greenDiff(riFrames[0 + offset]->data[i + offset-2][j + 1], riFrames[2 + offset]->data[i - offset - 1][j+2]), + greenDiff(riFrames[0 + offset]->data[i + offset][j + 1], riFrames[2 + offset]->data[i - offset + 1][j+2]), + greenDiff(riFrames[0 + offset]->data[i + offset+2][j + 1], riFrames[2 + offset]->data[i - offset + 3][j+2]), + greenDiff(riFrames[1 - offset]->data[i - offset][j + 1], riFrames[3 - offset]->data[i + offset - 1][j+2]), + greenDiff(riFrames[1 - offset]->data[i - offset + 2][j +- 1], riFrames[3 - offset]->data[i + offset + 1][j+2]) + ); + } } - for(; j< winw - bord; j+=2) { - nonGreenDest0[j] = riFrames[0]->data[i][j]; - greenDest[j] = (riFrames[3]->data[i][j+1] + riFrames[1]->data[i+1][j] ) / 2.f; - nonGreenDest1[j] = riFrames[2]->data[i+1][j+1]; - greenDest[j+1] = (riFrames[0]->data[i][j+1] + riFrames[2]->data[i+1][j+2]) / 2.f; - nonGreenDest0[j+1] = riFrames[3]->data[i][j+2]; - nonGreenDest1[j+1] = riFrames[1]->data[i+1][j+1]; + + offset ^= 1; // 0 => 1 or 1 => 0 + + // this is the index for the last column of the grid. Obviously we have to start with gridSize - 1 + int lastIndex = gridSize - 1; + + for(; j < winw - (border + offsX); ++j) { + offset ^= 1; // 0 => 1 or 1 => 0 + + if(detectMotion) { + bool skipNext = false; + float gridMax; + if(gridSize == 1) { + // compute difference for current pixel and skip next pixel, that's the method from dcrawps + gridMax = greenDiff(riFrames[1 - offset]->data[i - offset + 1][j], riFrames[3 - offset]->data[i + offset][j + 1]); + skipNext = !showMotion; + } else if(gridSize == 3) { + // compute maximum of differences for third column of 3x3 grid and save at position lastIndex + greenDifMax[lastIndex] = max(greenDiff(riFrames[0 + offset]->data[i + offset][j + 1], riFrames[2 + offset]->data[i - offset + 1][j + 2]), + greenDiff(riFrames[1 - offset]->data[i - offset][j + 1], riFrames[3 - offset]->data[i + offset - 1][j + 2]), + greenDiff(riFrames[1 - offset]->data[i - offset + 2][j + 1], riFrames[3 - offset]->data[i + offset + 1][j + 2]) + ); + gridMax = max(greenDifMax[0],greenDifMax[1],greenDifMax[2]); + } else if(gridSize == 5) { + // compute maximum of differences for fifth column of 5x5 grid and save at position lastIndex + greenDifMax[lastIndex] = max(greenDiff(riFrames[1 - offset]->data[i - offset - 1][j+2], riFrames[3 - offset]->data[i + offset -2][j + 3]), + greenDiff(riFrames[1 - offset]->data[i - offset + 1][j+2], riFrames[3 - offset]->data[i + offset][j + 3]), + greenDiff(riFrames[1 - offset]->data[i - offset + 3][j+2], riFrames[3 - offset]->data[i + offset +2][j + 3]), + greenDiff(riFrames[0 + offset]->data[i + offset - 1][j+2], riFrames[2 + offset]->data[i - offset][j + 3]), + greenDiff(riFrames[0 + offset]->data[i + offset + 1][j+2], riFrames[2 + offset]->data[i - offset + 2][j + 3]) + ); + gridMax = max(greenDifMax[0],greenDifMax[1],greenDifMax[2],greenDifMax[3],greenDifMax[4]); + } + // adjust index for next column + lastIndex ++; + lastIndex = lastIndex == gridSize ? 0 : lastIndex; + + if (gridMax > motionThreshold) { + // at least one of the tested pixels of the grid is detected as motion + if(showMotion) { + // if showMotion is enabled make the pixel green + greenDest[j] = 10000.f; + nonGreenDest0[j] = nonGreenDest1[j] = 0.f; + } + if(skipNext) { + // treat the horizontally next pixel also as motion + j++; + offset ^= 1; + } + // do not set the motion pixel values. They have already been set by demosaicer or showMotion + continue; + } + } + + // motion correction disabled or no motion detected => combine the values from the four pixelshift frames + greenDest[j + offsX] = (riFrames[1 - offset]->data[i - offset + 1][j] + riFrames[3 - offset]->data[i + offset][j + 1]) / 2.f; + nonGreenDest0[j + offsX] = riFrames[(offset << 1) + offset]->data[i][j + offset]; + nonGreenDest1[j + offsX] = riFrames[2 - offset]->data[i + 1][j - offset + 1]; } } - if(plistenerActive) { - plistener->setProgress(1.00); + if(plistener) { + plistener->setProgress(1.0); } - } -#undef TS -#undef CLF diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 69cda228a..24469cead 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -471,6 +471,7 @@ enum ProcEvent { EvLskal = 441, EvOBPCompens = 442, EvRawImageNum = 443, + EvDemosaicPixelshiftMotion = 444, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 2a7b41847..466b25d82 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -885,6 +885,9 @@ void RAWParams::setDefaults() bayersensor.dcb_enhance = true; //bayersensor.all_enhance = false; bayersensor.lmmse_iterations = 2; + bayersensor.pixelshiftMotion = 70; + bayersensor.pixelshiftMotionCorrection = 3; + bayersensor.pixelshiftShowMotion = false; bayersensor.black0 = 0.0; bayersensor.black1 = 0.0; bayersensor.black2 = 0.0; @@ -3364,6 +3367,18 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b keyFile.set_integer ("RAW Bayer", "LMMSEIterations", raw.bayersensor.lmmse_iterations ); } + if (!pedited || pedited->raw.bayersensor.pixelshiftMotion) { + keyFile.set_integer ("RAW Bayer", "PixelShiftMotion", raw.bayersensor.pixelshiftMotion ); + } + + if (!pedited || pedited->raw.bayersensor.pixelshiftMotionCorrection) { + keyFile.set_integer ("RAW Bayer", "PixelShiftMotionCorrection", raw.bayersensor.pixelshiftMotionCorrection ); + } + + if (!pedited || pedited->raw.bayersensor.pixelshiftShowMotion) { + keyFile.set_boolean ("RAW Bayer", "PixelShiftShowMotion", raw.bayersensor.pixelshiftShowMotion ); + } + //if (!pedited || pedited->raw.bayersensor.allEnhance) keyFile.set_boolean ("RAW Bayer", "ALLEnhance", raw.bayersensor.all_enhance ); if (!pedited || pedited->raw.xtranssensor.method) { @@ -7422,6 +7437,30 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("RAW Bayer", "PixelShiftMotion")) { + raw.bayersensor.pixelshiftMotion = keyFile.get_integer("RAW Bayer", "PixelShiftMotion"); + + if (pedited) { + pedited->raw.bayersensor.pixelshiftMotion = true; + } + } + + if (keyFile.has_key ("RAW Bayer", "PixelShiftMotionCorrection")) { + raw.bayersensor.pixelshiftMotionCorrection = keyFile.get_integer("RAW Bayer", "PixelShiftMotionCorrection"); + + if (pedited) { + pedited->raw.bayersensor.pixelshiftMotionCorrection = true; + } + } + + if (keyFile.has_key ("RAW Bayer", "PixelShiftShowMotion")) { + raw.bayersensor.pixelshiftShowMotion = keyFile.get_boolean("RAW Bayer", "PixelShiftShowMotion"); + + if (pedited) { + pedited->raw.bayersensor.pixelshiftShowMotion = true; + } + } + //if (keyFile.has_key ("RAW Bayer", "ALLEnhance")) { raw.bayersensor.all_enhance = keyFile.get_boolean("RAW Bayer", "ALLEnhance"); if (pedited) pedited->raw.bayersensor.allEnhance = true; } } diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 35a4f1932..3f5951cf8 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1182,6 +1182,9 @@ public: int greenthresh; int dcb_iterations; int lmmse_iterations; + int pixelshiftMotion; + int pixelshiftMotionCorrection; + bool pixelshiftShowMotion; bool dcb_enhance; //bool all_enhance; }; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 37cf2618e..f4760d44e 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1549,6 +1549,7 @@ Stop1.stop(); if(riFrames[0]->get_width() != riFrames[1]->get_width() || riFrames[0]->get_height() != riFrames[1]->get_height()) { numFrames = 1; } + pixelShiftColoursScaled = false; } if (plistener) { @@ -1757,7 +1758,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le printf( "Flat Field Correction:%s\n", rif->get_filename().c_str()); } - copyOriginalPixels(raw, ri, rid, rif); + copyOriginalPixels(raw, ri, rid, rif, rawData); //FLATFIELD end @@ -1798,7 +1799,10 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le } - scaleColors( 0, 0, W, H, raw); //+ + raw parameters for black level(raw.blackxx) + scaleColors( 0, 0, W, H, raw, rawData); //+ + raw parameters for black level(raw.blackxx) + if(numFrames == 4 && raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::pixelshift_simple] && !pixelShiftColoursScaled) { + scaleColors_pixelshift( 0, 0, W, H, raw); + } // Correct vignetting of lens profile if (!hasFlatField && lensProf.useVign) { @@ -1958,11 +1962,11 @@ void RawImageSource::demosaic(const RAWParams &raw) } else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::amaze] ) { amaze_demosaic_RT (0, 0, W, H); } else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::pixelshift_simple] ) { + if(raw.bayersensor.pixelshiftMotion > 0) { + amaze_demosaic_RT (0, 0, W, H); // for non pixelshift files use amaze if pixelshift is selected. We need it also for motion correction + } if(numFrames == 4) { - pixelshift_simple(0, 0, W, H); - scaleColors_pixelshift( 0, 0, W, H, raw); - } else { // for non pixelshift files use amaze if pixelshift is selected - amaze_demosaic_RT (0, 0, W, H); + pixelshift_simple(0, 0, W, H, raw.bayersensor.pixelshiftMotion > 0, raw.bayersensor.pixelshiftMotion, raw.bayersensor.pixelshiftShowMotion, currFrame, raw.bayersensor.pixelshiftMotionCorrection); } } else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::dcb] ) { dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); @@ -3010,7 +3014,7 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile /* Copy original pixel data and * subtract dark frame (if present) from current image and apply flat field correction (if present) */ -void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, RawImage *riDark, RawImage *riFlatFile ) +void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, RawImage *riDark, RawImage *riFlatFile, array2D &rawData ) { // TODO: Change type of black[] to float to avoid conversions unsigned short black[4] = { @@ -3341,7 +3345,7 @@ SSEFUNCTION void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur // Scale original pixels into the range 0 65535 using black offsets and multipliers -void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const RAWParams &raw) +void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const RAWParams &raw, array2D &rawData) { chmax[0] = chmax[1] = chmax[2] = chmax[3] = 0; //channel maxima float black_lev[4] = {0.f};//black level @@ -3555,17 +3559,12 @@ void RawImageSource::scaleColors_pixelshift(int winx, int winy, int winw, int wi for (int row = winy; row < winy + winh; row ++) { for (int col = winx; col < winx + winw; col++) { - float redval = (red[row][col] - cblacksom[0]) * scale_mul[0]; - tmpchmax[0] = max(tmpchmax[0], redval); - red[row][col] = redval; - - float greenval = (green[row][col] - cblacksom[1]) * scale_mul[1]; - tmpchmax[1] = max(tmpchmax[1], greenval); - green[row][col] = greenval; - - float blueval = (blue[row][col] - cblacksom[2]) * scale_mul[2]; - tmpchmax[2] = max(tmpchmax[2], blueval); - blue[row][col] = blueval; + int c = FC(row,col); + for(int frame = 0; frame < 4; ++frame) { + float val = (riFrames[frame]->data[row][col] - cblacksom[c]) * scale_mul[c]; + tmpchmax[c] = max(tmpchmax[c], val); + riFrames[frame]->data[row][col] = val; + } } } @@ -3578,6 +3577,7 @@ void RawImageSource::scaleColors_pixelshift(int winx, int winy, int winw, int wi chmax[2] = max(tmpchmax[2], chmax[2]); } } + pixelShiftColoursScaled = true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 560314802..648e5ec77 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -81,6 +81,7 @@ protected: int threshold; array2D rawData; // holds preprocessed pixel values, rowData[i][j] corresponds to the ith row and jth column + array2D *rawDataFrames[16] = {nullptr}; // the interpolated green plane: array2D green; @@ -128,9 +129,9 @@ public: } void processFlatField(const RAWParams &raw, RawImage *riFlatFile, unsigned short black[4]); - void copyOriginalPixels(const RAWParams &raw, RawImage *ri, RawImage *riDark, RawImage *riFlatFile ); + void copyOriginalPixels(const RAWParams &raw, RawImage *ri, RawImage *riDark, RawImage *riFlatFile, array2D &rawData ); void cfaboxblur (RawImage *riFlatFile, float* cfablur, int boxH, int boxW); - void scaleColors (int winx, int winy, int winw, int winh, const RAWParams &raw); // raw for cblack + void scaleColors (int winx, int winy, int winw, int winh, const RAWParams &raw, array2D &rawData); // raw for cblack void scaleColors_pixelshift(int winx, int winy, int winw, int winh, const RAWParams &raw); @@ -205,6 +206,7 @@ public: ri = riFrames[currFrame]; } protected: + bool pixelShiftColoursScaled = false; typedef unsigned short ushort; void processFalseColorCorrection (Imagefloat* i, const int steps); inline void convert_row_to_YIQ (const float* const r, const float* const g, const float* const b, float* Y, float* I, float* Q, const int W); @@ -261,7 +263,7 @@ protected: void xtransborder_interpolate (int border); void xtrans_interpolate (const int passes, const bool useCieLab); void fast_xtrans_interpolate (); - void pixelshift_simple(int winx, int winy, int winw, int winh); + void pixelshift_simple(int winx, int winy, int winw, int winh, bool detectMotion, int motion, bool showMotion, unsigned int frame, unsigned int method); void hflip (Imagefloat* im); void vflip (Imagefloat* im); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 33e988674..643c9e075 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -470,7 +470,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { RETINEX, // EvRetinexgaintransmission RETINEX, // EvLskal OUTPUTPROFILE, // EvOBPCompens - DARKFRAME // EvRawImageNum + DARKFRAME, // EvRawImageNum + DEMOSAIC // EvDemosaicPixelshiftMotion }; diff --git a/rtengine/rt_math.h b/rtengine/rt_math.h index 67d883080..5e2f04d05 100644 --- a/rtengine/rt_math.h +++ b/rtengine/rt_math.h @@ -74,6 +74,13 @@ inline const _Tp& max(const _Tp& a, const _Tp& b, const _Tp& c, const _Tp& d) return std::max(d, std::max(c, std::max(a, b))); } +template +inline const _Tp& max(const _Tp& a, const _Tp& b, const _Tp& c, const _Tp& d, const _Tp& e) +{ + return max(max(a,b,c),std::max(d,e)); +} + + template inline _Tp intp(_Tp a, _Tp b, _Tp c) { diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index 639eabc02..92351be2b 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -81,6 +81,34 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA lmmseOptions->pack_start(*lmmseIterations); pack_start( *lmmseOptions, Gtk::PACK_SHRINK, 4); + pixelShiftOptions = Gtk::manage (new Gtk::VBox ()); + pixelShiftOptions->set_border_width(4); + pixelShiftShowMotion = Gtk::manage (new Gtk::CheckButton(M("TP_RAW_PIXELSHIFTSHOWMOTION"))); + pixelShiftOptions->pack_start(*pixelShiftShowMotion); + + pixelShiftMotion = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTMOTION"), 0, 100, 1, 70)); + pixelShiftMotion->setAdjusterListener (this); + pixelShiftMotion->set_tooltip_markup (M("TP_RAW_PIXELSHIFTMOTION_TOOLTIP")); + + if (pixelShiftMotion->delay < options.adjusterMaxDelay) { + pixelShiftMotion->delay = options.adjusterMaxDelay; + } + pixelShiftMotion->show(); + pixelShiftOptions->pack_start(*pixelShiftMotion); + + pixelShiftMotionCorrection = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTMOTIONCORRECTION"), 1, 5, 2, 3)); + pixelShiftMotionCorrection->setAdjusterListener (this); + pixelShiftMotionCorrection->set_tooltip_markup (M("TP_RAW_PIXELSHIFTMOTIONCORRECTION_TOOLTIP")); + + if (pixelShiftMotionCorrection->delay < options.adjusterMaxDelay) { + pixelShiftMotionCorrection->delay = options.adjusterMaxDelay; + } + + pixelShiftMotionCorrection->show(); + pixelShiftOptions->pack_start(*pixelShiftMotionCorrection); + pack_start( *pixelShiftOptions, Gtk::PACK_SHRINK, 4); + + pack_start( *Gtk::manage( new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0 ); ccSteps = Gtk::manage (new Adjuster (M("TP_RAW_FALSECOLOR"), 0, 5, 1, 0 )); ccSteps->setAdjusterListener (this); @@ -102,6 +130,7 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA methodconn = method->signal_changed().connect( sigc::mem_fun(*this, &BayerProcess::methodChanged) ); imagenumberconn = imageNumber->signal_changed().connect( sigc::mem_fun(*this, &BayerProcess::imageNumberChanged) ); dcbEnhconn = dcbEnhance->signal_toggled().connect ( sigc::mem_fun(*this, &BayerProcess::dcbEnhanceChanged), true); + pixelShiftShowMotionconn = pixelShiftShowMotion->signal_toggled().connect ( sigc::mem_fun(*this, &BayerProcess::pixelShiftShowMotionChanged), true); //allEnhconn = allEnhance->signal_toggled().connect ( sigc::mem_fun(*this, &BayerProcess::allEnhanceChanged), true); } @@ -129,8 +158,11 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params ccSteps->setEditedState (pedited->raw.bayersensor.ccSteps ? Edited : UnEdited); dcbIterations->setEditedState ( pedited->raw.bayersensor.dcbIterations ? Edited : UnEdited); dcbEnhance->set_inconsistent(!pedited->raw.bayersensor.dcbEnhance); + pixelShiftShowMotion->set_inconsistent(!pedited->raw.bayersensor.pixelshiftShowMotion); //allEnhance->set_inconsistent(!pedited->raw.bayersensor.allEnhance); lmmseIterations->setEditedState ( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited); + pixelShiftMotion->setEditedState ( pedited->raw.bayersensor.pixelshiftMotion ? Edited : UnEdited); + pixelShiftMotionCorrection->setEditedState ( pedited->raw.bayersensor.pixelshiftMotionCorrection ? Edited : UnEdited); if(!pedited->raw.bayersensor.method) { method->set_active(procparams::RAWParams::BayerSensor::numMethods); // No name @@ -144,8 +176,11 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params dcbIterations->setValue (pp->raw.bayersensor.dcb_iterations); dcbEnhance->set_active(pp->raw.bayersensor.dcb_enhance); + pixelShiftShowMotion->set_active(pp->raw.bayersensor.pixelshiftShowMotion); ccSteps->setValue (pp->raw.bayersensor.ccSteps); lmmseIterations->setValue (pp->raw.bayersensor.lmmse_iterations); + pixelShiftMotion->setValue (pp->raw.bayersensor.pixelshiftMotion); + pixelShiftMotionCorrection->setValue (pp->raw.bayersensor.pixelshiftMotionCorrection); if (!batchMode) { if (pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::methodstring[procparams::RAWParams::BayerSensor::dcb] || @@ -160,6 +195,12 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params } else { lmmseOptions->hide(); } + if (pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::methodstring[procparams::RAWParams::BayerSensor::pixelshift_simple] || + method->get_active_row_number() == procparams::RAWParams::BayerSensor::numMethods) { + pixelShiftOptions->show(); + } else { + pixelShiftOptions->hide(); + } // Flase color suppression is applied to all demozaicing method, so don't hide anything /*if (pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::methodstring[procparams::RAWParams::BayerSensor::eahd] || @@ -188,6 +229,9 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pp->raw.bayersensor.dcb_enhance = dcbEnhance->get_active(); //pp->raw.bayersensor.all_enhance = allEnhance->get_active(); pp->raw.bayersensor.lmmse_iterations = lmmseIterations->getIntValue(); + pp->raw.bayersensor.pixelshiftMotion = pixelShiftMotion->getIntValue(); + pp->raw.bayersensor.pixelshiftMotionCorrection = pixelShiftMotionCorrection->getIntValue(); + pp->raw.bayersensor.pixelshiftShowMotion = pixelShiftShowMotion->get_active(); int currentRow = method->get_active_row_number(); if( currentRow >= 0 && currentRow < procparams::RAWParams::BayerSensor::numMethods) { @@ -208,6 +252,9 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pedited->raw.bayersensor.dcbEnhance = !dcbEnhance->get_inconsistent(); //pedited->raw.bayersensor.allEnhance = !allEnhance->get_inconsistent(); pedited->raw.bayersensor.lmmseIterations = lmmseIterations->getEditedState (); + pedited->raw.bayersensor.pixelshiftMotion = pixelShiftMotion->getEditedState (); + pedited->raw.bayersensor.pixelshiftMotionCorrection = pixelShiftMotionCorrection->getEditedState (); + pedited->raw.bayersensor.pixelshiftShowMotion = !pixelShiftShowMotion->get_inconsistent(); } } @@ -219,25 +266,34 @@ void BayerProcess::setBatchMode(bool batchMode) imageNumber->set_active(4); dcbOptions->hide(); lmmseOptions->hide(); + pixelShiftOptions->hide(); ToolPanel::setBatchMode (batchMode); ccSteps->showEditedCB (); dcbIterations->showEditedCB (); lmmseIterations->showEditedCB (); + pixelShiftMotion->showEditedCB (); + pixelShiftMotionCorrection->showEditedCB (); } void BayerProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) { dcbIterations->setDefault( defParams->raw.bayersensor.dcb_iterations); lmmseIterations->setDefault( defParams->raw.bayersensor.lmmse_iterations); + pixelShiftMotion->setDefault( defParams->raw.bayersensor.pixelshiftMotion); + pixelShiftMotionCorrection->setDefault( defParams->raw.bayersensor.pixelshiftMotionCorrection); ccSteps->setDefault (defParams->raw.bayersensor.ccSteps); if (pedited) { dcbIterations->setDefaultEditedState( pedited->raw.bayersensor.dcbIterations ? Edited : UnEdited); lmmseIterations->setDefaultEditedState( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited); + pixelShiftMotion->setDefaultEditedState( pedited->raw.bayersensor.pixelshiftMotion ? Edited : UnEdited); + pixelShiftMotionCorrection->setDefaultEditedState( pedited->raw.bayersensor.pixelshiftMotionCorrection ? Edited : UnEdited); ccSteps->setDefaultEditedState(pedited->raw.bayersensor.ccSteps ? Edited : UnEdited); } else { dcbIterations->setDefaultEditedState( Irrelevant ); lmmseIterations->setDefaultEditedState( Irrelevant ); + pixelShiftMotion->setDefaultEditedState( Irrelevant ); + pixelShiftMotionCorrection->setDefaultEditedState( Irrelevant ); ccSteps->setDefaultEditedState(Irrelevant ); } } @@ -251,6 +307,10 @@ void BayerProcess::adjusterChanged (Adjuster* a, double newval) listener->panelChanged (EvDemosaicFalseColorIter, a->getTextValue() ); } else if (a == lmmseIterations) { listener->panelChanged (EvDemosaicLMMSEIter, a->getTextValue() ); + } else if (a == pixelShiftMotion) { + listener->panelChanged (EvDemosaicPixelshiftMotion, a->getTextValue() ); + } else if (a == pixelShiftMotionCorrection) { + listener->panelChanged (EvDemosaicPixelshiftMotion, a->getTextValue() ); } } } @@ -271,6 +331,12 @@ void BayerProcess::methodChanged () lmmseOptions->hide(); } + if ( curSelection == procparams::RAWParams::BayerSensor::pixelshift_simple) { + pixelShiftOptions->show(); + } else { + pixelShiftOptions->hide(); + } + Glib::ustring methodName = ""; bool ppreq = false; @@ -316,6 +382,26 @@ void BayerProcess::dcbEnhanceChanged () } } +void BayerProcess::pixelShiftShowMotionChanged () +{ + if (batchMode) { + if (pixelShiftShowMotion->get_inconsistent()) { + pixelShiftShowMotion->set_inconsistent (false); + pixelShiftShowMotionconn.block (true); + pixelShiftShowMotion->set_active (false); + pixelShiftShowMotionconn.block (false); + } else if (lastDCBen) { + pixelShiftShowMotion->set_inconsistent (true); + } + + lastDCBen = pixelShiftShowMotion->get_active (); + } + + if (listener) { + listener->panelChanged (EvDemosaicPixelshiftMotion, pixelShiftShowMotion->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); + } +} + /*void BayerProcess::allEnhanceChanged () { if (batchMode) { diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h index bba4bd51d..404324ed6 100644 --- a/rtgui/bayerprocess.h +++ b/rtgui/bayerprocess.h @@ -41,11 +41,14 @@ protected: //Gtk::CheckButton* allEnhance; Gtk::VBox *lmmseOptions; Adjuster* lmmseIterations; - + Gtk::VBox *pixelShiftOptions; + Adjuster* pixelShiftMotion; + Adjuster* pixelShiftMotionCorrection; + Gtk::CheckButton* pixelShiftShowMotion; bool lastDCBen; int oldMethod; //bool lastALLen; - sigc::connection methodconn, imagenumberconn, dcbEnhconn; //,allEnhconn; + sigc::connection methodconn, imagenumberconn, dcbEnhconn, pixelShiftShowMotionconn; //,allEnhconn; public: BayerProcess (); @@ -59,6 +62,7 @@ public: void imageNumberChanged (); void adjusterChanged (Adjuster* a, double newval); void dcbEnhanceChanged(); + void pixelShiftShowMotionChanged(); //void allEnhanceChanged(); }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ebb31ef1d..6a020cd8b 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -370,6 +370,9 @@ void ParamsEdited::set (bool v) raw.bayersensor.dcbEnhance = v; //raw.bayersensor.allEnhance = v; raw.bayersensor.lmmseIterations = v; + raw.bayersensor.pixelshiftMotion = v; + raw.bayersensor.pixelshiftMotionCorrection = v; + raw.bayersensor.pixelshiftShowMotion = v; raw.bayersensor.greenEq = v; raw.bayersensor.linenoise = v; raw.xtranssensor.method = v; @@ -866,6 +869,9 @@ void ParamsEdited::initFrom (const std::vector raw.bayersensor.dcbEnhance = raw.bayersensor.dcbEnhance && p.raw.bayersensor.dcb_enhance == other.raw.bayersensor.dcb_enhance; //raw.bayersensor.allEnhance = raw.bayersensor.allEnhance && p.raw.bayersensor.all_enhance == other.raw.bayersensor.all_enhance; raw.bayersensor.lmmseIterations = raw.bayersensor.lmmseIterations && p.raw.bayersensor.lmmse_iterations == other.raw.bayersensor.lmmse_iterations; + raw.bayersensor.pixelshiftMotion = raw.bayersensor.pixelshiftMotion && p.raw.bayersensor.pixelshiftMotion == other.raw.bayersensor.pixelshiftMotion; + raw.bayersensor.pixelshiftMotionCorrection = raw.bayersensor.pixelshiftMotionCorrection && p.raw.bayersensor.pixelshiftMotionCorrection == other.raw.bayersensor.pixelshiftMotionCorrection; + raw.bayersensor.pixelshiftShowMotion = raw.bayersensor.pixelshiftShowMotion && p.raw.bayersensor.pixelshiftShowMotion == other.raw.bayersensor.pixelshiftShowMotion; raw.bayersensor.greenEq = raw.bayersensor.greenEq && p.raw.bayersensor.greenthresh == other.raw.bayersensor.greenthresh; raw.bayersensor.linenoise = raw.bayersensor.linenoise && p.raw.bayersensor.linenoise == other.raw.bayersensor.linenoise; raw.xtranssensor.method = raw.xtranssensor.method && p.raw.xtranssensor.method == other.raw.xtranssensor.method; @@ -2278,6 +2284,18 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.raw.bayersensor.lmmse_iterations = mods.raw.bayersensor.lmmse_iterations; } + if (raw.bayersensor.pixelshiftMotion) { + toEdit.raw.bayersensor.pixelshiftMotion = mods.raw.bayersensor.pixelshiftMotion; + } + + if (raw.bayersensor.pixelshiftMotionCorrection) { + toEdit.raw.bayersensor.pixelshiftMotionCorrection = mods.raw.bayersensor.pixelshiftMotionCorrection; + } + + if (raw.bayersensor.pixelshiftShowMotion) { + toEdit.raw.bayersensor.pixelshiftShowMotion = mods.raw.bayersensor.pixelshiftShowMotion; + } + //if (raw.bayersensor.allEnhance) toEdit.raw.bayersensor.all_enhance = mods.raw.bayersensor.all_enhance; if (raw.bayersensor.greenEq) { toEdit.raw.bayersensor.greenthresh = dontforceSet && options.baBehav[ADDSET_PREPROCESS_GREENEQUIL] ? toEdit.raw.bayersensor.greenthresh + mods.raw.bayersensor.greenthresh : mods.raw.bayersensor.greenthresh; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 4e9fa4eb4..5546c9857 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -692,6 +692,9 @@ public: bool dcbIterations; bool dcbEnhance; bool lmmseIterations; + bool pixelshiftMotion; + bool pixelshiftMotionCorrection; + bool pixelshiftShowMotion; //bool allEnhance; bool greenEq; bool linenoise;