From 416cf0ffbf3ba1d3d436a68c45b46c207fdd5842 Mon Sep 17 00:00:00 2001 From: Matt Clifford Date: Tue, 8 Oct 2024 17:42:15 +0100 Subject: [PATCH] doc build --- docs/IQM_Vis.metrics.rst | 30 +- docs/_build/doctrees/IQM_Vis.metrics.doctree | Bin 108008 -> 111988 bytes .../doctrees/IQM_Vis.transforms.doctree | Bin 93416 -> 93466 bytes docs/_build/doctrees/environment.pickle | Bin 454753 -> 456619 bytes docs/_build/html/IQM_Vis.html | 5 +- docs/_build/html/IQM_Vis.metrics.SSIM.html | 5 +- docs/_build/html/IQM_Vis.metrics.html | 233 +++---- docs/_build/html/IQM_Vis.transforms.html | 9 +- .../_modules/IQM_Vis/UI/experiment_mode.html | 2 +- .../_modules/IQM_Vis/examples/dataset.html | 10 +- .../html/_modules/IQM_Vis/examples/dists.html | 12 +- .../_modules/IQM_Vis/examples/experiment.html | 12 +- .../_modules/IQM_Vis/examples/multiple.html | 10 +- .../_build/html/_modules/IQM_Vis/metrics.html | 15 +- .../html/_modules/IQM_Vis/metrics/IQMs.html | 628 ------------------ .../IQM_Vis/metrics/non_perceptual.html | 268 ++++++++ .../IQM_Vis/metrics/perceptual_DL.html | 221 ++++++ .../IQM_Vis/metrics/perceptual_trad.html | 341 ++++++++++ .../html/_modules/IQM_Vis/transforms.html | 6 +- .../IQM_Vis/transforms/additive_noise.html | 16 +- .../_modules/IQM_Vis/transforms/effects.html | 9 +- docs/_build/html/_modules/index.html | 6 +- .../html/_sources/IQM_Vis.metrics.rst.txt | 30 +- docs/_build/html/genindex.html | 75 ++- docs/_build/html/modules.html | 5 +- docs/_build/html/objects.inv | Bin 8852 -> 8918 bytes docs/_build/html/py-modindex.html | 17 +- docs/_build/html/searchindex.js | 2 +- 28 files changed, 1141 insertions(+), 826 deletions(-) delete mode 100644 docs/_build/html/_modules/IQM_Vis/metrics/IQMs.html create mode 100644 docs/_build/html/_modules/IQM_Vis/metrics/non_perceptual.html create mode 100644 docs/_build/html/_modules/IQM_Vis/metrics/perceptual_DL.html create mode 100644 docs/_build/html/_modules/IQM_Vis/metrics/perceptual_trad.html diff --git a/docs/IQM_Vis.metrics.rst b/docs/IQM_Vis.metrics.rst index f6f3c5b..0b9563c 100644 --- a/docs/IQM_Vis.metrics.rst +++ b/docs/IQM_Vis.metrics.rst @@ -12,10 +12,34 @@ Subpackages Submodules ---------- -IQM\_Vis.metrics.IQMs module ----------------------------- +IQM\_Vis.metrics.metric\_utils module +------------------------------------- -.. automodule:: IQM_Vis.metrics.IQMs +.. automodule:: IQM_Vis.metrics.metric_utils + :members: + :undoc-members: + :show-inheritance: + +IQM\_Vis.metrics.non\_perceptual module +--------------------------------------- + +.. automodule:: IQM_Vis.metrics.non_perceptual + :members: + :undoc-members: + :show-inheritance: + +IQM\_Vis.metrics.perceptual\_DL module +-------------------------------------- + +.. automodule:: IQM_Vis.metrics.perceptual_DL + :members: + :undoc-members: + :show-inheritance: + +IQM\_Vis.metrics.perceptual\_trad module +---------------------------------------- + +.. automodule:: IQM_Vis.metrics.perceptual_trad :members: :undoc-members: :show-inheritance: diff --git a/docs/_build/doctrees/IQM_Vis.metrics.doctree b/docs/_build/doctrees/IQM_Vis.metrics.doctree index 019a6c584920eb433e6aa66f6e173490a8102ef6..0d6ff8aa773778c5cbbdfa093c6ef847b8e5dbda 100644 GIT binary patch literal 111988 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 ZDXmi)r_@f-$YAY(h=Mi$vS55?3;>fjZ@2&e delta 321 zcmbPri}l4#R+a|VsSF!gVvjJIPhS5var5CL{)|9o<3_K^vB&Cxth>kFahp%cV2_=W zA=blazWLhm^=yn;liSWk^J}=IrX`lgS7`N&xb0%dEZ4py~z_^@K04?l;WIvC5HhFCg=Ya-x|vJPm57~dWbfo z3Zv!Zb#Ifl-_d4_XPmru1_y6)er`cgYH@L9ex9x6$^9hi-U0R><1{-7f^e?82CCruvU=M6>Fk=MzAZdEE1!FuvP!P%45J8Ym9ZSY{ F#sDqUcN_o! diff --git a/docs/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle index 247cf8baf93eb9918536c975a25087b0d314895e..366c666562092238179412fcd19f67c5953e3b0d 100644 GIT binary patch delta 81888 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

h=r{5nI<$&t@Mk3vDBZ=;3&(XfN8b5`d zbwgo=l4C`ZJx5Z;fFZT29D3&>5*JvXf$mvEB0JW{ld`gM;p13YSwaH#mc)z+bk~g} z>N0eh(3mb0hA>?^IqEWDh;v<%#w*GUvQGhqY2AonAf=`ama7N7XAy~-VlN0Y7!nIL zJhwCtgm!9zQ0JQVph=5J!f1QxO^{exlAl$2V}5zoxCvv%+toul)7RHtBHg}-gvWGi zSWWuHA`-)!a9h?K{k8uviT|jxx(&9*7<*7{L};p{!6PP2q%i154YXr&W_CLUmT-by zF}T_LIALqR>~`GrWEBbH-8YH;TSa1xDm8lCh;h!8nqrqt5@TzsQk=V9TVP{AJTrQr zPCEP7o7L^m?6Hop-tb*ACS=h|OGu2L0~ftuBf)JQz$DRXcX{t?fR1Nu>u38eZ*KZYkrR%>KW}}6)*J9?+tzS&$!js1>Y(2}@ zy|?gn?=5Ui61jvF^HO%Fdu^l*eR2uRR14`}OUPu7cc!sRNL#wtMsOMNf{j?=)^;f= zgInEFbz#qCE|`lUU@Po14>(`7kqnunaaM zLA6_%7r5+JvW(|9gyzhVLTJm|U|qx}=S;qEO(`#}%&Da5{{bcamy@n$<|rgDpj(%d zQFPCFa8fobXN%oOmNTE#yn?M$VG$ofpSTqq1N^THP#g*K}3VHA@QpxSshi<$Z6rFW9nFU-g-OZLM9jeJo*%18f8g%0k}aB8`*>#+_*+k{WL7${lH3gBY4?!1Y9<55xCPUr z_pmi!-&JG|U$=BE&#x%FIiLEkfC7T}V0wHNTS)oVkR>2tWeuwf@CYNR-)hp8udR}2 z=g`g%kYsxEYS<)SNFQ6RHpYI`X9MX#&#%F1TSJEM+%qrXQ7?LU4e0^td}X#k zT`UtTXBB1rGRH)s-Gf zv;Tn&g}2tKBKy*sI*^u8$IQOHPIZ#gY3z+s1RX+29v7NUcl`@P&|3gNW{LN*{&MfV z&;b|Hi}$kSP|1C4ZF?S8A^=*~G4S(s>fS|nx@|SIMn59?(DV0$TDJSuHDDUIi%P6Xo`&3HdZY9P`22Vv#Dkj6a3n#YERNF8S$1pmuailR6CmlOc`<^M9S0S~jr zy!~Njd%s7>jhs1+?pP{?Q_G{UJb&*I(i>8kA0{TPU- zqWd2s3xfE@ZdFyaWUXLtsZI@}qaP=&CAiOjoGgz(hC8dQ32+!L6^^8&P`eNT|!7CL+hJ^2Jl)pITjqZbYk3+=syw9|7gr$t*x zA3bsheQFCCphxbi+e+GW*NI;V?vynb)VQ;2I`tDYeu1D6<*$R_&CHj)&slmC!jH|iThl6(}kST>K) z?%T-(y@2&0|f6y=JNOnTy>FuLwjXg3R6k=At1QzS$$@FV)b z(_{c0HOnnf4i#q@TSaRQT$)$@FbsnY09*jv`aUt{U| z(_=A`w;ukE8_hDy-rhgb{AXd;Sl3L>(ml_TX?o-WZMBE8@^2#O+uXlOlh1jMwAS0USvXz&9O4pQ4r0)x`Te|55VpoMB^n-&)>rDLU_rRb}7fzRb1hn^Fg!#TxTgg*T zi=_SD=d_lz=0#%HTB0=-aSJ`vuDix*Bg6NdoMO-j}9e)v<&#KDBSpX(C}8yEFp@?n^iAC1HBK zhtPwsgFL7^M)RQk_YqT2L3vKu+**BW9nR~~j?b=-jiQgerV85FL9(lkF^Uzw>0ob# zOuG3kaAyA6N0Rh9P2@VQ-w!qWzrMuZSFgxqeKkF?A6ka4|4s|1Nl!wDU~2xcpS0AA zohe#Pdp(@ZmALa2(nb&G(hG;de?0IC3D!?kbHdpqN1@jS(-$G8=4WT7Le_bsXxghJ zQZKEDTPHf5MA((4G@O#H#1c7aL{f21VTqlra(!0+3?e?hcH}DR_nMgZS)*E@n5O+} zB#;&**|(}is6kJ?v6cY)HZWGF*TBv{WV+k6=ViRDk9(c8)|X>BHos2vTr&7;C)&H4 z?Nz!1E3Utu|1KfM7ZWw7W8NTk^U+E==MDS8u7>s9mh{|U5^dLvW%~0Qq>Em99cnXJ zkKBh%eUKhm&+GBXJER3Y_aOC?+Z^Tc+>6B-nWo93+ukX)r)U;Fj z3v6El%!+ww+UKx99s54%BaqFAq`W{{)E$H$Wj!TteMYC*z|<0Gt@P@COOp=T=ko(j zaoy+vUk|&P?+n62^hwWSHAd6)L-q#vrS22hmYCjKvU68{#}R3mUZFpgE}Z;<{Y?K4 zSClUOfV2{2n|~aNwC@AbRWCt`pyWd`P%sTR0Zc!Db4QCmB<=K^o)L7@hop}l@{Yju zKq6f@nFQL6Q@#q}j3Xg{34tB`kBG0xbKEJ&vt~c!xn~M#Z6_!!0%zuyG;u14wj)>~ zXwJuEpkAAn5p>x>&?Y-gGSf|9dOa}~%K3@?WZPO%68MAktnDJ`eV>qMeXnRA!H4m; zKOyZSdFz>s>ySi_t817PnmL1{h#{V_q(soshskIq0|uqCj4gEUVbV@9!en~vD_DLf zy2F^~`>Ci*#@;J}4*Zmi(o5(Yfe!U}J(LzfPklksX~|%*;9#i-M$kQO@-lw5wznmlA{-21hsyQ6zHK+W{(sMLPpc*Ob?%phHiPd_A&=?mi)w42)+9ZF!R1pyydeZ70ciJ+ho0J4uT4$Q^XjDf_bCrIdB` zDH0RR+bEvDvfiV%QF`eVc;iP;k>-jZMqZ7UOI8{+Lu%Cod|@6%vr8eJZGxn(T^JYT z7GL-!iBML~3|^;COry(4D|PT@uale>9~q)hr(*rTrBZ4C??~88yO6EIhbQx_@2Pye+M^vK4ffGC)kk4T z52{J&h3`pNoINLt!|F5oFoOEO27}#uKM>EZ^?9`rfj-eEkVUnLMesd(PLYQXDYXRy)ZR~S)G^p z6rU$tCA5!^>Qy)$K{MVW5jGb&+9h9b0t;aKi6g@ALKbZX|Oa0o7;zi>N^Q@m3PhPqm`G5-go_C4Sc_LHGYi z!fm>wEZ(Wl?oVzk)mHHhm>JWG$fjP#KSE`-&Dq5;yTIollN@wVP(4UPdc?jm@wcm7CXl%b!&!8Gnq@L1mZQLH5x z9L8Zb_Z<8VqJv9+@bFT{^XWKFM~YmN&qCZ}`cFjNmty2-3!VQH>8rRZ42rX$?`xrd z-U6fUnV*QdreVZ37V2?^bkp<4Tj;Peq?aD*U_s}fi3p^AONp=Q`7s%Z7W&BgP5oXU&05Hwee!Qk#3e&H+$Q(PAY_Yy@tah^ohog;qAEI9)W(T`JU z+&Qr-VR*WQ7M>$R74;c3$U^s=6PxM`8mcpN@_7=ZctDIcLd}v9?6;Sp)b0l@6 zo^g%lMLc^Rwof3C+gx$wXVAodz|LQvC+Y?f;~vlRTe=0DiV-VFOVw>)#7Ue8Zcj^n z38yF}+<1X>7t)ttobI;^qS-J3vv?y*|5-FL2Ip|Owx3BS#oP?ewh^zk_Q-4WiZp|=iUA6b$Qe=tBjs*+Q`ZBdIDM0r3pi}sm*|Q%r^8w z9drhatcyiA`8c1QtF7^!WI~7FG?}=#K$Ie z*~)0=*7lP|=yUxU>iZzEtlcJc(8Ir3Fs5Yz8Ey6O9~Rt?ve1!4Qnvt^*uUulBB}9i zhFqkt6G`2)VF<)~w6>SMNQ%@8c8|o}jRAVd4A3^ntN%qPw$EZo-M(SMydvq_r(r;j zb&~>>sf*!05Kz}e)!Wm|N1%uJhr9cSslE&2^9R0a_q?3S9GY|yf^FxZzlNdfIj68F z-;OgVlHLQ&i*e8~w@9WscgaVuXJ{lnp=Sux6C)z2)m<8^hoT~B+V85s|G7(HdSXl@ zjr5Sz$(yO#Dw39XNa|)6gW5*Y10MF)P0*x9&}@^viX9{A%=f@rFl?J>)+5j%T0Y?B zYd>ZrK{?L@&qAmW0n>};TrWm2P%f#fNE2;e$0W4VKOc8R}NGR@n}@3rG3U2 zOVOy!9jF*O(Wth29mu$ctdZ~6sB9Mycak;gHx5+X$JD4H(Lybj7I*$MYB;CD+m-wU zOtt~2kz=&PY)=Vy`!s4h2P$soY1D2GRNQsbsD16Iwq{n`U(?8g?8wcmxRa()M>QTJ<9wiLoupGN)8fr<+yjrt=}ZM>&4*BVz!8u>3RF{9#Y zN2B`0h{naJxCYUvDGpS0<~3>$jXD#*YsB1kjXX_9Mk@NR8g-!q6@5L8`iBD*=Q)i! z2u3AkXkx=G40tgbSvw5phM$|jkq-{bJ?$g4!$WgNeWWPzF#Xd3K4(l_J?2g*oYiHj9U&^S+&neG^ zqY^Iy2;bUpD$;ubV~QOI{})9k(OXk!4~_PdHj}sLK0j$2oaig@momsoy2oD{NNVUM ze`&I55sZ=6MRZ1h)XirJ{>BSv(214>O0o3i0El@lLmV%F_d-05UJ8(6e3m1Q7r;9s z-kH9COfs3RcOc;oS{Nt|_qhvy;{}*n(Nl5o&hQ6;(scMZL1K`!*o5PIb*y{}VmogI zNrTBl)F)V)=8i)*%}Iu1EK7o=KGK|U`eLv&Mk)`d-XYRhvXM>?kuu3{x(#nH(MuuH zD5-r!U4Rru^IE|POIxTEYo?er4Wr3vpfMm3^kk^yXI_W!Iyi@xs=_H@Qkdxhgdd<8 zVbUP;Cj7lAjGpQbEQi9uKRlk}X7aT@f;e8FFk`VW9qCCpxJM&rx`hO?Ip=ZYzzc9p z&~aqP!T}~LW7&!cKw_lx-ZMY_xa)%r62ei?ZNQaIEXZrYE)e%e1$%Jz8;f8#}y z9@`q0IB=-X-_!agQr}d}13Jah>?}8LUb=UXh8Hd6&L>HfH!IfxBp#qA6R<2%Qb*Gv z1P)QsQkr4<2!DS>W1~SKJi^D597gmoJsvF$Vkh`GdIZrU$UD_^6n`JZ--GChr%3?k zIDzO1OgF{!CI0@BbHKs95KrsZhfLb|D$n< zyoUX$|8vBfm*OuZ{Y7^oX=y7758^OGHUkI23g`8*T1f*;ZusCv5A^0t5G76_UP?x5qTJkWrKvIivTGLJ;!9l%Xv(*n_ zKN{Ufm3HQ^n-5KI1BD1gQXnlBr2b#P88N182$Dj=>EoWoI$>LbMk*D85ba!4BBb6UW^=Jgt3^*f*S> zN{~jI)9@ip;q-40QT(FzQjmEd!UGi;&(iS*G6dlvbZ@e%JdpTNxkAfp09i(*A7`+ zjHJmr>*MJ;o@yGBrol%IRQ>Vn98K#4ZEz-%X7c7qGhTt+UsjZCgtMVFb&~pi&$wHF~(eq2pow6Io(WE_)x`5 z>fc%NrLhBGmPt;MOr`}$TEI)fNb{1UNb@2@7b)@(t{X@^g7R-|}oI;V~4m9{M(_Q%cE}bB8 zY87WY`HTb)RcN&)Izk^|9-#6af!)%q2CeyPiQXg|2{;tz&kkwggX}%BP z`&dI{ih0n-J4k(ehjkckS6dSCJR1YGK7j-^>qpCO6MAb(Nw`FCg#&Z34>1{;crdzv7y-e@n@At5O4e>dMzwrVk?m#>Dk~*li_z)?00m@jUbfNw|ByTz< z$ODGsPml@+(Bh(@jX*YGNQ^aohVW-No&fg&2oM}U06Py$d%ytn1(LqNT4y9PJrLvp z)AMnJkF#-95tJU_5zb9{3TdaXnv^7PFwNg|8qw1VdQk1Q-y-_0lJh|rrTuzIA?63zWMioF5P z{4wP`kO(i;!zjzl;!kh+kc9Hy=7}^omiALO7~!*fKodFeA@SujZ=}KbH1H8Sv-4@x zFVq7@5nsgNcpAg;cp6P%cmU#XI!%*>N7T5iV59{{&<*{hk>)UbfMaRr`bk5~7JPuC zXiRmmlt0}u6@q$8`-8XK5@~QI4JJ@{M=uRp2A)ad5@V4DN77F9mxh^J;{zN<1C>UY z+u;M8K(nPuTO{9Bv{SlNXTr^a>b7{eESi3k4qg}T2UI7~%}3$u9i;=LkB?#Oz~b>C%u2r_N#qOZn!3_y9-EE)JHa;!(3ePwNnb;FK9a zMdso70O!l*50U2kjKT-JfZSm&3*F%O(DGKfAkAzu}VEJPjFOA<}ZVRBE1y4{*E; z)E-NJ9qs{sWi~=^yzJ6&us|+8IAwIxivHc^Y8_h-d0LR4okCYafOYs2? zh(Uqi9KCWtEXdbdjyPUG8Teer2x&a683k*tD#Y;u_#BRpgU?jJAj6Eg0Lgd(@;oJ3 zrbmpgbrBNq0)%W%D9wQLjf=*3G!JA+mmmjTfMc5A@bg)QI9>q10rAoFWHIrAZp@M` zNAhxdHbYwGa|iy$3$P~9%n8sL|DFU>=tElb zNU%I>p(p)qtd#DK8%cEYd=dno$nc}n$4UK7xO-IHlE#(62JONPCfa$T)ZgbJ{EZi2?1qf- z^xQbfiyr!ln7rA>*yG6YIC3Y^pC(HFK06S=3nWS9Nm3?(Kky9V&!8?z^sx#!ug<=E zW_=Oi7wM`=QkrQ${@zbNo+Ld>?xlC%AdQgT;-xurgY+NI&D_MXblFr0ZmyXuRnQAl zz}S&fq%h_9iSmsN_7OF9RIC119{3Rj&KS#I!mXv_Wv-hE zo>i3v#qPy5M0taB=SlL46mhr#*5Iq}gGcM6_0gp1KZ3wd$gs^g+%c)C}B!AE!v2;vKXoFBXE2BNtx4_yf>fZBv{uJIX$V zsqo@5l{f-cR#8%}80R#m!V9Dt$?|gi!p8BL;FsaiFmN!K;<}p1D@w{Mtf+*S7ns@3 zAQxVQ3hkXRJ1UOHx4`jmBD<)puuPSW2ehns5wcV4Wiw_+*?20;iWf-Lmldz0E)_dk zRa}u(QBhc|6af!aS@8l1hOh+nK0T2+T?+TPgnW1bKGs3nCO8T%DJp~iXu}MHC#I}; z0q%j$rJkBDh4|oMC@WrEOV#O$N1&{D5mM_F4!Ip|f`^@~-WHlR19rTUV5l$$AQE7q zV`hP85{wVQ7P@{GL?*-V0WXk6ce-jeobEAaNw<;j=-pXTjTC92EwiP3sTcOcFnWJB zY`3Lil2i-5b2hjghq7VXYL^2Wb#VyCS!mxJDbuG7KHvq!_C&E=>H9g7x4Apw-7WNF zj+Eik0Uz)JOanMm$!sauoQOD_K7tI!nN#o~1yanG)=Q?=bV;rxn{ey9I)TpbVv3_Z z^Q2K8xZ7P#H{VJ^f-*l9Q7szr{GVMGUHU*aE zOYP|Tb0nw*+ZrE)EQ2gGZjLm=cPKvK1^9bw{IKL&4(=A59r81eMwZbKST2xyvJ*pG z%vglSGI*$YJU)!K(4qox1}EXeBny3@Q0hgaZzlo4R+jN}#PI@o_0aMPqbKLW&O^pr z$;&(oS!P-2thwN`=HNq)h3=Rujq%OH2fRSyJ`RaJX}?0r&$j?s@B%E|>#t!($GlO z=(-h4eNA`_$a)JsWrMkYW3gm0Ek$4{-CHb;Hr5!MDYSCyXjKy`yJkL z*;ES4z%|IRhQ42pF3NnV1wBzJMVjtK^xnEMX{hOb{CPjBsxZJ|9gArLq8sR@GBCqt z{JoiOypeMR)z!eem|Uy>A_*^${~(?}WYXUBDB_P|@~#vQ+|UE_VIBSiqE8?SS=|I{ zTRc$%t|=?vP9)+5M8S6v=Sw{Tlgf%pD;4rnNPY^-pDGU2_?fNGBK#~CZ>-Pr_!}=m z0^R!;?CUK3%;avi?m_AvEJZ54_!sf>X1VS~bT8dkA_*H z4n9EA2UxfXrjPOW$N0Mk^}AQ3{uJR)QT<`2&++%?PA&eJLsvlPhPO#TSZS@5D25m3gb&VeQtul!Z%38i(M9h)b^PPHi*7Q z>i68l_z@1(az7#d6ZQ2(`nIIo8gz*A;_N4=C z&~m0Omcq<<`o-$6u&3PuC#be9h5M0R#2%?$7~CmcR`8im&Hq@8RoY504H2dEP>@{0zSam7ESQU-jE6pxbQmahzxiE;k|hg@obCQ_L7i{ z7a(`#Lg(Hp%^+Xwe*ISI zZ9*>WUbS2rMFv-J5QgE_q0O+U(w3ExjvAliKVqStVH{serLq>SU?? z?gOi(YDrqwX7}`3X)b~H$zEG44e|_wpfm(!W$ITa#hdV{I*7*A!KZe|)k%GTtGZ6g zf!og}@WN=X;M1$>(;N82&f2^Q zzaZ&5D!`cEQ=hB{IQftOKH$K|3}C@_Jgox~J{2r@KnH-&1%O9#05~Q9j1mKILI4;g z2H=zcFgy&vR|3GeFaTc*0E5CdK)w|SMuh?R9s#zA_XGR_;EW2evYk_(tmirT7Xe`K z82En|0GPAOMUe1JFqT z7)1skNdOo%z8wy`qzDA##lX@<02nU@psN5dXbeDi0bslsfSv-tP%!|#1%UBl0Qw35 zL&X5}X8>#e7%&DTU9e!h7=VESz)&#&g9U&AVgQB;03*Wy3>N@Kh5;BU01OEOFj@c@ z2*&n5Mj#mf1z?;2Fz^e&cmZJW7l4TZz=$sZHwXa3yZ}rQ00wsfm?i)W>jE$X0UPUP z7|jJ_mSDjcE&$mAz&I`dvju?BTLAI|fDv2(<_G{ow*br)0ETY?unGWTwl+kH1cHHE z07?Xa(OLk?1c1?50Lle`VOanw1%MG*0B#fj24ewOAOH-&0&p_`Ha^Z^6c&)hf(7HR z04xyzMqU9}DgcbJ0&uGUFsKT^asgmq6@c3XfH747{v&{i;n4p8xl14zI|ZOx02na^ z;2r^BoD_f>0bqm_fHeZZC@BE70>J1f0CfVuh$sN}#)1900Wcy8$U4D-QBeTa3jkxG z0BjHdhCuSez#TS@JSGqfZ34>^0>D@%09yrs0Zjn5 z3jm{-0PGY1hB5(oQUDml1mI}_VE7V%XX9}EV_g7amVi7bSTIfrzzYJvU?l*11b}f$ z0A3aV1}g#BCjbmn0`Q6eFjfh`YXY!guo93r1cCud0NxS+h9&`cM*tX~1mHaZU}zG6 z_XU9QNdOKB0OOMYd?)}6O9Jq*O&}PL1mv&)FcJyCX9B?ZBLJTZ03(k892EeD8v!^j z0E{#Oa8dvmWCY+#6|g~Uks+s51Okc-_(lL2RD?9&2>=6$0Q?{T3?u^ZlK?P!2*6nZ zUuz11mF(=V5|^;zXX6mLIC~|07eG^xF`S& z2?EdzHtwX8fZ2ycN#Oa|boqeGK5=009Lx%uF2>?$I0}vwsj2{9JCjbl|0?=9j7%~K) ztpIEoHv}YJAQ(0TpuGSvTnIo%0bs}wfJ6aczz~3B0btM&fX)KIm>~eE0>EG)0Nrc? z!7w2pJp_QELI8RR03(F}^br7t2Lb3O01OcVkR|{O5CSkj02m|$V2}#fAV|oNAu0la zLIw;I07eWU%?JTtln{VX0>JPf02utR+06Z-Y95)K!Ne(O&00s(yW3d1*ObCFDwSQKW*En*kV8K8kuq+nuy@ z1mHgcz%U^IcL@N)gaA|v07HWS+#>)Rh6Mqs5eNna0azmd3V3CAPoc|%X*%-nSJS^ysaQfo{c!C4l1b}DVLF7&WU^ozf zrv!ijJpi5+07m2hcwPW_Y#sgoJp#cX8?d}A01Tl4uulLOE(72d0bno;fY$_oAuj;l z5CBHA0C-CP7^ni^9R@J}9|Kc>yeC*N`~<-J0>JPR0EYyCK_mb^6adDD0Qgt{826#xci05~oHjJp7EQUDls0pLpkVCV&a(*nTA3jp6B zz}^V>7JdQn0|GWgSoQxT=w~?nyZ|D(gkJ=JZw-Ki-vxm28UX$f07hy6_)7q7IPi}E zFieB%--`mlFb$+>)>>5*gERn00>D5G0PYB|c!mf30>D!RSV_FpC#yFn`w9SqI=~+w z02@Yi00|ZdzP12Bm;mri1pq7pz}OA|Q3Akl4gk>t7|MZI0bl?JI9dr{EC<@y1cLD! zU}+}+jNt%~AOMWp0MJ1I7^(rFlK?PW13;1hFj@mZiU2S+13(uQut6w>Azf9(TFim& z0>G#Yr0FRDjKl!Y8v(Y**#~|B&|d{uHKeOg)&ZP6SO6HW0sdjF(f?r*@Qn^YMhX@T z-2jjw01Vv#FirsYZW;g+1c31y0450l<2L|I761lu0GKL(+ie_~E)Wdb0Lx4PV3-Dg zECHD@d0QmyIhztM)0>EGl0EMm5|6&HfkPIO61PjJs04Np!MqmIa z6#xcb0GKZTjI{tzApi`q08k|W46XohlK^ZOT>)gFKrpHTz#;))Km~wX1b_h*09eyy zx?>y#fMtRM<0t^!CIAee0I)&;7&-yq4owI~OaQr4uwd8(fV%~N0TTdL3IL-f0IU)K zhDrcfEdUIR03Zth;~)U6RRJ4|eE>pLgvC4nxK98W>;T|?0bpPQfCmJC0Sy2)3IHP+ z0BjZjhA#kkNB|ha0KoRJKrm_n$fE+l&;?B-_$4T@0|Rn0RG~@zXG_(0n!G9<+#B`f?rT54;5e% z%{F|TjdV{=_f`Q$_fem$zMLE&fItp}2q2UL5dyGqprrt!IS?m+R&Bukpj2CdwBs!8 z1<-*5i2_LCKxYAT;XpS5bmu@X1ah%xy*bcN1z6G2*pm(E>6|`DrCSGcV3+`gb6}JJ zMsr}S0LF1(0s?s`bRq{Ps{qS%s`_M|#>uvs0-42;90APcKt2NbC~^)53RQrKoToln zi#WMd0A(Dg5I`jdZW6!(tbeG0MFLsO0oE?&V5Unsa2s+Uz%pH-K3Q+)49JS2esa^O(`JVp;cDUBriXxvj$ zG}%wnpORw9UYdhXuhOMYNipPgy6Gt?j=V`&CVjd)pzmnnF$_Qq>5UdH34058+=G6^rU z@REm@GPu;tt~Tct;fEUFL|jI@-4maY^4h_F4uAd&sT173`2q~Fj`|!0v#g`ZN1?py z==h^jf4HqaD#gR?d44-}RB8)P=3`*aM`^obQX8^v_o!oVatqK^r=|Fab&%btfKh=E znDrV|RG2$&bk6L2IPLi;J$Ralzi?U#hqPW_OAnG2ySIHU6@>e!A54P}+rfXn9NX8e zVIwf@jQdi*LaMPaahQf`jSFC@B;OkIZoEXYK_=99f^iUT3pHqAd5=cc^ZfL#xvKaqcS#AmNbRo;FJKPeo-Fm<+JDUl)E87k2 z^?0^h7XXiDyY+@!SPsj4SPlbk&T;Etc@*=>lQPywP|D^NrR9}bMQ}tCmiW702DVB_ zb>R~?tgG^+F_Q>^23a_Zcocu4ayB&lCw^dz?C(V7~qFT|rn+t?<7#I))0q-kRBo%t4p z({t>pe>i;i-kG^`@9)m{&A`kZ*e=IY*e*v`*KQqwyxr|mt=UNYLOmsRSTm(Fo$qUS+-pO#aCKS-BfqM{ zif9sBJLDh^bXdpYQ&)#HXX*uOj&!s$-{PEQ5udhO6XkJ1OI3^b`2}lMf>f&9g4RQ& zSTG$zt9b8%bqHeg;svWV9^31T)yWz+Vs&y>Mx36aYWCNhF*F>u#IrKcfEI5x%Hs6t zT8ni%79SVOntw0W z37zpJI>EA_L?@e9l}O@~B|2I8-4dN(*;S%v$v|>W)SM-xR%nf<+Uxez)>0sibm@pY zqtvC34O8fk;UiFoK&jN>@I2YpSM#ugRuNr_-EB1{m+F7kuu@u?p7I)XZv#?hu?S1NGy%*D2h(lGH0P(%Z3BU@w?7=xlt0gF&Q4-%8wk?I zs$zNsj8OdRn)3(ZYw@zv$0LBkr%e@?Pz;}Jk+PT&2^k7!g%;;ba_J!98E+xmZi<9_ z6M`1!JYqS7mXFCR@OV`m@^3^+?T1InAr(gfg?&>L5bR%yl06@fl0E;RMAD*R%peJ$ zOBUy6)L_VRU&UfC{bh2isEvl9$`^mNIJ<}&>Z^AzS`zS3Sc;dTr4fD~4LNF-2(dat z#mQ($7Hf`aVc2JS43Hn3G1RrOGzPvTg-WMNt3IxZSEgbst>V~Jpa{4&RgNHG8aP5p zFJ8_o#DYQ?BCljdf#uVrXZE51KAo5*2ld@F*5zSw)TNt$gF+GXw!=i+ z?#jTD3NQXWIL%yqgyNy;+%f>&eoqbl!F!8QI~~5DH^d`FkfkQ_fqW1)lOfi1Vj?kA zut;j%RRrS|e;7|g{%|pcGPB-szlA(Iw-_=MH;X%vJ5;n?(vredU+65vQZXc>9gm|R z%3m)Ahms%9C!jpuFj#{pJUj82j0&5H{2qkkeitNYt;S;|;L@?ynTMcAf2}{BFgf|T zrBWwM*6@_NXmI}>ffI~!_3gRPk$a+kql`jwENEhB*TuRvh^) zBt}wx)cP>H`7ad{?%*7iDh{52Nm#U`W>T*ZmwcM_r~t*)9NLM6eb?l11uNFE=Bq9&(TBV%|WHIjjq%vLfa zCEUCQxmPnT{(x9_31X8Zq95X3tg4fsS#<{YitU{kwoRQ7s{Fo`*AXc>Q&w5QH)56W zp3^QeldMv{l2{FB1@Y!(xK~WL0z<`9S76MH+u>tb^XA)Jg`6>GUQ`f4uB(=|}jv^X%wHVi}rWWEna6atJJM+gju4#INNhr5nKzD1ln4KIqn9fjdy<4178 zDE}CCXa>S8QZvPdegele1I3~>)P+|MC&~fjESZ;oSnD5hxtek#bb8R*W2JO_4x02*56pYA5O{cFtK~Eih))9 zn$h(J46=&7cUz-{egK-)PtP2HN<%jwUK0arHRp zAyDC6WOs|17hy|vn4Cev&5M+K;VGUcp`U}Sn;1X{B=f1r($y8t5=}Nqi8Ax`_QjKn z&&Gw|6^Lt+@jQn=i`CB|?Jfe^sm(N@6&r-0j=JoBVCk)nxV3 z^&oF2U5SOiosr7EEJ;yr*>APC&hK5~4piXLE~(uGe%YK-zP$|hi_$BQGO6MAs6}K) z_CYox`H1<#d{|t&51^@!K%ZRacJsZ1bF;&a^P|H~v!uh`YvK$0udweEL&28FL)4Va zqU^BWO;)&V19-aAR7B1f4!aC>vFCG$Gi-l>*Fb&0g-U$Hi|t?GeWTKH$vg{99V6DQ z(PE>OF&*@gNAt5uHtb)*v-GWfD3K-4mbL8iI}pq>dy+JXSCP-u$v8==;royh(sQ&= z5?|!kkr+g14|qjR5=)9F31_0_9EPi#9;k}>NsQJjxIYI1c)#Huo6!wnA$R5VZ0Mq(h%VPH$AEmP_tCnNnLjj0WPr%S7({%oZ zn%b3iPrcn=E8pqz+uJ?~A9LzF{)#}2EHXxo9p|vi|3+s@Ie)-c??t(vc^Yu|9=}@> zGHzjJ$fg|jTt!Q@D+!Zo$;}aYxs29&u3Sbdm&RO{oht1$n5W=KF@M${wQVEMT;P|FM82U=d%) zHd)dVjTZ{ppTL@zn`bm~7OBxsV#+v{Wwgy?b0aZnz*B+qA0;W}KrUdD!4T84}EGM0>w|14wn45?ospNp!5mIv@+O^@9Ap>Ok2 z9zd!UlQ84VAtt$5!VoFFmTy9O#KJn?;>u-y%mn7HtZyWdrEWGz8TdJV5JhxS#+-Ey z^OIt)n;j305AD~FLYxja;*kZ+3T-qmU_L$8zB*k(ywS6y!J9t8p69TO;?*!#jP$a_ z7TltH+RJ=c8aKSG&eDJ9wGDD9(@!j|WP{M&zo=waqj6YES4s12T*YX!;gwYqBqvu% zH-5j0(dJ0fYH5J{)htCu34fHYMSc4_YnM#(_!~X62siwznL8GRk8fcKYKJkEk3^}k zdQYQQt^a7yKW$;DgQZ=@NmSWXw&t4x6StCjV%AoMn>EJrt?cMDe4Kbn`uY)7tT-i= zefAU^t_(Pa=VMm`7JBO3bpC3YT<(esO6;doGRTLVmc_)=3>W!g!D*JR^l<%h!!nZPAR71ztQ?L9)_ZpyIKyb`Xy+Lkg)mfc{tUxS zo2SppxXC_?Mr{={&dQ-wpJlX9@XT2mOn*4bXiMP6StfVD&dI{1idE;N{=3depS+8O zgqd@v=G;v)m#v`|7yh^r<@eKZz82%Vb8I{<%|~=G+P#_AB~^N~i=s}5E;*n>U5s`l zy1Ph05!Wq?ySrKD2sz4Jo`)@mN>2tBR+$)8Mi0epmI}9`itXKuwh3SDmZLw_&C=A4 p#4KKi4MfNWs_FxNcZIKKO}mUY5>GaBD^KKpP3SXRU$ZF7e*nx7C*}YE delta 80200 zcmd2^cYG8@`*-$|yYxnSLMkOdDor{G9YP?XNeP661jwb5LK8TOQbS#EtSDAgK(Ju} z0oyAI0+!c?6cs57!fS8vd!CuyxxLF>$kIN){IPrceP*6{<~x0!+0C;*MVvel;WFQK zgZB=XrY%VjjV&NS?(6GZ^9w3!Yu3wtGs5NggjBk4iZL*-&UZ>tO-*t6l)UPi{HmIw z!u555v~n>CBzl7oSx_s2grbL^XvT7G>T^CmsO(G zJoMlh-(l8UC{J(t*SDXGMn$w$IPg%S<_&#^E|_8r8o&dTxWw4!lnWN#He8zz1Cv29w}aObZUsaFC|ib zBqdJ%I;EE!oYG7lp3<^waB^~rLTXB0UU7MGOh%eAA({{)2d0$f z&w`qULFAsPP3112`=3;AIX5*T!Y*WSS^kuwY7AM|MPA!6S>D#xTRxf+CeKKXlVj5& zDVI)aDnHDRzYU@L+F@~iikoFkDFTY?CH*GXGP2SQjRzBM{RvywW zT7IW(Gr0`z9_`}fgY6>aHtpi&x^^-0*>>GXxO}pG6Re-ynrM8Kx3>3@)4Ft*H+ECbq#W>=Iy>(uI*Yvn#m`-M$3

ww>(Q?~vL2^tt&vo5A($|=SnI>~MzcuBzIDTuvZ&L*$?M?GnHJ%x}N4TdnzbxSRigOKpMq4*cDK4IN67z}$sBTNJY7OfJ`#9M;f= zlJiPOcG{=M@Z^H7Gr2KWN$!>OWDmx03^FY5OK)1lX^p?mgvVYb;RjZ=fPCJU5zX_N zcAd$MyGnB7H@1P~2J~vilk0h%$zgkMs1y(PY6Z#t)hmuCmvx=VVHeR*a`SsPB5egYMYQ}XMHPL}lp4$E^bbnLMhi`x0@5T&Q=3Cr=yRXxLda@z1 z4}o$+)^ve3-|< z+ssB_99PY3aKwSm%tk95gUoCo!Qp|;>CD)3vl*HhJ5Mv~0kJPLvknP65HsrquqB&W zbHt_u6R=FUVl6kbs)`lQ%xVwT2{S8LEG{$S99d&?bTi9Mol8vxtgCP`GZO9pN>0xV zPr*^z+P1%fr#ko2;_8~b;+mqe_40bVDU`e{vxBc)9Qj~oXt6EEdQMzC-G;L(FGAy_DN?o~yTi>ivsC#mx`Pd&Oo!}#@l-X?F#476}_ zT$u{<6`;>9_bhyZ*#!bPmUuXkn0=iI7*n3ZYYSldDgUwBr!Nv&rvNw~Rog%sv#OC3 zQXnZwPMz*&VKp}fqVlXI>rtX%$J|n=Xv0)EWykCW@;Vb#wVJA;qVDx;5YyVYX|??9 zke9;8V#>LAnShsxcqzb3p*(wN3He?Ae&|r%Q4Iw2TBhuEo&~j~rA0M)Snrh{hv%}W zadsLk)_SCEJ)H9dW|q@RW4^{Z;{kO>-Aa)kDs}6_DvlQA$uHBx3ad90XZhOKo5gyR zIIcH~^r*0Cbu5IKH*xpGu;~GA zR&~R!-FzEP=U8u)Y}7H(L6wM*kBttpuM%zaDAAH&?U53g3a3*6+lf*-=&(*SuVK)W zSC)o48|1R|WQH-aZAyUbV4xeMN0DPz`s-2Qq@ncT%sQKBUhAA8PW00w2PRLdt*)t% z2aF4c-e%IcR=l^FrpI_eWa&%(bZ9&YsNYwY>(S?!&yvQgusCb+H;K=9EuTd*D`l_o zO@YnU<6Cn!H#FXK)^|t9SS=sk;!j^~1#Buy6SH;bTc<~%V>(wiT1DylTS%w8Zvt-R zoShKEse852W`dQXB2LX~YTwVjtVfY!%3jc;qFAfLI$O92HBc^_h?H%Zs8IH`9y2wR z1zNa|t$ua;QjbP$zO7@#XN^!{F*|ak+*Izs*g7$5m0J{q0+Brnl*uYF=^bCO+3qTc zu&;ZU8)1%9At&48F3a9h? zo6%y+i_kr_p(vWOHn8z#YC5@7OZ};L4sowP+V<0<&oOho8?WM4kGA33(RN00q1M>Q&R#Fvf zPunm(iX786RF8@V>)+LeDVDyok&gGQS5wjONViWk<(|C_%Sc}H1si4!KJRl+MHN9I@`^n zp88I%LdS3o$TCfQ3;vyJ&7O6l$+Oo`^RvK#(}s6O9_JL@$RQlcqE7K5%lDRgJKJ&p zMGpb2k~r9HzobWr<4STtj|wM!=}lrWQjFzlJ(A022l8{VD9e>6&JJtG>r<$^o~aSG zx#f@f%d6+P)A{F!OZ}aIAU*mVGaJx&6;5{oZW6P2;F6szO6JVUF>}z1(REHsK1b@- zc++7gfc0QIkxdU8HJun8?7Mf?qtG#(9UHB};&k8rCeayXOQ(EdZWyp>Sr9@^<0NmT zhE8m>{kS2YGjFK>PV)uZCpHg>BkNHq41mI$EnHH+d5x=WAotWx%#-_oAM z1$vY?CUKq~6;3AYH=!cR2j_;!#S4O1&1=rv@n$`y0%iTF-+AKdp#46fN0DRN9&NM= z=YF%BLEDkLLg?yQ#7$0IMedx$1C2JEH{2u{+_`LMLA4IZ+^l?m|34jsJNP^@+LHJFt*M&i@h@& zGfAGi)Xn~YSf@tVEtU~%TsgHg(tcd&pht;g{@UtM(cs|R(3;4}lE}KO;w$N^sc3jt z<8D2R3N0JTt_FJp;8yKwz`J&QSEIGq)tIKIDCD#i^}Jx^dK730uc+KgcEL-byoGcUEo8qQ``LEzg?k-(xZc&H z$Z@rJi>YwhQf!Y=-sHW%GkUV4@DkwYO_Ni46glSQn}&J0?)|?`YX?ido^r+vv;78O zdu0PqZne(aqTTkp%~Qw3MVl+@_{4M7aO)GpHK>@ZzM*8c9*8>5nYoeMehr-%aly8_Mn_=Ett@=QSE>CUO_Z{32~+4OC`4eo8CPZ_dDpOr6iaM zm0gdY_2fn{Tk=u>?Ky|I(fNysNBw2VMLkNj3|WWN^Nm;G^swwrVA;{ja3Nkg=3j!s zWslW6#Sy4Skz?BY^{8;ti*wqp)&;Zlovr40&v7*s4foc*({se%#xF;#``)hJ@Iizx}H5SyI+O7oYH#H*Trth5lTR zBFFT8sz-$rFZ4~I*U_ZoiXKx%1?{;l+P?Mwqeqcr+Wyp|qQTaGwHX6Tzy4^?wN zcQq9aPdfVR$%>W@W$DPiUU#b|9q=hUKIteBla5Z_dgr3^Uvs#H+(C~bEfLl!d|RgC z|HH)N4n3J+jb;984quWOp+}KpR&w;HaMD&(=n$T5+%dQ{w6BCTT~C$hLq-v1&V2K??t<&y>v>oHysS^83Q zdmQUsF$lZEW zIGH}&gr+Tbdj$^=mA;}-c3O{_8p=ZG@y*1u{%+5Adh|JF?quUtINj~J8O%BG;CuS$ zA7R_rS2j02N*q(>sz*hGt@dg&CYHXlNf#gFucm^hZ>z()8=BJi(zjKiOuE>YDsR=K z3%>iyCta0d($z;#QLqMed{@1lo(w%o99M}ROoh`4*LC}*AK(4GUooU%F2PF~UMl4K z-zc~DR41dSy7L}i?xl9&v-7dcxJG^|Qky@kZ;0pbYIV(8UEx&~<+P)jr$_tvX|8ysqJqC{In);a$= zrot&fw#P=U-(_@uUzq0G$LIHj^R2O+dNQK0;V&1x8D`&4zo4#u#K~7 zTf3~4>zZD+Tk%$;hPoARHRaTOrN>-Bo$>8@hc`dhqsTFJpXyQJWQe;7)M2xX98g=9 zUmlZPR5hunvW9(JGUgrp@Q24camp6r6+PAqCSQIh&b|`D7GXwsQj`CK1yszF_*6(}$Ep_hk)vBI)=iFoTsB}zY(}qr>V?_}$%P||PU|A1J>!PRXY@&2#vLE7s+D+&KwfX}(= z#E6&Ma8WRe#fdd}+WvZ{iO1+spe4XM*o|T;>{$>b+~~n>;``zKSYz=TSPuWosjJCo~DZPdP9dh?*mbq;m-Sj^0BLj^_a_O zTYezQp0)?|C~-{NeR@>fLfY0GjOfqmoOkbvvNHIF^1$lqTJib!xAa)e*o*qG-e-XK z>QUmDz1@0LIGHH$N>{&AWht5)=u@rzGVc$rrb6kZoqWJ~xSp(N*--jr_J0`~Tnk%n z*co<6Ui>FJn}4}tzF+jy|J2J*L<9e`icNzi9j>=B`Lmvu29#)7v3AzKF%?cb>+4<| zCmiW1#romFZBNaY8{}h0+Sx3F1N?MMY_vJCRx_THt5q`=mu;6gS_c1ot%NGojQtaw z2CJF1mi4r*RIcq+3HXOPeE8ois?{JpG|D?Zt~dPm*P}pN4%QmghpBK{qi*!@f8>({ z%?Nhn6UCEItS2M#rf-wvF`w4+oln-I#4#I_^r&z$f=%R%-q3-6)qk66Xj}DP<#Vbl z^_UB^rO4i&h1(DO%k?O6OxqGYD$H6P*17yuXuGyX=l8i-nkoNBQJHD(&|@)HIE#Dy za8*UURoON@+O*lXw!>$c3g_)G%js(5nl?`Izkq+sBrvvE#EW`V+*%Twa1#3zS69N9v15i8&z5%`^~_?E^ZK%)E=p?+_t!Ds zV9aKG9ctgth3HY@nAt!*Dx3@tH=%mU8OLIwB4!*@zj@R{kDZLKqsQv;)m4uY$9#3t zqv96wb@Vv?x6h-;W0l^oK#!e_uO%m9?CV#a9wm@q}D^RQ%EvdXzY(ZN45APNpAMX_nVE{mA)NJ8jGPR++XvqsLz0ZJ>QsdrFT2$DBRR zR5+b)*v>Yt`y&FIzl$8eI(eU=HB*bKV#HL6yH!8XlOI-*I-jby1@oRBC5}mXM~@08 zBj=lXbZE`6u8n!wTy1UK@D>cO&sWpI(yxCUftL!Ok~&qPq~EZkfY0ik>fq@+QekC- zuTbl&P||N;Q_H%z$j~z-vM&^Hn6v*0YPVBx(;Nlxzi|85xX51?I|h*fdL}{{KREoT zYM34+S~9Gwm0+gAY42gXYk&nM{0Y~xT7md=MmBS_`&YIq$m?rYC;19ud9dI8lrw%v zvY6r(we^;Cot!9hsEdJ$3M)w+uBzhdpCN6_iN4W`8Bw`6|_+u>{Tefrs)${E2sV%K9KS0J3@Jltc*Df)hhawbKC2i zj*QBCe+{&+rjP4U;+VrtOoh`9@di()a(-$K>zACLnkws;_w;0dvGB`J_0GDyqeqEj z7T(mO!bxM@qeq9<4C{=67e@UV0}Czcvoe2h;=uPd6Y{0~Y{R?xuiHkB8XF~&VHm+P#dzBCLPvI_(x5b3TyNR9&3;sjRZNEBvmB&Mm zB5k#>j>jgZ!f6}536mBvo@%FabpqvsLZZW*HF)fC+phs~`43+9{a7o9nsgm~Y@tVm zlO2e7&a<<+buBYMIqBD?4UPlZdhBKn+HJqKu;(vJj}pgqY>*xmw~)VGzo|zcvhquc z%csP^GCXGFKxKcmMvv7BdjWFh@Ab~!Ow*&tF@xoLR5%$!cnx&g^YUKXQO9fTym@DF zH5CnyAuf8dqGbckfX=%Ju!g&)C_hkqKu-oZ5dm`0-}U~P+kQQI924Ad{9Q>RfJ&u_{#R75R|h?Is#S5zm3khDwtDn9rYuE|iUzCV)kYwezOx-%-d9{r zMZ<>Y6fRmJRDz%KL7oW+>@98jr0Dp~r7d!;BkMTut{A0{?QC?t`1Mpq{3u{FJIh zXG^5snWS<(inQ!mN4^q0DxB0M&Ysf};FZWx0Vp$($q=GZW3L6fG%?~_)7T3N>RjMM zE4F)+<`ZI8vata|{Oj#k(UWe(;WqdK4XCN7g)vlbhxcBl!YMH~cr2z-u0$P-@0glj z6H{Cr1F!D@RXvpfW4E3xAu&mGhbyV)NqbF?8pq7+)T6@5nDHWK_ePGzbc>P1`fM=X zMsCBux$6_mClFIN(oX6zn-e(HMCxs&9n+)6F@ay{QQ@T3-vk1&amEj*m=RM`5z~8W zMMZTHRzbRTlhlOHaU*Un*#7DLo1_*>PwE<^V-ACijNP09lCiBV-Bl8-&P`=Z{ zyNj!-Xm~i@peHL@Hk6(`3NWV~7F$K#xX;4UzdcBNcdQZS3!?Y#VON|NK>|CG|Kqn` z`0Y1-`@==f9~DlbmEbwl*j1MvOhf6u-Gz!yOodZ6Zglru;zh#fWpCmJ za}D?%-j3yCysmt3KIq3@M49PZ2^p(PkwZf6(4)e_%19yAAV?j-NxhN1HWYVVU`}m* zX>koWf2J43WR&NZ&Z2*L6R)9c2~}TMU95VD7U;>7THhAD)`TwdAtAgkvT{66mokSO z->FAM@h#(+Zuce4t!K>fu?4T7Pv|jNA&@rnBOUC?dsLSqhvYr1N5!>O&}*KvdJeCs zg%_z~dRG({u@{L3vFQa?UK2wXb;e3~GrAo9+iMiv7(hBm7lUX@Ac>$C14xm1eyOJte z-h`y(v;PpG%p^{7E48*{VEt%~&)o>}C#%F5f|&p@$!ng1ofOMTWHJhR;KW z3alTiX*lo7Op9D@LVpb-%FBz^Zsty1$}}Wcr&}}isA#bBwl9oEl!diC`K<41Dn_d_ zP)$~><=KJtMUACaqvEm)oftuS!?*1pk02vS6#XlLWLm~zPm_z633!=^mjb*L!llTJ z|H>Vv$e+OfPRnQi-w7Uk;ltwjX8dT>cv!^Rf6xfNi%?|7w`d_`ES!DJH{-k?Lte!G z%nM4w+!8On@M0Mc*P_}wzsbd=Mb&vV6?s)f1+~Sch3q&J8n+r^jsy*Bn3dKiG}ros zcH!Y9n(8uqOw>l1#o$@)}b^MtuY z8D@SB%Pl^kMQd2LtxuSL{sdp{TEm!NkMvMeQcTX#&QW9lsi6y_$oA%+Ax%l3#QZt@ zlGiKmh2jK$i1{c$L(E?X(>tO`yH>~9(+PIP;cJNbB>Y}x{syj48sD)SIQK5m7oy3} z#7LitAw%Kzdkh%^x13l4|0tQh7fU9=ZT=!yGI+%jPnsP^a)?9^-$jDx&N$ewl<0{# z(h+XyivdcEC*2@?aXgE5FrL)FQ?F)Z5!~KwMv5R@VskPaRW>ITaJ$%?+-Ed~z_>F6 z6iK1sv|PGd<7Xv>T`+LkN< zu&^C@3T|HQ$%Alvx;;y&YX>sfC}GaSXj*g9gud2+wDMwlTjvr;w{|4C9Oy$UKQqMA)Z57v4s@r7_87wH&fCdE4s@nz$x;w<>q{s0 zAt7{LItizT-z33Sa@KSr(|G7^H1-Qa7>(&n@*v^)oynbW`=>K0=HlM;@GFp9T^CZM zYJcu+DEp+TFoWsQiL|HNyAdCnnku<@tJGsQyVDbALG9A6Bp>vh>q<)0=ny`LR(2!f z0spWYsfAmg?xdQFhtk#O3~lHc007VJL8f7-9%L@u2KOX0c&IKkIvxHQ$MK$I0^mK; zRlGA@u)rmV9!_VIUd)oIy+{>2ebtL;&g#vAyxyCck=BPS;tBMi zM>_UE`j$9Ah{qNKY$suX8<%5P%==ZpbMS?!W8%B>9(hrJ_bc6a>y_rR-?O5 zhgEZ7eoYZQIUcItieVrv8%Fx7!6yc|2GN7VNH%I4&M00moQ&Y&4s?Mhh%XK&!@QZc z<}->5rxevF4P?M@;!P_?ka!+?&^;qbGrDU8sRUg~BUxM9Gm=%8?xPr6J4UfirTZPM zz@Ou{*wHM=!=qXLBF3;A9mDb-HkMRy<=yF}FI~c@PcCUe4~`{WAqn?!tfpATF>RN| zF*OyrWCqAi=dvy)e>|&iAB<xYk&SRWk$x|zCS9&rWGCgc0NucA$ zz*Kz5F=C=eCz4>$`}0KBc}~g)O%nYqpLFAuu?5{%Lz>DL%ROj%0ZD<7l?5y#KNhgQ za`q(Ft6!SL(wtJrc=)-HPzbrAh-`pc>}2v7&+AZnUwLhcGBOxJ86v2+S}9EkQY@&p5XOsP#HUx zUQHKFBVDLRH5;%dRI{pdv6_4U#_XzrW++kLTGF3uZ9$`F0w?ooNlU=@&4M{q)9FxR zAJmf8ki7qFSW*Fy0>Z56tP{9zIvLC3cBk1hNGSc^3ZQ%S4B}5a%^;m1(zF?57%$j( z>USrENS_Hq@Q*XtfDk?t`V6Kliv3e`djCw;#XzK%9QbJ_X#pYFz#MZY{DYxYvxqzG zHjA|3$+qDp!#@E}<0cQ~hK}NCMzb{KiA&t*%Go4=$7#jmd_5a%kf`UKkbTw-^1!t6 zPSP20pe2azfh0}LfmRnmQ|FM70QR6A5}MPr`6MP4@mA~W!r`6=j?iR<{$#|H`wSdD zV)%M(tYn&FA(0+dDNXA|nmCA+oR>EVKJAp3XA`~o;Ov3f!};JEy@0qioIDF`6JMJ= zSB1%YX^p0P7myHMjpMU2`dZUsS%R#FI?O5rwMi+FWwbBLD9B>o!HQlc3nu~+M*uF0RAUM2N@WiH+=ZOEE^6|83%)u z^qJhsL-U5zIOd`mja@{dQxrSG94Z(xIJ=LH5lPGlKV}396$@zoToTB9#Ps+g63l0c z&4$^q-Ec}6)@e#8te?`pc_f&(#b&g}!mDMa9-rE*pir9tvo#q}$K16o%P%R)D=Dff zFDlKeC@iG@GoZ&>xs14VQTS};kWag4b{YP99!W4jJeqMg35sAGSCkj!RZK6c%F7-; zWS9s}*UTlctP@GL2|zE+ArY=DBJHu=HAJ1$vYA(R=+k`eW;2Rucay2`^yS@b9Rl5A z4(BnERZaZ&YwmR8GU&KZEGE7X@Zw@N;7nM;rV@viu)(F}QZfZ(tCtcp-2Ph1WF^bU zM0h%|jEvRxeyGxg4p`25{h71Tt%gBhPo-p}Kh%+A6B{g3X3_;KNhVFImfY0r8|j@Z znOR3ysw<5+I(IpVkW;sqsCgAh1e571wnXz<%_gA5s~JNdttORxButxBQC?G(Urp17 z!?X=j4x)FiA&G7*(Zs2>^wJ6v$Mk)^hK+NEwM^g4wV+6%C)W~XM%a!%@`)5kd#od) z)dAzf`$(|7=LHYCYaJW7POW2e^xiTv`f-`maDuwhHK$yH>4O_!TpPC@)|y7TZapc5 z+m-cX4&3H!fXOI4ZD6xd#^5oWcvz^>i!Qr|wB~xc(Zlx`1L?tgSUIFnmeqSHnF&Gt z?uZepUwa0-p?w~5BC!bfF%#8bG!C*)e|tUNu4Ko(rx#XRBv2dTB~`^gRE}t zdXU`9jme-p_8G%z%|q&nYX|}@sc|Ez;vxD`KcgXrZrrFY(z?<7*Nwq6{$Y~GLv*D_ zjzR7p1OROL=V3;fw1Hn9ZDHmUkM(8$NZz>AMU^Y(p|v{N~`ct2^)(WXP8u{`K1 z`O}!kV8U{7k>o*lKT1qIWEWcb0L+jf{t!s4=VNTP`rKoz<%B%0E;o8orticPFn{0m z1o5DU9w*pby`NxBWZ4sJM*a5_Y-T*=Nj7Kw`bn~cr_r6KvF0gtnb3)|3P2bwi34@p zpM)9Skj=ykbdKB1Dx_LSFduvxLY&>qDsAA?q@36Hb};G8!@h_-Lz3z4r%5uz{qbos zTP1P(&p_h*XBdemo*`>MJndPsP$ek+H>fmzTSx&12GJwSrFiO1knfq(f;%ejz=won+C{ZR)_1!oVIoNPl|4Pja_eTX&(C z1{ebAzuU-oo={J^z#n!~Wr0gUoEg zH|T0>>m+kE+jsjun8rR&;w8BEd!F1CfdQ7)niJrbc^d?)oTUVVec)YhLYn_R5B;4B zO?rX!^g0`U+iiTy&g@1rUW8S`>QABK9E~AOyv-V+Cw=J!(#~6h_=M2dW3Wl#`yy$f zRpXCpx@toPhR|)lK$)B3V3o863f@PnIV6P6KLC0zzDV3VYV?Q0mW25nn76EE{etz@ zPw#2tHsxVx%1fkK1dlrkH{W7y<2Iuwn?d>?yhJ>G)+_N@xMuW`mq@x|D??g>H6H;B zNK{RY5en@LTya9<7|ZAAjq0%2Ji5JLBU17>Y~m9*1_&*b6fR~T&6450&GBX?*6 z=Aapav{sJ*t3Lv(V_qk1v?1@{2483)*%&;QZhf8f(JB}pLMu*yO_9mub{k_SD&#1FqO8nIp!DuQ) zl|!}KDo|Ut*6b>4zGGTHiaWAHR;tZFapi*2#f8ZrwtL>sP}}>^9E>E=ikC(N1l!4U0Ri^!i|; zessbqgHap*HP#h3rK`G=IGd=uL+IL*kTq5S?ro(cZLGak>ip^1cS)dD_!i@@4c*&T z3fJQAYE1>9E3Nwv3D8!u{n&V;cuipeO4~_Iv?>nNQ?aL=WW&cHZ3w>%V#~)zA#^oX z1(qq0y3+0KVXl4XJz~-(^Ql^_@7WgX=dihswY6?P@e3)e$g3=^sDU#;njZWsEirpx z>%fN7V@h*7w4Wqv(>tj(>#Gj7Ir>gphL-n9ur}strI*(|3%Trz38?Nh+C*8XFqFOIwk!`q>akoSSz;~_x@DaI{E?B+n;WiY#RPQ zV8Q_suT9~KO$s^v?NWf*$3=ITPF+4gnrn@Ar6~tVFD>Fm=N=@Tw1_9&caU_^666z# zQ;?>#VxV2U_YbApUI&5KAy^0u?ETS*f`+4P7WKTJAm1%Fa^@Wc}l2&mBSKRGm(nLEi>Z2H(|FLcG{vwk> z+KM!Y2j|m2dO3$Ag=o#m0&$(|q|*HAYP#tQSagHOBF4txY&zu=(p78NaF)`Bt&%(a z;1d$56^-IXm_8*@T6he?HiK#|4+xXwrdlrYLaEnI93PJoKX7j}w`o=dp)~0YsEsJ3 z6EmbZZ4yPa=Uc$H&nVK;Cel<^5tBffiEfN=wVBP7(AIB5oYc=qiq?qoP(BvEdKA2p zdwbdTK-09s`J-X8*>5y72`#5J!jusD>Nyu*+qv=#x)u#RKbo|#i8Wi`&>M^)zBaj- ztJD!RiDd;sxY5@mT|Kpi&kv;&+@U62{2C0O^#$?Q610fsyb0+tX8TGubL7R?Yj6>L zCCt@k09&Tb@8{#}CU12jt9~>)mxS0Dy;^CG7r(TfYphe+Fe}H0`bjpO_=ZqEi&*`Y z?QnB1FGt$7zwIdafP$~E!#7&>G@)PhmwdEbY!Vr^>GB`P4v6s(>1R8XJ*8wN`)k{t zY56e{rETjkD{Xz_G15wD)OX;z>@}N4 zy}f|6SBYoh-Jtw9QDT;-j5jIC((?a;ea5rg z)fO+{y$B!qhIA8%_h*2#`Bp4%n8hbU>6~xL1Z@J}h0@dClCdJ*WsH~i9T_B$?9Tx? zeuAXX@ukGiO=-z@&`pSMKMF%v@+s0%%hyHZ3r4F`uuH4q>u063cAO%;v?lx(de8SH zUyJ++Mg2XQqJ{opM5NLar=bR>o+iG+zIk7Q9pg`vegZj+$iCBLh(Myh0wn1S87`0t zL^hrw1GI*F(*KeHnenBX`wzpf}hjxJWe8%yDXU#%%QT?=> zdq1@)O%0>_E|ai)tz$LW#>c4*UDD`ez~iQkSk9BN*e0WOV`@WBtDj86zD#Z88Y_1S z>sAM52Y%#$`@FNbBh)dWGc+dL^BV~*WF^3SmfFN-*GmlllX88hD@Jsj&|HTJF_)z_ zq4|wW2qQX9Xpvn)V_A-v>r$K0;zlN9>%i1%SQbW$e<5*51e`Lkb!OUBiaOT3aW3D= zre4_i9c^N)4r5DCZ=2xgj#QUotfj6CW4qB2N+=r*8z6hIBTZ9(6)PAP=U(2`%>7k# zatwZe!|(h`)CoU>H*&b^dFaXgeiOaZIP6{?s;a@+ZP*`ER6~ zGX64Xa~PjHyDfpvd-oFS<~ox;3)#W#?BL(Utd!x~!f2o0NoTF19bq_uRX6Tgs27#k z-~Ub$l|hB!J9!p1{smd+`Ui>7%3k9#pMODS`GbUNWxKg-Cv>gKD8bb2Rd_w|2T4@$ zTx8>I1&{hun8on_gwe@=l75Qu40=C|zWOH_q$I|mgBqR_{}O9aCOfQX&iPA}B*Q-z z8B^!i4F0cxBj~@7X>BrJa9NAL#X!ZP9OW<@lLxLQ0fA~wV$$PE`Vams7T*m2hR6Ef z-=fMe_!Ng9`WIH1+5d>meI`4@Wpn-!Ma1AAIQ-r}VpL@C1r9^$#A-8fiNizxCCOU& z7Y;+Z>b3+^@;irNTf&`Q_?LKT%j_>DXI_^{s#ev%IB++mk(EY2b-*2uWlX@q!@NB7 zgUc{^e)_VQS1_>)-FsQMQ5a&PbNVJzY36$z(* zJw;+{bFq+a{RIT8J*AdPKhGlE4ZE*<0RP%kQo9$1FU3lgNcTPoJ8V6^HmbWzOtu0> z?1NlaY!h~nLu>e|aCGe2G{&`@U#RE4^!R4tsV?o9w)IMF&+wMoYb~SUbfLGT?hCV^ z_j5f^mD02{Jj7wBIyPB&gu}CaBz2pXDS3>;tPje28YS%4>b0BFdnx0b;VJ%7do4F_h-6x8;e8y2JciTg0I>E- zp_=E9DqQ_53d}a4-shpd50Ly?Ya$<12Pn1*t2G~mXMA7xd&EzN)0iewn8gLW9#iK{ zoyWqMUE!bpnct5V2P^O-gH`HgC&e=iR;i~|%Dl{YlEEsCvXkOj1CUyjgg4lU(Xnfd z91|(bVye*@WR<4aNzsvGm749O=zXwCEz9i0xYutLud$Qj*1lC5-PG1B+&i>Na)zQH^vW&SY_FXBGdg5u+3* zNml7>=p2+Df~m$q#VUQrPI@q${tzNX;Q=qtP^m@q_wZ`qTzF5uG{2yzl$`;qbDL5G z-wG@&nhCFQ((F(v3Ey-Gm2UTI5d$f;#7hERTG4kvLt!)conW?=)p=!A6xNm&!ABcW z4<5R*3t>)!XiL^FUSF^TQm-z`ubMP+k;XVI)D(TQLDcC;!PP8@*4m0+lA>qc+$2KkB{dD9IfYUzof#o@@OFdl$BY+9swJ(6kYebU5t5J56LC*^Awue6 z^ugagG&xf0Z}i9C{`AgBsi!dze+SaNkuSCK24=sGKJpNRGI_pY7!+C7_slH zi={hSLHdiLq^@K+-4i9{xMR1-j{nOWCkE4$Xemv)5<&~2rJ?TF>($|jbotUG*w&Ah z+ColTVjvQBX$x(1=HuIwCH0PFUGivBres zWZ-=pf&#pNU>HvdV!6<*6^1aAIR~XVXjCtJVbtF^0)Y`oTpZF7L(^X;o}MiEJ5Y27 z4-4nY{7qvK7#l)M`>FPHuQb3B#PNvZ1(F}N<)yFxdH_h z+E~w~!Mc^lszPCvh5RVmuU(9UJ^pP-wp&-Cc%*q zC7UZzuo45sAs$43gs7%9h{6%E%Zbt;lZ+2=EDS2gDAPUo04Kl>VXcM;k?hzk93e+O%EarhrU+#;&FoLg-*mvsd^8i5KexrZ3}VOd9yZW z4IyskM-hkPUnjcrNWS!qxA0}H6j1mC%HRmt9;_Z<1Uq8oMrWNhc=?z&qYy7Z+W@*L zRl1$VoQC6%tW=*xA)E+f7OHR5`k1yM49CFKTrq_{^uk$#znggn3gIl+1F2G9(~I~3 zXTMYh!AdrEA`Yj%fUy+ofiF7o95&F`Q1}}5AB<$h+@9|eZ{EaqqZ}__@(47!6@`Oe zZB2U-ha+DqaX#$G7thICD1#GUz}pbhyZ8XdyqHzi6J9LK`%$)EX-kYO^@LZb=>W>$ zY?n129P0`(9YPombOD@c`UoH3{ML~kKz4R}sk!M>MBu0vqaTnkdf*3xyPNrQ#Nnvc zKBbcR(BIlaWBv+ZIG<(B1)k5M*&QUK=@`o3be2_C*Fg$1okaMgk|whm4rhg!zC##} zWigWRL>6xgrx8BQ+Z79Z@O{#hvvdwca3;%Iuy`g*X~pMJh!>ze4QYqBFK>sA;UeM} zS!3y7{0$#|;|*j2oTb78RYtlMewqG65gfLH{HB}!!3Q{8#ah_l&ej$t!7yW%XhvI5 z54bP&J4l*v!(CD2O8>>i$3(dYNe~ygp~#KyyXvp zfpUS^K6LItI1k9X8h;eRi7M8CG9jFc3gxN;Q5HxK_u#61=;06HG$5-hAt-|5R92np zaVmdfILcsasHYOGDckCYPe#`&T}e|6fES>%6HV(3wfLDs#GhC37!=|Kgh@;oFs-&2 z)_g48c$C6%E33J9+=`pq0%a{INrrU)?kcr5wnCs4Cp4>@)Y6oKKuRdx8xKqX5<@2( zAznOoTa>k>Ly{mi6YV@g{J5wCiaOBL?oy7a6aMZLO0!~B6$gic1DRXb6@^{tg5Ii* zy&n-1*UebeMeq<0^_0Sm!%;XKm8N@-!ryp-fNeAZlhP$$(-;(v3B~5w zik7BJ5yo6Za_P!+sgp4ef9KH;(qaBlfWHf9a)va_W=EKmwB{l_7Yl@CgB@>j zqY<&LFwo9N*?c;`56m$a;qOJf6fX9Wl8uWISj^iZ08QxYVXpqXke8uonK0Ln;?X1} zy*iZD348g;Bt^CwWvhA3g>3rK%zje1X&s_)ED7rRVABSCfMZBdR((wO;scyLQfc|02nQ3m>=~3jgLFeRKq)K?`BGaV1D60SSm5?MxAgDXMeZ0 z3#+D(NEe!2NPL^{Er@qfiWiU$M-#fxM^2D1Z~(C#iv1|Y3y8-Eaclq+9zY>pKsZ_m zeW}k$==)fRLl^=t5F(FlEVNa{0ygnt zDSnQ@K8M*-wlu}`6+V2$=*jm!h7WiF1-Tjpd%uO{MA<0G}NMLzVaJETHyfBcOXPz2vb7$ps+$)n-DzbkMqjVlVo z5P|f-Xi1hni>3Kvr2TMqw#`^6AC|={$4Zl+Ib0emO*Z0=Rb3oCG6Tdj$4UK2XT*cq z$soCWfgAm1oRr~;dsB6E?ko~6CoXcMgL0*GBkoAmMaygN4yBuOCHR~Qy_hTIk{oPb zp|ohc)X^A)Rz%TFX80Q~bbBuB?!GZz3ZTIgpa*J=g4Q%;0<1)n@Hbu{W2rP_ z46H47kB3^nbAse+OhsWTJupG)?cEW7BQWq3Tu zj2C-l)vB^`41pJWW!3eR;UOS1ULa^1OE;WbR-IQ}U0kMEho^naHDPp`S!&~ga=LFS zY;WN49W!1aax#k?%p#YURu(ET@#qdr7zi-kLdfiMgr{@Nc(Kz{RVK28Cv#vHVby~& zdp&sg#*7y`J(`^0!5f%xpq^-E56bNIEW<#{=<%siVk`?(?|cobA9Wb4PNPd4si~|k zuTltDje%Cvt%Xt|XYTN1n3}FbbRCOIcij!GX^a`xZ1*C1FQd7?=>dFrAdK!YOBvo9 z@c}Q8vyOC6snnFVE|C_&=Nq?`NNc1=!)SV`R7Cdjw(~|QtW;jZD6fUlE#)w-_9}xF z)@DTD6ii;3lw*7rAD+dE8%htCO7Z@jB(~|i8)duEW-g=M%b}auf#?pJFx$JpgAky6vFlu@Se=LN-5J7 zH=^t4v^wam->H-ayWrL{J^2?2g17N~Y3FHDH}V(H*s5ue$bUd=#tS5p$rG7a4KL(_ z!k8vzwzd5}2Ehvifp7ny9cmCC`s1H)sD=eQh{5mz!MccG;q-Ww)13h_b@Rze2_ z@x$?(1U~NnMFC!fAi?wnVqb*O)z#8K(@}gl8b#fz)p2sa>oA z&6PEhhv^gwPleG1HPRsOGx&fP2$>;5rh5N?I9>pUm*6p5pdkX@@0WbNFQ5=FAnd3S zK35CsFQM=fGb!8j3qJh9(&|jJr$fd29g*J|l142PUGWeOW9VNL;02T>&`q;oT>Eso zG)3AGM|;eWEQHWEW=I8a*d}(SG|7lt_jS>fJOEopkIt0(8gaKCfFqj$aGfP}kzj)! zwt9yfT|i)Vq4&>{dKpdl+e9zlEhW(HvtdR3!E_g2SbVVkeh(CS(26;#aQ+qeKn)Xl zqsTj)KD1J5i4kMG{Sd(mSPO&FEU68Jb13c`qGA0Xb0@5GnqYt?)Ni4x?ZgHW(uAiJ zj554Hl%F2QhtS!eNKI42B@p$Y>NsQ{P3Zux_@imnw`yVI1aQ zh_N~TZchK5s|IW%N#33;Hwh>L-E(2F+6I5Oq2uO4J59#l$(krW1~p0=iqcTj*ZX$- zjTf-K8zpzcb|m{ILzlZHFJl)JcEN17S%J zriUBH;qP(y`*!-sLMhTX0f7mcT;RzO9xoq7`B<3!jD`5SkmlYcrPBu%!F*>50#h(6 zBfQP{8!upVFK#q^Kq7=@-vwJ$e$%0;l-?zEHCAG2K{;ky#P_k3gYF`4I}Xb#33Y_#BS3(a0E4Kyyq-wTn5A>Mc6 zZ@hqE1G!=BxW~|^h>tg~&Py@K(r}uyL>gvXfe$M%Zg2YI60l_z0;`Y$s4q+5ZJf0T z-~}{xqZ!MfcFkETg%~N~lvn(U<uV0(kQQ1Urx2 zEA5b^_v3f2eLxDAq@(dWLB%0S`YnFvyhkMX+z@^)qb`UZ+5}ZwdQ?hqLjW9_ZnW*A zQcKt`82hL+0&dSe3X7yD>i-xllA>tsV^S};z4DlpVTlC~s2ML)=Ph1uPQj;C^$ESB zii;FvJ@BcgD(i($`1xCNZ}eu=t{G3DfQI2B2p&2C zV3Yuwa$t-A+&C~!0O(tVDB}fy4psp21b|*v0P+QZu2u^mlLUeeR{)9-U^_vR;THhK zD!}qqqCS~Rxwt|Ac;W@ZR|xjZ#4TL9Jz z03Ejg+#>*V+yZc~0MJiRcv1l9b_HOw0MP9Uz%v3sXX|1({jo(L=xv1{+XR3fRsgmO0R5`~JTCxrrvmVz z0MMBVz{>(a|0w{k2msxs0KCQkR{zmi3dk-I1RbORydeN|jRLS&0O%hD;7tLbe-wbX z1%QrG0Nxb0HAe+7VUPyjwhz`~jt`aS{qQUpP#CjdtUfSyhOjtKxAn*f{;0D3e5_(lNe%LL#% z0igd9fbRtWK1>TDX9R-YO90LZ06mrf{3rnQP6BX20O*?p;GzJ~Aql|$1b|LS0Dchw zdLjY%4FC)8XVCu$$R8pIdL9AzO91G71mGV5pz{%c%K|{JBLKI-1~ONQ{zd>K0icr+ z02cwA46!i8C=m24LJ&6rpidD14*{Sj5dbd%pyLn#9|54-5CA^`pz9ET00E%G5P-l~ z;Gf%yUPC~FMG*8B0uU+y^brCOE&%il0uU(xbP56xB>?mc0uUnr^acVDCxAc;N16!) zJ%13Sg#ggq2S9=V(6a|XYXP7)4}e4gpcfB-WC5V-4uDhvpz98Rwz0rJCjfnSfV3Au z&|wEaM**Ol4uDPqKwljIT?BysIRLr|0KIYm^bi0#aV1b~h>07eJ^y>9@F z5&(MJ02nO*bg%(1RsiT=10Yub=vD(@f(ls7=t~1+qKcT&p$0&K0ML~NK%oH8e+Iy0 z0iY8NfT;pNCmH}|0if#)fKmaVzYG9Nxj@iM21um<&_M=3l>pF520)Df&`}1!bOE4? z41k#eK<5|$vju>@F#zT$0JJ~!h5<591VQ%~0P_WaJ}&?k3IN?*0Nf=2^mGBRSODnR z0$?cu%nPs#egROY0&FI=iq(H6U(My~R5^Ry9wKZI0D8RuxK{unVGMXc0OG%0zj7*08a@3Jy-xdEdX>_0r0E<&@lzTRso|wj34omfKyMQOuL=MiOaQzt0CXn-uv-A= zK>}cp3Rsxu2#|d$!hA&lyd?m14*~Fw0MIW4z<&fF@sijt09OutAOJTG929^j2P}sK z;=_?60`TX+#{xhH5TyGl0_@cDf8iGZU#I}9R9~r2=A&GETmUCH@T~wMEL`RH0>Puw zpz^E$@NhH$KMDZ7O91>N06YQ>!2bl$lLNmBpf3mh5I`me{$}-`WhI9rmqiftGlACI zz$e2qi+&~mBmtn42>=%XppyvzqX5vm1b~|W(7ObHhX5?-M*_r4AiX%?BY*)M@Dsog z4g?^;4qG>YU!Wsc1z0hJs!!~_bPz`%z;@{)dH86!Ss211#0q&Fmp2zc3l6jr03P55 zm5BntBijI^2mt*_0Hg^3y+#1E6F>n1F#qo$5OfDYklO_?l>?mxP{M((0x0J|cL7Y} zKu-anqXv{_2w(;WdNY8{|Is4@LHddy=y(C3zW~tJ0>D54pi2dSOaY)51%NC8pvMG& zp#nhP2mm<(KtBl1|Az|%eINjg6aczE0JuW{=mG&?i~!IB0>C%~n5QBaegTlD0<3KF z)hBZS7Z)i2j6aWZ4O2xBJVFl|N(6v@69CEtu$coD0(h1K(*%J25{ObQfE^sD6##lk zaQ!<&Am}B5II|F7TkW&q7XWirfMvy^KAGop@gf1BF9pIc767_Y09Ymf^rHY!CjiS| z99b<8bfZ9!wE{q=2>`MH&^-dc1_7W;1OO@kbcFzLp8(Jq0>A?TK!*qb4_R~b4M!dp zLD2sJK{g5C30KW+Uy%GTY zAprD70PvRp&<6p)KLS9{0|1u=fbItXZnMOz1fc%`5J>>&bpXIc0O)!Ez$gH8JpkY) z0CYV7;30rA4tNOwT@Mh#M+GcqbUOgzry^!_I{*+M0Q5Zo5GVljH~K!O0!y8u9I z0iaI-fJ6m=_J@uIK$1lebS40hDgbmQ0MJ$d=t}^gy#UaE06<3ppw9q+P69wb0RUYD zfDQue|GNnUy#x@XhXBx106@9`&`|(DF9D!?0DwLMKoMp83Q#1*~<_F_Hp2C0ldS3_Yf#Fz-2!N z4yXW2^h5Q@e29xb62QkC_^$vy`HCaQRDh{Gp+1>Ua`ATpIK_c80yxWo z9|drp0~ZBwi37hNFxdc?U$Os%*6@dlutfh-pUi)A@nr#A;egak)nI^MpumVglmRX# z4tS^l)99r>nZ3E#PXRi@nL~~QiXcH82o*pW2Ooh z+x+)-{QVYv4Pp&A0QnLB%CXKD{=->*-ju5R%Bj`KQ;H{}o`W_aJm8-X=fk-=MfjmA zqzU_^rX${K4(xo0m#^`10xzH8x#Hb+3Fl z2Nq6;UXmUq3wQqSk~Ae0|3A#mJP$*k32rP#^Gx_cMk)Nq1N<00SaM*hAr@{IrW!Dh z5ygf!aO+=eNQ2v~VnZ_AHWwSZxwFUzvqA}-UktJFoAnIK3MW|wbeq`_OqZv^TNh>w zm^GDTl`0|Arx}`nlIdnc3f!KA8_Q|dLXuUd1i_aSB_PgJVo2t~2T9hCgxiVVpofSP zOAM{ywxYz40Jj%Qn7Jn*0zCPZGO%;0p(8w1mKtt{+vZY3s~Bd?XeldS0-AhTffdcH zEUGGoS6XV2s!OGYwh*{knV}2Z^2(TztIG^+eOS~rQr0?*8bMFCB@qUUalXtD3T0+2 zH?*yRD4oACU>%wGjUkSumf1G57ew&q|A;cVs>u2!Yj67KH-=Ua_yEN5VuX&%oW`_& zxQ{diLFBiF7Ok0JMy3S>0g9GMQ}fHG6y;$ffeMCIa6#siP)~AxFvLK#mESUMUip?; zf96}3NWgantZAM2ZNhhqsg>U`-d_98kOZmx~dWz|E z{hkF$`<^}Jf6r1_@jc7>^WPhw64TH4)8+3C9pI_`X;u~`r&+T1pJvhDJ$j7vW(pYvl`81Hc|NaO9} zT#)(+<6N-nt{CUiI+Ag-F7qDX&YP8Xer07ce+S8%9vSC?B>yzd1xfSEWlFl_x?p1+ zpX-7(sV>*0IWL)0ndd-B5Y6cf$C(f3y10P!(_9y%%`o026>javyI_sX8}AYVxtTE@ zt=Reac$W?yfPOi}r8QU7HnRgLilJ#kNmx)`ULpJgs63?*Z_n%uqENaii-bu~wZ=>Z zBj)d1I@RS{0=i1gF45aSS6!$pn)qC(Ydo)&K_sgeftX=*?F15zE$5$5S8TTlVXnx? z&@lFNXP9eCW<%E7Bx^rJpp~(%Q6N7U=8F9N9_ES#7a8t~`RE_+iv3hYxGU!Ip>S8^ z<3PA8a{DL0wTNJ{5&X6=!WB#E*$CH`+^iu|)<|qD2{b>#6}}x4;pzu+&q&vFMk!YkV_6GlnbZyP!E|9XG#khg@!lpN?FfQ`2SS!Z)4!|#hA_BO*Jp-phRuP$>|tt)GGgC8vIXLJPk8fuOEvQ4s0} zJ`jAgD35@&JVY!M@YxSLGrKprf%>QUKG@xvIdf*_oHKjQ+&yP7=L?Q-hJWSIzbAMS z!VOQ0FBs}X%j7Ipbb@v9Wx)_+xjGB-umQGb!51T~R!r3fAOrk@sY6NW>Grxq+=%kM zskVu=Jgo=`lBLq2^g|B)s@S$=RjhSg6`S$lDj;X`W)(NjISV+Tn(C4_SF`!&R70^< z<3<|cxbbWLbjXz-oK$)t(f(?<(ZX)lwjj2Eu$gl0Ka@noj;&#%x@&;^--a3(Wzp`{ z_Oa|2KUXpk@t+!Q#iD6YXyH$4=MbMIe>|?xz*ssB2B8LP>5^!^It|XoS#-U%K1i1- zN1nyxMzjY4iQm5y##q>NEd#N6(wL54{aihbo2Pg%W@##dhZ6V(N`Q$zG*Pz9gwZ78 zOm5D1W^xmJHxn|j-u|-~IDQtJ%rgrrkn*`%prRjmcNWypK+H5?s^iI?a{h8?mtz*d zxc+#$Wq!FD`9dGBK|1hKURZ#=$6F7HoF;8qJrwfImU;;CP1Pf4T&)56+DXvPe+g-F z^WQLi==oLPG}ko1{c(Mj9!d}T!=oKyc&9?5ESU$@j@MI2fVt-RdC=};b`LIqBEGrW z1_Pzu*2%ZJ6;j$;A(@eBtuTUbv{o2SH|DQf;c|RF+pCW@9PJg?;0pv?bX*PtOSCEk zMk;@NDct8c5Z9^w)aZncsBunwr~W$^z+hW76ah~SY=e|Y)dS@=6p){={sHo28>F%{ zD12{$O`rH6^dW0!EeFh8ZTgo(w$jD=Cro=`1>C_r(X`{EtZM%G5jYWpTpxK9ijk|i zQ^GLfetr#%sY!{nT=XH3j}`p#hN(SzeJH?)XP z=OErQCfDFuXKNv)Y(!(&+Yoa5yoN`$g$PHAazZp$-F&NX9iI^rT{*12D3S+qVZG_Bw7GKSCDUKZ3t1 zvc6g1cjn3XrQ)zdFk1fp0Dj}T{tyWB>?e@vu+RuhFcG~_F*kh*X)*HsBk-6E9EIjs z($xIyD5NU#Bt^}xF^LS}S8vb;1A`pTuNaJD+V1D0EaInTf%MP~2AI(9#cH0e8F zmHg@?vW6f@y{qTSB=ue3HcxawY+MZXcUf~dHg!qG|M{oVh{1pA^eXk1%1XLaPSmSv zBVg>)G?=0~XQMCBV$cXtDeJ3h@IXs*H>d^PaEpIYA(fotYE@0%lStbfq=27uv`ryPa{A>6H7a(X^5R%xfk-~#PyJS zQ@|Ap2fXT(5==yEcnb=hEPRxB1>vCE+hh&kC|PPFvaH?>bb_8{o!x9Lxb!qe8CS3jO;PSdWDxLcW4It_AJ}SA|^m5oGs7c!RISZ_}j^ z9X(%9SQkV;?ZP_c%w3QnEJftzQ;@xcb!b3S7@lCntUbOm}q%7vY@RbFAG$E0M7+#aLplZxZTX}F&0Hwcn4h5ZnYCFhhw)MS?sPU zqfm0&2I%ezc1)2C>S+NEgq(p6c#$=eJ+tdwzv@6 zFi)lFJQ@vktv5mq%_{DGQcGCS2q(+IHwJtyb=+-b&hJE)tlkM(dF7q`jyeRh3Wl-e z>V5bI;qpP*dm9YQ??&ftB%@%D!5s;P-=*e|v}`0<>=3z2@~62PUET(lYIv~`X!%bA z2^+-XsCr#i<1}LeOnxunYs{ruyu7|pxq44D`^C(LKx9j+%EkFO8ffJ4Vx}v9YyoD4 z56i2k;O-@qLlBRM;ta-}6H{6uX7kL;#?ZL#TzBMZqiH&UWpF`Dq-hLDu#TDT#-u_U zhom;98-JaHQOTXB(>wafCy(~v%qCtP3a z3N5hW?4q`U8!c%6&W(4JWEXeyMYGit6}_(_%eO$r5@MyNDEbiMmDsJ6#Ziy7k-a0w zz;|PHi=zLWigse74X005^f`nD`>1(RS^t?0?2TvGH%+g-RyePs&u5O;9&yj21{M7w z=4fRO=f0sg+Q7uA)^X?EBy3moHHxe`1N|&z*D3nz#37c5Z5>xcVD$E|S7f^s{R5_} z6L4flIlGa)vWJ1)Z_y^bHO*0pZAS*&7Y zUoO_WTem7SXMX{2;chV0S?i@`lF{UfD@vM^A=$LJkn=A@I{iqk!kl*jUKz=)rzLTL zq$VSb^IpSShoR7r3nPkLR@KUp8`%4F8C0RoMNq7@m6IVY+9rg=wM4e_GVmGg8w5rM zZFK+9e$dmXRT2yy(da!}jR5ZDrDFO(Mb9N<^oai60{z60)^D%_BT11V-^EcXIf9}E z19HTBj;$%?sT^@2CUz=XPb%AD)6D%t#CAu|VXD_(;q~LI=fe1y6mwmHm;|z>M2s_s zj1WaJCf?o#a%`!fh4k&EVlZCrDHRlZdAd|kAa!4CQnJ_Q4!Y`^7vbwP=x=rfTsT(b{bhn8FfWt|3cVaI6SNHfrc7Y)$4nn9p6qL| zIh|S>vWQz)7i@MnMplUFT0Q|6bpsY@r3ma}MW#JQ$jZWubupiE_Q}q>efYlQ7Z$>0 z`V{eyT=N2xqM zOccpuH;GKsJx46S_?0~F5}CcIs@1<;N$Y3%ql@j9(J0gjEW$+X4iqrnPL&Aj6&&}ineLVFy!^r|!F%nf5`XHxC$wuWo9*ANj~?+Hgb z@eb{Pe5XGs_<9-lkwI-De>_t(YE4Md zkFq7R(d+z%J5cAviGj_+&4Vh52r#7Y^Mq+i#lI^oYZDY9-OxrI*?hH4)b+D|BuLV7 zNE*s=+|`oB?II1SC$$R-FL~OpSDr^(ntZ73;TFW+!F`eS|n{7g_JGT|@}gCU2h z6U#}51%)4*tjhz3S+eI2i~K>%qeh#KJQ6%^%wbQ-AKCY$%P%duK1W#lV(U_UgzXwW zA}9v=#1WB>V`cjh9(x@}cqA%EMUJJ)!`cc|W$EXF!oR;bDvAoZzIN>oSYHyZPpGP> zD#>{+W@M_|g-O>fF6*=x$sor?p5Vfj!E)DHWpIMsc)PTNNKSw9`!K$MiwhRaVy&-M^!0>H2>bDO z09T#i#VI7>%yAu}ECt!MUJ?|!-E>LhSoR#C4I+9wF*kX0Zt4@4#9&KaTEtyRQh0G@5I!h(3=00`c2@cK`qY diff --git a/docs/_build/html/IQM_Vis.html b/docs/_build/html/IQM_Vis.html index d667abe..72c088a 100644 --- a/docs/_build/html/IQM_Vis.html +++ b/docs/_build/html/IQM_Vis.html @@ -140,7 +140,10 @@

SubpackagesSubmodules -
  • IQM_Vis.metrics.IQMs module
  • +
  • IQM_Vis.metrics.metric_utils module
  • +
  • IQM_Vis.metrics.non_perceptual module
  • +
  • IQM_Vis.metrics.perceptual_DL module
  • +
  • IQM_Vis.metrics.perceptual_trad module
  • Module contents
  • diff --git a/docs/_build/html/IQM_Vis.metrics.SSIM.html b/docs/_build/html/IQM_Vis.metrics.SSIM.html index dbe89bf..bb745e6 100644 --- a/docs/_build/html/IQM_Vis.metrics.SSIM.html +++ b/docs/_build/html/IQM_Vis.metrics.SSIM.html @@ -68,7 +68,10 @@
  • Submodules
  • -
  • IQM_Vis.metrics.IQMs module
  • +
  • IQM_Vis.metrics.metric_utils module
  • +
  • IQM_Vis.metrics.non_perceptual module
  • +
  • IQM_Vis.metrics.perceptual_DL module
  • +
  • IQM_Vis.metrics.perceptual_trad module
  • Module contents
  • diff --git a/docs/_build/html/IQM_Vis.metrics.html b/docs/_build/html/IQM_Vis.metrics.html index c568985..23204b1 100644 --- a/docs/_build/html/IQM_Vis.metrics.html +++ b/docs/_build/html/IQM_Vis.metrics.html @@ -64,7 +64,10 @@
  • Submodules
  • -
  • IQM_Vis.metrics.IQMs module
  • +
  • IQM_Vis.metrics.metric_utils module
  • +
  • IQM_Vis.metrics.non_perceptual module
  • +
  • IQM_Vis.metrics.perceptual_DL module
  • +
  • IQM_Vis.metrics.perceptual_trad module
  • Module contents
  • @@ -112,62 +115,29 @@

    Subpackages

    Submodules

    -
    -

    IQM_Vis.metrics.IQMs module

    -

    sample metrics to use with the examples of the UI

    -
    -
    -class IQM_Vis.metrics.IQMs.DISTS[source]
    -

    Bases: object

    -

    Deep Image Structure and Texture Similarity (DISTS) Metric. Uses the -code from https://github.com/dingkeyan93/DISTS. Uses the PyTorch backend. -It is robust to texture variance (e.g., evaluating the images generated -by GANs) and mild geometric transformations (e.g., evaluating the image -pairs that are not strictly point-by-point aligned).

    -
    -
    -__call__(im_ref, im_comp, **kwargs)[source]
    -

    When an instance is called

    -
    -
    Parameters
    -
      -
    • im_ref (np.array) – Reference image

    • -
    • im_comp (np.array) – Comparison image

    • -
    • **kwargs – Arbitrary keyword arguments

    • -
    -
    -
    Returns
    -

    DISTS score

    -
    -
    Return type
    -

    score (np.array)

    -
    -
    -
    - -
    - +
    +

    IQM_Vis.metrics.metric_utils module

    +

    Helper functions for metric computation

    +
    +
    +

    IQM_Vis.metrics.non_perceptual module

    -
    -class IQM_Vis.metrics.IQMs.LPIPS(network='alex', reduction='mean')[source]
    +
    +class IQM_Vis.metrics.non_perceptual.MAE(return_image=False)[source]

    Bases: object

    -
    Learned Perceptual Image Patch Similarity between two images.

    Images must have the same dimensions.

    +
    Mean Absolute Error between two images. Images must have the same

    dimensions

    Parameters
    -
      -
    • network (str) – Pretrained network to use. Choose between ‘alex’, ‘vgg’ -or ‘squeeze’. (Defaults to ‘alex’)

    • -
    • reduction (str) – How to reduce over the batch dimension. Choose between -‘sum’ or ‘mean’. (Defaults to ‘mean’)

    • -
    +

    return_image (bool) – Whether to return the image (Defaults to False which +will return a scalar value)

    -
    -__call__(im_ref, im_comp, **kwargs)[source]
    +
    +__call__(im_ref, im_comp, **kwargs)[source]

    When an instance is called

    Parameters
    @@ -178,7 +148,11 @@

    SubmodulesReturns -

    LPIPS score

    +

    +
    MAE (scalar if return_image is False, image if

    return_image is True)

    +
    +
    +

    Return type

    score (np.array)

    @@ -189,11 +163,11 @@

    Submodules -
    -class IQM_Vis.metrics.IQMs.MAE(return_image=False)[source]
    +
    +class IQM_Vis.metrics.non_perceptual.MSE(return_image=False)[source]

    Bases: object

    -
    Mean Absolute Error between two images. Images must have the same

    dimensions

    +
    Mean Squared Error between two images. Images must have the same

    dimensions

    @@ -203,8 +177,8 @@

    Submodules -
    -__call__(im_ref, im_comp, **kwargs)[source]
    +
    +__call__(im_ref, im_comp, **kwargs)[source]

    When an instance is called

    Parameters
    @@ -216,7 +190,7 @@

    SubmodulesReturns

    -
    MAE (scalar if return_image is False, image if

    return_image is True)

    +
    MSE (scalar if return_image is False, image if

    return_image is True)

    @@ -230,11 +204,11 @@

    Submodules -
    -class IQM_Vis.metrics.IQMs.MSE(return_image=False)[source]
    +
    +class IQM_Vis.metrics.non_perceptual.RMSE(return_image=False)[source]

    Bases: object

    -
    Mean Squared Error between two images. Images must have the same

    dimensions

    +
    Root Mean Squared Error between two images. Images must have the same

    dimensions

    @@ -244,8 +218,8 @@

    Submodules -
    -__call__(im_ref, im_comp, **kwargs)[source]
    +
    +__call__(im_ref, im_comp, **kwargs)[source]

    When an instance is called

    Parameters
    @@ -257,7 +231,7 @@

    SubmodulesReturns

    -
    MSE (scalar if return_image is False, image if

    return_image is True)

    +
    RMSE (scalar if return_image is False, image if

    return_image is True)

    @@ -271,16 +245,11 @@

    Submodules -
    -class IQM_Vis.metrics.IQMs.MS_SSIM(return_image=False)[source]
    +
    +class IQM_Vis.metrics.non_perceptual.one_over_PSNR[source]

    Bases: object

    -
    -
    Multi-Scale Structural Similarity Index Measure between two images.

    Images must have the same dimensions. Score given is 1 - MS_SSIM to give the -loss/dissimilarity. -Note that images of small size, below 180 pixels will have their kernel size -reduced for compatability with the 4 downsizing operations.

    -
    -
    +

    Peak signal to noise ratio - https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio +The score given is normalised between 0, 1 by taking 1/PSNR

    Parameters

    return_image (bool) – Whether to return the image (Defaults to False which @@ -288,8 +257,8 @@

    Submodules -
    -__call__(im_ref, im_comp, sigma=1.5, k1=0.01, k2=0.03, mssim_kernel_size=11, **kwargs)[source]
    +
    +__call__(im_ref, im_comp, **kwargs)[source]

    When an instance is called

    Parameters
    @@ -300,11 +269,7 @@

    SubmodulesReturns -

    -
    1-SSIM (scalar if return_image is False, image if

    return_image is True)

    -
    -
    -

    +

    PSNR between the images

    Return type

    score (np.array)

    @@ -314,17 +279,21 @@

    Submodules +

    IQM_Vis.metrics.perceptual_DL module

    -
    -class IQM_Vis.metrics.IQMs.NLPD[source]
    +
    +class IQM_Vis.metrics.perceptual_DL.DISTS[source]

    Bases: object

    -

    Normalised Laplacian pyramid -Proposed by Valero Laparra et al. https://www.uv.es/lapeva/papers/2016_HVEI.pdf . -NLPD is an image quality metric based on the transformations associated with the -early visual system: local luminance subtraction and local gain control.

    +

    Deep Image Structure and Texture Similarity (DISTS) Metric. Uses the +code from https://github.com/dingkeyan93/DISTS. Uses the PyTorch backend. +It is robust to texture variance (e.g., evaluating the images generated +by GANs) and mild geometric transformations (e.g., evaluating the image +pairs that are not strictly point-by-point aligned).

    -
    -__call__(im_ref, im_comp, nlpd_k=1, **kwargs)[source]
    +
    +__call__(im_ref, im_comp, **kwargs)[source]

    When an instance is called

    Parameters
    @@ -335,7 +304,7 @@

    SubmodulesReturns -

    NLPD score

    +

    DISTS score

    Return type

    score (np.array)

    @@ -346,22 +315,26 @@

    Submodules -
    -class IQM_Vis.metrics.IQMs.RMSE(return_image=False)[source]
    +
    +class IQM_Vis.metrics.perceptual_DL.LPIPS(network='alex', reduction='mean')[source]

    Bases: object

    -
    Root Mean Squared Error between two images. Images must have the same

    dimensions

    +
    Learned Perceptual Image Patch Similarity between two images.

    Images must have the same dimensions.

    Parameters
    -

    return_image (bool) – Whether to return the image (Defaults to False which -will return a scalar value)

    +
      +
    • network (str) – Pretrained network to use. Choose between ‘alex’, ‘vgg’ +or ‘squeeze’. (Defaults to ‘alex’)

    • +
    • reduction (str) – How to reduce over the batch dimension. Choose between +‘sum’ or ‘mean’. (Defaults to ‘mean’)

    • +
    -
    -__call__(im_ref, im_comp, **kwargs)[source]
    +
    +__call__(im_ref, im_comp, **kwargs)[source]

    When an instance is called

    Parameters
    @@ -372,11 +345,7 @@

    SubmodulesReturns -

    -
    RMSE (scalar if return_image is False, image if

    return_image is True)

    -
    -
    -

    +

    LPIPS score

    Return type

    score (np.array)

    @@ -386,12 +355,18 @@

    Submodules +

    IQM_Vis.metrics.perceptual_trad module

    -
    -class IQM_Vis.metrics.IQMs.SSIM(return_image=False)[source]
    +
    +class IQM_Vis.metrics.perceptual_trad.MS_SSIM(return_image=False)[source]

    Bases: object

    -
    Structural Similarity Index Measure between two images. Images must have

    the same dimensions. Score given is 1 - SSIM to give the loss/dissimilarity

    +
    Multi-Scale Structural Similarity Index Measure between two images.

    Images must have the same dimensions. Score given is 1 - MS_SSIM to give the +loss/dissimilarity. +Note that images of small size, below 180 pixels will have their kernel size +reduced for compatability with the 4 downsizing operations.

    @@ -401,8 +376,8 @@

    Submodules -
    -__call__(im_ref, im_comp, sigma=1.5, k1=0.01, k2=0.03, ssim_kernel_size=11, **kwargs)[source]
    +
    +__call__(im_ref, im_comp, sigma=1.5, k1=0.01, k2=0.03, mssim_kernel_size=11, **kwargs)[source]

    When an instance is called

    Parameters
    @@ -427,17 +402,45 @@

    Submodules -
    -IQM_Vis.metrics.IQMs.make_kernel_odd(value)[source]
    -

    +
    +
    +class IQM_Vis.metrics.perceptual_trad.NLPD[source]
    +

    Bases: object

    +

    Normalised Laplacian pyramid +Proposed by Valero Laparra et al. https://www.uv.es/lapeva/papers/2016_HVEI.pdf . +NLPD is an image quality metric based on the transformations associated with the +early visual system: local luminance subtraction and local gain control.

    +
    +
    +__call__(im_ref, im_comp, nlpd_k=1, **kwargs)[source]
    +

    When an instance is called

    +
    +
    Parameters
    +
      +
    • im_ref (np.array) – Reference image

    • +
    • im_comp (np.array) – Comparison image

    • +
    • **kwargs – Arbitrary keyword arguments

    • +
    +
    +
    Returns
    +

    NLPD score

    +
    +
    Return type
    +

    score (np.array)

    +
    +
    +
    + +
    -
    -class IQM_Vis.metrics.IQMs.one_over_PSNR[source]
    +
    +class IQM_Vis.metrics.perceptual_trad.SSIM(return_image=False)[source]

    Bases: object

    -

    Peak signal to noise ratio - https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio -The score given is normalised between 0, 1 by taking 1/PSNR

    +
    +
    Structural Similarity Index Measure between two images. Images must have

    the same dimensions. Score given is 1 - SSIM to give the loss/dissimilarity

    +
    +
    Parameters

    return_image (bool) – Whether to return the image (Defaults to False which @@ -445,8 +448,8 @@

    Submodules -
    -__call__(im_ref, im_comp, **kwargs)[source]
    +
    +__call__(im_ref, im_comp, sigma=1.5, k1=0.01, k2=0.03, ssim_kernel_size=11, **kwargs)[source]

    When an instance is called

    Parameters
    @@ -457,7 +460,11 @@

    SubmodulesReturns -

    PSNR between the images

    +

    +
    1-SSIM (scalar if return_image is False, image if

    return_image is True)

    +
    +
    +

    Return type

    score (np.array)

    diff --git a/docs/_build/html/IQM_Vis.transforms.html b/docs/_build/html/IQM_Vis.transforms.html index b1a72dd..91395dc 100644 --- a/docs/_build/html/IQM_Vis.transforms.html +++ b/docs/_build/html/IQM_Vis.transforms.html @@ -273,14 +273,15 @@

    Submodules
    -IQM_Vis.transforms.effects.blur(image, kernel_size=7)[source]
    +IQM_Vis.transforms.effects.blur(image, kernel_size=1)[source]

    Gaussian Blur on an image

    Parameters
    • image (np.array) – image to be rotated

    • kernel_size (int) – size of the convolutional kernel, will be converted -to an odd number. (Defaults to 7)

    • +to an odd number. 1 is no blur. +(Defaults to 1)

    Returns
    @@ -380,7 +381,7 @@

    Submodules
    -IQM_Vis.transforms.effects.jpeg_compression(image, compression=90)[source]
    +IQM_Vis.transforms.effects.jpeg_compression(image, compression=101)[source]

    encode image using jpeg then decode

    Parameters
    @@ -388,7 +389,7 @@

    SubmodulesReturns diff --git a/docs/_build/html/_modules/IQM_Vis/UI/experiment_mode.html b/docs/_build/html/_modules/IQM_Vis/UI/experiment_mode.html index 54fcedc..b5b1602 100644 --- a/docs/_build/html/_modules/IQM_Vis/UI/experiment_mode.html +++ b/docs/_build/html/_modules/IQM_Vis/UI/experiment_mode.html @@ -241,7 +241,7 @@

    Source code for IQM_Vis.UI.experiment_mode

                 self.ref_image_unprocessed = self.data_store.get_reference_unprocessed()
             # get MSE for experiments to get a rough sorting
             mses = []
    -        mse = IQM_Vis.IQMs.MSE()
    +        mse = IQM_Vis.metrics.MSE()
             for trans in self.experiment_trans_params:
                 mses.append(
                     mse(self.ref_image, self.get_single_transform_im(trans)))
    diff --git a/docs/_build/html/_modules/IQM_Vis/examples/dataset.html b/docs/_build/html/_modules/IQM_Vis/examples/dataset.html
    index 8bc816d..557dbfd 100644
    --- a/docs/_build/html/_modules/IQM_Vis/examples/dataset.html
    +++ b/docs/_build/html/_modules/IQM_Vis/examples/dataset.html
    @@ -93,15 +93,15 @@ 

    Source code for IQM_Vis.examples.dataset

     
     
    [docs]def run(): # metrics functions must return a single value - metric = {'MAE': IQM_Vis.IQMs.MAE(), - 'MSE': IQM_Vis.IQMs.MSE(), - '1-SSIM': IQM_Vis.IQMs.SSIM() + metric = {'MAE': IQM_Vis.metrics.MAE(), + 'MSE': IQM_Vis.metrics.MSE(), + '1-SSIM': IQM_Vis.metrics.SSIM() } # metrics images return a numpy image metric_images = { - # 'MSE': IQM_Vis.IQMs.MSE(return_image=True), - # 'SSIM': IQM_Vis.IQMs.SSIM(return_image=True) + # 'MSE': IQM_Vis.metrics.MSE(return_image=True), + # 'SSIM': IQM_Vis.metrics.SSIM(return_image=True) } # make dataset list of images diff --git a/docs/_build/html/_modules/IQM_Vis/examples/dists.html b/docs/_build/html/_modules/IQM_Vis/examples/dists.html index 0a16f1b..efd520e 100644 --- a/docs/_build/html/_modules/IQM_Vis/examples/dists.html +++ b/docs/_build/html/_modules/IQM_Vis/examples/dists.html @@ -165,12 +165,12 @@

    Source code for IQM_Vis.examples.dists

     
     
    [docs]def run(): # metrics functions must return a single value - metric = {'DISTS': IQM_Vis.IQMs.DISTS(), - 'LPIPS': IQM_Vis.IQMs.LPIPS(), - '1-SSIM': IQM_Vis.IQMs.SSIM(), - 'MAE': IQM_Vis.IQMs.MAE(), - # '1-MS_SSIM': IQM_Vis.IQMs.MS_SSIM(), - # 'NLPD': IQM_Vis.IQMs.NLPD(), + metric = {'DISTS': IQM_Vis.metrics.DISTS(), + 'LPIPS': IQM_Vis.metrics.LPIPS(), + '1-SSIM': IQM_Vis.metrics.SSIM(), + 'MAE': IQM_Vis.metrics.MAE(), + # '1-MS_SSIM': IQM_Vis.metrics.MS_SSIM(), + # 'NLPD': IQM_Vis.metrics.NLPD(), } # metrics images return a numpy image - dont include any for this example diff --git a/docs/_build/html/_modules/IQM_Vis/examples/experiment.html b/docs/_build/html/_modules/IQM_Vis/examples/experiment.html index 86751b0..86cb97a 100644 --- a/docs/_build/html/_modules/IQM_Vis/examples/experiment.html +++ b/docs/_build/html/_modules/IQM_Vis/examples/experiment.html @@ -93,12 +93,12 @@

    Source code for IQM_Vis.examples.experiment

     
     
    [docs]def run(): # metrics functions must return a single value - metric = {'DISTS': IQM_Vis.IQMs.DISTS(), - 'MAE': IQM_Vis.IQMs.MAE(), - '1-SSIM': IQM_Vis.IQMs.SSIM(), - # '1-MS_SSIM': IQM_Vis.IQMs.MS_SSIM(), - 'NLPD': IQM_Vis.IQMs.NLPD(), - # 'LPIPS': IQM_Vis.IQMs.LPIPS(), + metric = {'DISTS': IQM_Vis.metrics.DISTS(), + 'MAE': IQM_Vis.metrics.MAE(), + '1-SSIM': IQM_Vis.metrics.SSIM(), + # '1-MS_SSIM': IQM_Vis.metrics.MS_SSIM(), + 'NLPD': IQM_Vis.metrics.NLPD(), + # 'LPIPS': IQM_Vis.metrics.LPIPS(), } # metrics images return a numpy image diff --git a/docs/_build/html/_modules/IQM_Vis/examples/multiple.html b/docs/_build/html/_modules/IQM_Vis/examples/multiple.html index edafe5f..2c2787c 100644 --- a/docs/_build/html/_modules/IQM_Vis/examples/multiple.html +++ b/docs/_build/html/_modules/IQM_Vis/examples/multiple.html @@ -95,13 +95,13 @@

    Source code for IQM_Vis.examples.multiple

         file_path = os.path.dirname(os.path.abspath(__file__))
     
         # metrics functions must return a single value
    -    metric = {'MAE': IQM_Vis.IQMs.MAE(),
    -              'MSE': IQM_Vis.IQMs.MSE(),
    -              '1-SSIM': IQM_Vis.IQMs.SSIM()}
    +    metric = {'MAE': IQM_Vis.metrics.MAE(),
    +              'MSE': IQM_Vis.metrics.MSE(),
    +              '1-SSIM': IQM_Vis.metrics.SSIM()}
     
         # metrics images return a numpy image
    -    metric_images = {'MSE': IQM_Vis.IQMs.MSE(return_image=True),
    -                     'SSIM': IQM_Vis.IQMs.SSIM(return_image=True)}
    +    metric_images = {'MSE': IQM_Vis.metrics.MSE(return_image=True),
    +                     'SSIM': IQM_Vis.metrics.SSIM(return_image=True)}
     
         # first row of images
         row_1 = IQM_Vis.dataset_holder([os.path.join(file_path, 'images', 'waves2.jpeg')],
    diff --git a/docs/_build/html/_modules/IQM_Vis/metrics.html b/docs/_build/html/_modules/IQM_Vis/metrics.html
    index bee8a3b..18bfab9 100644
    --- a/docs/_build/html/_modules/IQM_Vis/metrics.html
    +++ b/docs/_build/html/_modules/IQM_Vis/metrics.html
    @@ -83,15 +83,12 @@
                

    Source code for IQM_Vis.metrics

    -from IQM_Vis.metrics.IQMs import (MAE, 
    -                   MSE, 
    -                   RMSE,
    -                   SSIM, 
    -                   MS_SSIM, 
    -                   LPIPS, 
    -                   DISTS, 
    -                   NLPD,
    -                   one_over_PSNR)
    +# Author: Matt Clifford <matt.clifford@bristol.ac.uk>
    +# License: BSD 3-Clause License
    +
    +from IQM_Vis.metrics.non_perceptual import MAE, MSE, RMSE, one_over_PSNR
    +from IQM_Vis.metrics.perceptual_trad import SSIM, MS_SSIM, NLPD
    +from IQM_Vis.metrics.perceptual_DL import LPIPS, DISTS
     
     
    [docs]def get_all_metrics(): ''' diff --git a/docs/_build/html/_modules/IQM_Vis/metrics/IQMs.html b/docs/_build/html/_modules/IQM_Vis/metrics/IQMs.html deleted file mode 100644 index 7ae5f73..0000000 --- a/docs/_build/html/_modules/IQM_Vis/metrics/IQMs.html +++ /dev/null @@ -1,628 +0,0 @@ - - - - - - IQM_Vis.metrics.IQMs — IQM-Vis 0.2 documentation - - - - - - - - - - - - - - - - - -
    - - -
    - -
    -
    -
    - -
    -
    -
    -
    - -

    Source code for IQM_Vis.metrics.IQMs

    -'''
    -sample metrics to use with the examples of the UI
    -'''
    -# Author: Matt Clifford <matt.clifford@bristol.ac.uk>
    -# License: BSD 3-Clause License
    -
    -import torch
    -import torch.nn as nn
    -import numpy as np
    -import warnings
    -
    -from torchmetrics import StructuralSimilarityIndexMeasure as ssim_torch
    -from IQM_Vis.metrics.SSIM.ssim import ms_ssim
    -# from torchmetrics import MultiScaleStructuralSimilarityIndexMeasure as Mssim_torch
    -from torchmetrics import PeakSignalNoiseRatio as PSNRs
    -# from torchmetrics import UniversalImageQualityIndex as UIQI
    -# from torchmetrics.functional import universal_image_quality_index as UIQI
    -# from torchmetrics import SpectralDistortionIndex as SDI
    -from torchmetrics.image.lpip import LearnedPerceptualImagePatchSimilarity as lpips_torch
    -from DISTS_pytorch import DISTS as dists_original
    -from IQM_Vis.metrics.NLPD_torch.pyramids import LaplacianPyramid
    -
    -
    [docs]class MAE: - '''Mean Absolute Error between two images. Images must have the same - dimensions - - Args: - return_image (bool): Whether to return the image (Defaults to False which - will return a scalar value) - ''' - def __init__(self, return_image=False): - self.return_image = return_image - -
    [docs] def __call__(self, im_ref, im_comp, **kwargs): - '''When an instance is called - - Args: - im_ref (np.array): Reference image - im_comp (np.array): Comparison image - **kwargs: Arbitrary keyword arguments - - Returns: - score (np.array): MAE (scalar if return_image is False, image if - return_image is True) - ''' - _check_shapes(im_ref, im_comp) - L1 = np.abs(im_ref - im_comp) - if self.return_image: - return L1 - else: - return L1.mean()
    - -
    [docs]class MSE: - '''Mean Squared Error between two images. Images must have the same - dimensions - - Args: - return_image (bool): Whether to return the image (Defaults to False which - will return a scalar value) - ''' - def __init__(self, return_image=False): - self.return_image = return_image - -
    [docs] def __call__(self, im_ref, im_comp, **kwargs): - '''When an instance is called - - Args: - im_ref (np.array): Reference image - im_comp (np.array): Comparison image - **kwargs: Arbitrary keyword arguments - - Returns: - score (np.array): MSE (scalar if return_image is False, image if - return_image is True) - ''' - _check_shapes(im_ref, im_comp) - L2 = np.square(im_ref - im_comp) - if self.return_image: - return L2 - else: - return L2.mean()
    - -
    [docs]class RMSE: - '''Root Mean Squared Error between two images. Images must have the same - dimensions - - Args: - return_image (bool): Whether to return the image (Defaults to False which - will return a scalar value) - ''' - def __init__(self, return_image=False): - self.return_image = return_image - -
    [docs] def __call__(self, im_ref, im_comp, **kwargs): - '''When an instance is called - - Args: - im_ref (np.array): Reference image - im_comp (np.array): Comparison image - **kwargs: Arbitrary keyword arguments - - Returns: - score (np.array): RMSE (scalar if return_image is False, image if - return_image is True) - ''' - _check_shapes(im_ref, im_comp) - L2 = np.square(im_ref - im_comp) - if self.return_image: - return np.sqrt(L2) - else: - return np.sqrt(L2.mean())
    - -
    [docs]class SSIM: - '''Structural Similarity Index Measure between two images. Images must have - the same dimensions. Score given is 1 - SSIM to give the loss/dissimilarity - - Args: - return_image (bool): Whether to return the image (Defaults to False which - will return a scalar value) - ''' - def __init__(self, return_image=False): - self.return_image = return_image - self.metric = ssim_torch - self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - self.preproccess_function = _numpy_to_torch_image - -
    [docs] def __call__(self, im_ref, im_comp, sigma=1.5, k1=0.01, k2=0.03, ssim_kernel_size=11, **kwargs): - '''When an instance is called - - Args: - im_ref (np.array): Reference image - im_comp (np.array): Comparison image - **kwargs: Arbitrary keyword arguments - - Returns: - score (np.array): 1-SSIM (scalar if return_image is False, image if - return_image is True) - ''' - _check_shapes(im_ref, im_comp) - im_ref = self.preproccess_function(im_ref).to(device=self.device, dtype=torch.float) - im_comp = self.preproccess_function(im_comp).to(device=self.device, dtype=torch.float) - ssim_kernel_size = make_kernel_odd(ssim_kernel_size) - # set up metric - with warnings.catch_warnings(): # we don't care about the warnings these give - warnings.simplefilter("ignore") - if self.return_image: - _metric = self.metric( - sigma=sigma, k1=k1, k2=k2, return_full_image=True, reduction=None, kernel_size=ssim_kernel_size) - else: - _metric = self.metric(sigma=sigma, k1=k1, k2=k2, kernel_size=ssim_kernel_size) - _metric.to(self.device) - if self.return_image: - _, ssim_full_im = _metric(im_ref, im_comp) - ssim_full_im = torch.squeeze(ssim_full_im, axis=0) - ssim_full_im = ssim_full_im.permute(1, 2, 0) - ssim_full_im = torch.clip(ssim_full_im, 0, 1) - _score = ssim_full_im.cpu().detach().numpy() - else: - _score = _metric(im_ref, im_comp).cpu().detach().numpy() - _score = 1 - _score - _metric.reset() - return _score
    - -
    [docs]class MS_SSIM: - '''Multi-Scale Structural Similarity Index Measure between two images. - Images must have the same dimensions. Score given is 1 - MS_SSIM to give the - loss/dissimilarity. - Note that images of small size, below 180 pixels will have their kernel size - reduced for compatability with the 4 downsizing operations. - - Args: - return_image (bool): Whether to return the image (Defaults to False which - will return a scalar value) - ''' - def __init__(self, return_image=False): - self.return_image = return_image - # self.metric = Mssim_torch - self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - self.preproccess_function = _numpy_to_torch_image - -
    [docs] def __call__(self, im_ref, im_comp, sigma=1.5, k1=0.01, k2=0.03, mssim_kernel_size=11, ** kwargs): - '''When an instance is called - - Args: - im_ref (np.array): Reference image - im_comp (np.array): Comparison image - **kwargs: Arbitrary keyword arguments - - Returns: - score (np.array): 1-SSIM (scalar if return_image is False, image if - return_image is True) - ''' - _check_shapes(im_ref, im_comp) - im_ref = self.preproccess_function(im_ref).to(device=self.device, dtype=torch.float) - im_comp = self.preproccess_function(im_comp).to(device=self.device, dtype=torch.float) - mssim_kernel_size = make_kernel_odd(mssim_kernel_size) - success = False - reduced_kernel = False - run_error = False - while success == False and mssim_kernel_size > 0: - # _metric = self._make_metric(sigma=sigma, k1=k1, k2=k2, kernel_size=mssim_kernel_size) - try: - if self.return_image: - # _, ssim_full_im = _metric(im_ref, im_comp) - ssim_full_im = ms_ssim(im_ref, im_comp, - data_range=1, - win_size=mssim_kernel_size, - win_sigma=sigma, - K=(k1, k2), - return_image=True) - ssim_full_im = torch.squeeze(ssim_full_im, axis=0) - ssim_full_im = ssim_full_im.permute(1, 2, 0) - ssim_full_im = torch.clip(ssim_full_im, 0, 1) - _score = ssim_full_im.cpu().detach().numpy() - else: - _score = ms_ssim(im_ref, im_comp, - data_range=1, - win_size=mssim_kernel_size, - win_sigma=sigma, - K=(k1, k2), - size_average=True) - # _score = _metric(im_ref, im_comp).cpu().detach().numpy() - _score = 1 - _score.cpu().detach().numpy() # get score not similarity - success = True - except ValueError: - # get an error with small images that the torchmetrics package seems to advise the wrong larger than size for - reduced_kernel = True - mssim_kernel_size -= 2 - _score = 0 - except AssertionError: - # get an error with small images that the pytorch-ssim package seems to advise the wrong larger than size for - reduced_kernel = True - mssim_kernel_size -= 2 - _score = 0 - except RuntimeError: - run_error = True - success = True - _score = 0 - # _metric.reset() - if reduced_kernel == True: - print(f'NOTE: Reduced MS_SSIM kernel size to {mssim_kernel_size} to deal with image size {im_ref.shape}') - if run_error == True: - print(f'WARNING: Image size {im_ref.shape} too small to use with MS_SSIM, returning 0') - return _score
    - - def _make_metric(self, **kwargs): - # set up metric - with warnings.catch_warnings(): # we don't care about the warnings these give - warnings.simplefilter("ignore") - if self.return_image: - _metric = self.metric(**kwargs, - return_full_image=True, - reduction=None) - else: - _metric = self.metric(**kwargs) - _metric.to(self.device) - return _metric
    - - -
    [docs]class one_over_PSNR: - '''Peak signal to noise ratio - https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio - The score given is normalised between 0, 1 by taking 1/PSNR - - Args: - return_image (bool): Whether to return the image (Defaults to False which - will return a scalar value) - ''' - - def __init__(self): - self.metric = PSNRs - self.device = torch.device( - "cuda" if torch.cuda.is_available() else "cpu") - self.preproccess_function = _numpy_to_torch_image - self.initialised = False - -
    [docs] def __call__(self, im_ref, im_comp, **kwargs): - '''When an instance is called - - Args: - im_ref (np.array): Reference image - im_comp (np.array): Comparison image - **kwargs: Arbitrary keyword arguments - - Returns: - score (np.array): PSNR between the images - ''' - _check_shapes(im_ref, im_comp) - se = np.square(im_ref - im_comp) - mse = se.mean() - if mse == 0: - return 0 - psnr = 10 * np.log10(1/(mse)) - return 1/psnr
    - - # im_ref = self.preproccess_function(im_ref).to( - # device=self.device, dtype=torch.float) - # im_comp = self.preproccess_function(im_comp).to( - # device=self.device, dtype=torch.float) - # # set up metric - # if self.initialised == False: - # with warnings.catch_warnings(): # we don't care about the warnings these give - # warnings.simplefilter("ignore") - # self._metric = self.metric() - # self._metric.to(self.device) - # _score = self._metric(im_ref*255, im_comp*255).cpu().detach().numpy() - # _score = 1 - _score - # self._metric.reset() - # return _score/255 - -
    [docs]class LPIPS: - '''Learned Perceptual Image Patch Similarity between two images. - Images must have the same dimensions. - - Args: - network (str): Pretrained network to use. Choose between ‘alex’, ‘vgg’ - or ‘squeeze’. (Defaults to 'alex') - reduction (str): How to reduce over the batch dimension. Choose between - ‘sum’ or ‘mean’. (Defaults to 'mean') - - ''' - def __init__(self, network='alex', reduction='mean'): - self.initialised = False # initialse fully on first __call__ to save load up time - self.network = network - self.reduction = reduction - # self.metric = lpips_torch - self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - self.preproccess_function = _numpy_to_torch_image - -
    [docs] def __call__(self, im_ref, im_comp, **kwargs): - '''When an instance is called - - Args: - im_ref (np.array): Reference image - im_comp (np.array): Comparison image - **kwargs: Arbitrary keyword arguments - - Returns: - score (np.array): LPIPS score - ''' - if self.initialised == False: - with warnings.catch_warnings(): # we don't care about the warnings these give - warnings.simplefilter("ignore") - self.metric = lpips_torch(net_type=self.network, - reduction=self.reduction, - normalize=True) - self.metric.to(self.device) - self.initialised = True - _check_shapes(im_ref, im_comp) - im_ref = self.preproccess_function(im_ref).to(device=self.device, dtype=torch.float) - im_comp = self.preproccess_function(im_comp).to(device=self.device, dtype=torch.float) - with warnings.catch_warnings(): # warning because we have reset - warnings.simplefilter("ignore") - _score = self.metric(im_ref, im_comp) - score = _score.cpu().detach().numpy() - self.metric.reset() - return score
    - -
    [docs]class DISTS: - '''Deep Image Structure and Texture Similarity (DISTS) Metric. Uses the - code from https://github.com/dingkeyan93/DISTS. Uses the PyTorch backend. - It is robust to texture variance (e.g., evaluating the images generated - by GANs) and mild geometric transformations (e.g., evaluating the image - pairs that are not strictly point-by-point aligned). - - ''' - def __init__(self): - self.initialised = False # initialse fully on first __call__ to save load up time - self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - self.preproccess_function = _numpy_to_torch_image - -
    [docs] def __call__(self, im_ref, im_comp, **kwargs): - '''When an instance is called - - Args: - im_ref (np.array): Reference image - im_comp (np.array): Comparison image - **kwargs: Arbitrary keyword arguments - - Returns: - score (np.array): DISTS score - ''' - # load model on first time called - if self.initialised == False: - with warnings.catch_warnings(): # we don't care about the warnings these give - warnings.simplefilter("ignore") - self.metric = dists_original() - self.metric.to(self.device) - self.initialised = True - - _check_shapes(im_ref, im_comp) - im_ref = self.preproccess_function(im_ref).to(device=self.device, dtype=torch.float) - im_comp = self.preproccess_function(im_comp).to(device=self.device, dtype=torch.float) - _score = self.metric(im_ref, im_comp) - score = _score.cpu().detach().numpy() - return score
    - - -
    [docs]class NLPD: - '''Normalised Laplacian pyramid - Proposed by Valero Laparra et al. https://www.uv.es/lapeva/papers/2016_HVEI.pdf . - NLPD is an image quality metric based on the transformations associated with the - early visual system: local luminance subtraction and local gain control. - - ''' - - def __init__(self): - self.initialised = False # initialse fully on first __call__ to save load up time - self.device = torch.device( - "cuda" if torch.cuda.is_available() else "cpu") - self.preproccess_function = _numpy_to_torch_image - self.nlpd_k = 1 - -
    [docs] def __call__(self, im_ref, im_comp, nlpd_k=1, **kwargs): - '''When an instance is called - - Args: - im_ref (np.array): Reference image - im_comp (np.array): Comparison image - **kwargs: Arbitrary keyword arguments - - Returns: - score (np.array): NLPD score - ''' - # see if k has changed - if self.nlpd_k != nlpd_k: - self.nlpd_k = nlpd_k - self.initialised = False - # load model on first time called - if self.initialised == False: - with warnings.catch_warnings(): # we don't care about the warnings these give - warnings.simplefilter("ignore") - self.metric = LaplacianPyramid(self.nlpd_k) - self.metric.to(self.device) - self.initialised = True - - _check_shapes(im_ref, im_comp) - im_ref = self.preproccess_function(im_ref).to( - device=self.device, dtype=torch.float) - im_comp = self.preproccess_function(im_comp).to( - device=self.device, dtype=torch.float) - _score = self.metric(im_ref, im_comp) - score = _score.cpu().detach().numpy() - return score
    - - -''' ============================================================================ ''' -''' TO ADD TO DEMOS''' -''' simple functional format to call a metric (numpy)''' -def _MAE(im_ref, im_comp, **kwargs): - '''Mean Absolute Error between two images. Images must have the same - dimensions - - Args: - im_ref (np.array): Reference image - im_comp (np.array): Comparison image - **kwargs: Arbitrary keyword arguments - - Returns: - mean (np.array): scalar of MAE - ''' - _check_shapes(im_ref, im_comp) - L1 = np.abs(im_ref - im_comp) - return L1.mean() - -''' functional (using torch)''' -def _MSE(im_ref, im_comp, **kwargs): - _check_shapes(im_ref, im_comp) - metric = nn.MSELoss() - device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - im_ref = _numpy_to_torch_image(im_ref).to(device=device, dtype=torch.float) - im_comp = _numpy_to_torch_image(im_comp).to(device=device, dtype=torch.float) - _score = metric(im_ref, im_comp) - return _score.cpu().detach().numpy() - -''' can also call as a class to input default args (using torch)''' - - - -'''Example of metric image produced to display (using numpy)''' -def _MSE_image(im_ref, im_comp, **kwargs): - _check_shapes(im_ref, im_comp) - L2 = (im_ref - im_comp)**2 - return L2 - - - - -''' -Helper functions for metric computation -''' -def _numpy_to_torch_image(image): - if len(image.shape) == 2: - image = np.expand_dims(image, axis=2) - image = image.transpose((2, 0, 1)) - image = np.expand_dims(image, axis=0) # make into batch one 1 - image = torch.from_numpy(image) - return image - -def _check_shapes(im_ref, im_comp): - ''' - make sure both images have the same dimensions - ''' - if im_ref.shape != im_comp.shape: - raise ValueError(f'Refence and transformed images need to have the same shape not: {im_ref.shape} and {im_comp.shape}') - -
    [docs]def make_kernel_odd(value): - value = int(value) - if value % 2 == 0: - value -= 1 - if value <= 0: - value = 1 - return value
    -
    - -
    -
    - -
    -
    -
    -
    - - - - \ No newline at end of file diff --git a/docs/_build/html/_modules/IQM_Vis/metrics/non_perceptual.html b/docs/_build/html/_modules/IQM_Vis/metrics/non_perceptual.html new file mode 100644 index 0000000..3477a6b --- /dev/null +++ b/docs/_build/html/_modules/IQM_Vis/metrics/non_perceptual.html @@ -0,0 +1,268 @@ + + + + + + IQM_Vis.metrics.non_perceptual — IQM-Vis 0.2 documentation + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +

    Source code for IQM_Vis.metrics.non_perceptual

    +# Author: Matt Clifford <matt.clifford@bristol.ac.uk>
    +# License: BSD 3-Clause License
    +import numpy as np
    +
    +# from torchmetrics import PeakSignalNoiseRatio as PSNRs
    +from IQM_Vis.metrics.metric_utils import _check_shapes
    +
    +
    [docs]class MAE: + '''Mean Absolute Error between two images. Images must have the same + dimensions + + Args: + return_image (bool): Whether to return the image (Defaults to False which + will return a scalar value) + ''' + + def __init__(self, return_image=False): + self.return_image = return_image + +
    [docs] def __call__(self, im_ref, im_comp, **kwargs): + '''When an instance is called + + Args: + im_ref (np.array): Reference image + im_comp (np.array): Comparison image + **kwargs: Arbitrary keyword arguments + + Returns: + score (np.array): MAE (scalar if return_image is False, image if + return_image is True) + ''' + _check_shapes(im_ref, im_comp) + L1 = np.abs(im_ref - im_comp) + if self.return_image: + return L1 + else: + return L1.mean()
    + + +
    [docs]class MSE: + '''Mean Squared Error between two images. Images must have the same + dimensions + + Args: + return_image (bool): Whether to return the image (Defaults to False which + will return a scalar value) + ''' + + def __init__(self, return_image=False): + self.return_image = return_image + +
    [docs] def __call__(self, im_ref, im_comp, **kwargs): + '''When an instance is called + + Args: + im_ref (np.array): Reference image + im_comp (np.array): Comparison image + **kwargs: Arbitrary keyword arguments + + Returns: + score (np.array): MSE (scalar if return_image is False, image if + return_image is True) + ''' + _check_shapes(im_ref, im_comp) + L2 = np.square(im_ref - im_comp) + if self.return_image: + return L2 + else: + return L2.mean()
    + + +
    [docs]class RMSE: + '''Root Mean Squared Error between two images. Images must have the same + dimensions + + Args: + return_image (bool): Whether to return the image (Defaults to False which + will return a scalar value) + ''' + + def __init__(self, return_image=False): + self.return_image = return_image + +
    [docs] def __call__(self, im_ref, im_comp, **kwargs): + '''When an instance is called + + Args: + im_ref (np.array): Reference image + im_comp (np.array): Comparison image + **kwargs: Arbitrary keyword arguments + + Returns: + score (np.array): RMSE (scalar if return_image is False, image if + return_image is True) + ''' + _check_shapes(im_ref, im_comp) + L2 = np.square(im_ref - im_comp) + if self.return_image: + return np.sqrt(L2) + else: + return np.sqrt(L2.mean())
    + + +
    [docs]class one_over_PSNR: + '''Peak signal to noise ratio - https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio + The score given is normalised between 0, 1 by taking 1/PSNR + + Args: + return_image (bool): Whether to return the image (Defaults to False which + will return a scalar value) + ''' + + def __init__(self): + self.initialised = False + # self.metric = PSNRs + # self.device = torch.device( + # "cuda" if torch.cuda.is_available() else "cpu") + # self.preproccess_function = _numpy_to_torch_image + +
    [docs] def __call__(self, im_ref, im_comp, **kwargs): + '''When an instance is called + + Args: + im_ref (np.array): Reference image + im_comp (np.array): Comparison image + **kwargs: Arbitrary keyword arguments + + Returns: + score (np.array): PSNR between the images + ''' + _check_shapes(im_ref, im_comp) + se = np.square(im_ref - im_comp) + mse = se.mean() + if mse == 0: + return 0 + psnr = 10 * np.log10(1/(mse)) + return 1/psnr
    + + # im_ref = self.preproccess_function(im_ref).to( + # device=self.device, dtype=torch.float) + # im_comp = self.preproccess_function(im_comp).to( + # device=self.device, dtype=torch.float) + # # set up metric + # if self.initialised == False: + # with warnings.catch_warnings(): # we don't care about the warnings these give + # warnings.simplefilter("ignore") + # self._metric = self.metric() + # self._metric.to(self.device) + # _score = self._metric(im_ref*255, im_comp*255).cpu().detach().numpy() + # _score = 1 - _score + # self._metric.reset() + # return _score/255 +
    + +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/IQM_Vis/metrics/perceptual_DL.html b/docs/_build/html/_modules/IQM_Vis/metrics/perceptual_DL.html new file mode 100644 index 0000000..a39665c --- /dev/null +++ b/docs/_build/html/_modules/IQM_Vis/metrics/perceptual_DL.html @@ -0,0 +1,221 @@ + + + + + + IQM_Vis.metrics.perceptual_DL — IQM-Vis 0.2 documentation + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +

    Source code for IQM_Vis.metrics.perceptual_DL

    +# Author: Matt Clifford <matt.clifford@bristol.ac.uk>
    +# License: BSD 3-Clause License
    +import warnings
    +import torch
    +
    +from torchmetrics.image.lpip import LearnedPerceptualImagePatchSimilarity as lpips_torch
    +from DISTS_pytorch import DISTS as dists_original
    +from IQM_Vis.metrics.metric_utils import _check_shapes, _numpy_to_torch_image
    +
    +
    +
    [docs]class LPIPS: + '''Learned Perceptual Image Patch Similarity between two images. + Images must have the same dimensions. + + Args: + network (str): Pretrained network to use. Choose between ‘alex’, ‘vgg’ + or ‘squeeze’. (Defaults to 'alex') + reduction (str): How to reduce over the batch dimension. Choose between + ‘sum’ or ‘mean’. (Defaults to 'mean') + + ''' + + def __init__(self, network='alex', reduction='mean'): + self.initialised = False # initialse fully on first __call__ to save load up time + self.network = network + self.reduction = reduction + # self.metric = lpips_torch + self.device = torch.device( + "cuda" if torch.cuda.is_available() else "cpu") + self.preproccess_function = _numpy_to_torch_image + +
    [docs] def __call__(self, im_ref, im_comp, **kwargs): + '''When an instance is called + + Args: + im_ref (np.array): Reference image + im_comp (np.array): Comparison image + **kwargs: Arbitrary keyword arguments + + Returns: + score (np.array): LPIPS score + ''' + if self.initialised == False: + with warnings.catch_warnings(): # we don't care about the warnings these give + warnings.simplefilter("ignore") + self.metric = lpips_torch(net_type=self.network, + reduction=self.reduction, + normalize=True) + self.metric.to(self.device) + self.initialised = True + _check_shapes(im_ref, im_comp) + im_ref = self.preproccess_function(im_ref).to( + device=self.device, dtype=torch.float) + im_comp = self.preproccess_function(im_comp).to( + device=self.device, dtype=torch.float) + with warnings.catch_warnings(): # warning because we have reset + warnings.simplefilter("ignore") + _score = self.metric(im_ref, im_comp) + score = _score.cpu().detach().numpy() + self.metric.reset() + return score
    + + +
    [docs]class DISTS: + '''Deep Image Structure and Texture Similarity (DISTS) Metric. Uses the + code from https://github.com/dingkeyan93/DISTS. Uses the PyTorch backend. + It is robust to texture variance (e.g., evaluating the images generated + by GANs) and mild geometric transformations (e.g., evaluating the image + pairs that are not strictly point-by-point aligned). + + ''' + + def __init__(self): + self.initialised = False # initialse fully on first __call__ to save load up time + self.device = torch.device( + "cuda" if torch.cuda.is_available() else "cpu") + self.preproccess_function = _numpy_to_torch_image + +
    [docs] def __call__(self, im_ref, im_comp, **kwargs): + '''When an instance is called + + Args: + im_ref (np.array): Reference image + im_comp (np.array): Comparison image + **kwargs: Arbitrary keyword arguments + + Returns: + score (np.array): DISTS score + ''' + # load model on first time called + if self.initialised == False: + with warnings.catch_warnings(): # we don't care about the warnings these give + warnings.simplefilter("ignore") + self.metric = dists_original() + self.metric.to(self.device) + self.initialised = True + + _check_shapes(im_ref, im_comp) + im_ref = self.preproccess_function(im_ref).to( + device=self.device, dtype=torch.float) + im_comp = self.preproccess_function(im_comp).to( + device=self.device, dtype=torch.float) + _score = self.metric(im_ref, im_comp) + score = _score.cpu().detach().numpy() + return score
    +
    + +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/IQM_Vis/metrics/perceptual_trad.html b/docs/_build/html/_modules/IQM_Vis/metrics/perceptual_trad.html new file mode 100644 index 0000000..f8cc02f --- /dev/null +++ b/docs/_build/html/_modules/IQM_Vis/metrics/perceptual_trad.html @@ -0,0 +1,341 @@ + + + + + + IQM_Vis.metrics.perceptual_trad — IQM-Vis 0.2 documentation + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +

    Source code for IQM_Vis.metrics.perceptual_trad

    +# Author: Matt Clifford <matt.clifford@bristol.ac.uk>
    +# License: BSD 3-Clause License
    +import warnings
    +import torch 
    +
    +from torchmetrics import StructuralSimilarityIndexMeasure as ssim_torch
    +from IQM_Vis.metrics.SSIM.ssim import ms_ssim
    +from IQM_Vis.metrics.NLPD_torch.pyramids import LaplacianPyramid
    +from IQM_Vis.metrics.metric_utils import _check_shapes, _numpy_to_torch_image
    +
    +
    +
    [docs]class SSIM: + '''Structural Similarity Index Measure between two images. Images must have + the same dimensions. Score given is 1 - SSIM to give the loss/dissimilarity + + Args: + return_image (bool): Whether to return the image (Defaults to False which + will return a scalar value) + ''' + + def __init__(self, return_image=False): + self.return_image = return_image + self.metric = ssim_torch + self.device = torch.device( + "cuda" if torch.cuda.is_available() else "cpu") + self.preproccess_function = _numpy_to_torch_image + +
    [docs] def __call__(self, im_ref, im_comp, sigma=1.5, k1=0.01, k2=0.03, ssim_kernel_size=11, **kwargs): + '''When an instance is called + + Args: + im_ref (np.array): Reference image + im_comp (np.array): Comparison image + **kwargs: Arbitrary keyword arguments + + Returns: + score (np.array): 1-SSIM (scalar if return_image is False, image if + return_image is True) + ''' + _check_shapes(im_ref, im_comp) + im_ref = self.preproccess_function(im_ref).to( + device=self.device, dtype=torch.float) + im_comp = self.preproccess_function(im_comp).to( + device=self.device, dtype=torch.float) + ssim_kernel_size = _make_kernel_odd(ssim_kernel_size) + # set up metric + with warnings.catch_warnings(): # we don't care about the warnings these give + warnings.simplefilter("ignore") + if self.return_image: + _metric = self.metric( + sigma=sigma, k1=k1, k2=k2, return_full_image=True, reduction=None, kernel_size=ssim_kernel_size) + else: + _metric = self.metric(sigma=sigma, k1=k1, + k2=k2, kernel_size=ssim_kernel_size) + _metric.to(self.device) + if self.return_image: + _, ssim_full_im = _metric(im_ref, im_comp) + ssim_full_im = torch.squeeze(ssim_full_im, axis=0) + ssim_full_im = ssim_full_im.permute(1, 2, 0) + ssim_full_im = torch.clip(ssim_full_im, 0, 1) + _score = ssim_full_im.cpu().detach().numpy() + else: + _score = _metric(im_ref, im_comp).cpu().detach().numpy() + _score = 1 - _score + _metric.reset() + return _score
    + + +
    [docs]class MS_SSIM: + '''Multi-Scale Structural Similarity Index Measure between two images. + Images must have the same dimensions. Score given is 1 - MS_SSIM to give the + loss/dissimilarity. + Note that images of small size, below 180 pixels will have their kernel size + reduced for compatability with the 4 downsizing operations. + + Args: + return_image (bool): Whether to return the image (Defaults to False which + will return a scalar value) + ''' + + def __init__(self, return_image=False): + self.return_image = return_image + # self.metric = Mssim_torch + self.device = torch.device( + "cuda" if torch.cuda.is_available() else "cpu") + self.preproccess_function = _numpy_to_torch_image + +
    [docs] def __call__(self, im_ref, im_comp, sigma=1.5, k1=0.01, k2=0.03, mssim_kernel_size=11, ** kwargs): + '''When an instance is called + + Args: + im_ref (np.array): Reference image + im_comp (np.array): Comparison image + **kwargs: Arbitrary keyword arguments + + Returns: + score (np.array): 1-SSIM (scalar if return_image is False, image if + return_image is True) + ''' + _check_shapes(im_ref, im_comp) + im_ref = self.preproccess_function(im_ref).to( + device=self.device, dtype=torch.float) + im_comp = self.preproccess_function(im_comp).to( + device=self.device, dtype=torch.float) + mssim_kernel_size = _make_kernel_odd(mssim_kernel_size) + success = False + reduced_kernel = False + run_error = False + while success == False and mssim_kernel_size > 0: + # _metric = self._make_metric(sigma=sigma, k1=k1, k2=k2, kernel_size=mssim_kernel_size) + try: + if self.return_image: + # _, ssim_full_im = _metric(im_ref, im_comp) + ssim_full_im = ms_ssim(im_ref, im_comp, + data_range=1, + win_size=mssim_kernel_size, + win_sigma=sigma, + K=(k1, k2), + return_image=True) + ssim_full_im = torch.squeeze(ssim_full_im, axis=0) + ssim_full_im = ssim_full_im.permute(1, 2, 0) + ssim_full_im = torch.clip(ssim_full_im, 0, 1) + _score = ssim_full_im.cpu().detach().numpy() + else: + _score = ms_ssim(im_ref, im_comp, + data_range=1, + win_size=mssim_kernel_size, + win_sigma=sigma, + K=(k1, k2), + size_average=True) + # _score = _metric(im_ref, im_comp).cpu().detach().numpy() + _score = 1 - _score.cpu().detach().numpy() # get score not similarity + success = True + except ValueError: + # get an error with small images that the torchmetrics package seems to advise the wrong larger than size for + reduced_kernel = True + mssim_kernel_size -= 2 + _score = 0 + except AssertionError: + # get an error with small images that the pytorch-ssim package seems to advise the wrong larger than size for + reduced_kernel = True + mssim_kernel_size -= 2 + _score = 0 + except RuntimeError: + run_error = True + success = True + _score = 0 + # _metric.reset() + if reduced_kernel == True: + print( + f'NOTE: Reduced MS_SSIM kernel size to {mssim_kernel_size} to deal with image size {im_ref.shape}') + if run_error == True: + print( + f'WARNING: Image size {im_ref.shape} too small to use with MS_SSIM, returning 0') + return _score
    + + def _make_metric(self, **kwargs): + # set up metric + with warnings.catch_warnings(): # we don't care about the warnings these give + warnings.simplefilter("ignore") + if self.return_image: + _metric = self.metric(**kwargs, + return_full_image=True, + reduction=None) + else: + _metric = self.metric(**kwargs) + _metric.to(self.device) + return _metric
    + + +
    [docs]class NLPD: + '''Normalised Laplacian pyramid + Proposed by Valero Laparra et al. https://www.uv.es/lapeva/papers/2016_HVEI.pdf . + NLPD is an image quality metric based on the transformations associated with the + early visual system: local luminance subtraction and local gain control. + + ''' + + def __init__(self): + self.initialised = False # initialse fully on first __call__ to save load up time + self.device = torch.device( + "cuda" if torch.cuda.is_available() else "cpu") + self.preproccess_function = _numpy_to_torch_image + self.nlpd_k = 1 + +
    [docs] def __call__(self, im_ref, im_comp, nlpd_k=1, **kwargs): + '''When an instance is called + + Args: + im_ref (np.array): Reference image + im_comp (np.array): Comparison image + **kwargs: Arbitrary keyword arguments + + Returns: + score (np.array): NLPD score + ''' + # see if k has changed + if self.nlpd_k != nlpd_k: + self.nlpd_k = nlpd_k + self.initialised = False + # load model on first time called + if self.initialised == False: + with warnings.catch_warnings(): # we don't care about the warnings these give + warnings.simplefilter("ignore") + self.metric = LaplacianPyramid(self.nlpd_k) + self.metric.to(self.device) + self.initialised = True + + _check_shapes(im_ref, im_comp) + im_ref = self.preproccess_function(im_ref).to( + device=self.device, dtype=torch.float) + im_comp = self.preproccess_function(im_comp).to( + device=self.device, dtype=torch.float) + _score = self.metric(im_ref, im_comp) + score = _score.cpu().detach().numpy() + return score
    + + +def _make_kernel_odd(value): + value = int(value) + if value % 2 == 0: + value -= 1 + if value <= 0: + value = 1 + return value +
    + +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/IQM_Vis/transforms.html b/docs/_build/html/_modules/IQM_Vis/transforms.html index fc3142d..fec9247 100644 --- a/docs/_build/html/_modules/IQM_Vis/transforms.html +++ b/docs/_build/html/_modules/IQM_Vis/transforms.html @@ -108,9 +108,9 @@

    Source code for IQM_Vis.transforms

             'hue': {'min': -0.5, 'max': 0.5, 'function': hue},
             'saturation': {'min': -0.5, 'max': 0.5, 'function': saturation},
             # 'brightness_hsv': {'min': -1.0, 'max': 1, 'function': brightness_hsv},
    -        'blur':{'min':1, 'max':41, 'normalise':'odd', 'function':blur},
    -        'Gaussian Noise': {'init_value': 0.0, 'min': 0.0, 'max': 0.5, 'function': Gaussian_noise},
    -        'noise hypersphere': {'init_value': 0.0, 'min': 0.0, 'max': 5.0, 'function': noise_hypersphere},
    +        'blur': {'init_value': 1, 'min': 1, 'max': 41, 'normalise': 'odd', 'function': blur},
    +        'Gaussian Noise': {'init_value': 0.0, 'min': 0.0, 'max': 0.5, 'function': Gaussian_noise()},
    +        'noise hypersphere': {'init_value': 0.0, 'min': 0.0, 'max': 5.0, 'function': noise_hypersphere()},
             'salt pepper': {'init_value': 0.0, 'min': 0.0, 'max': 0.05, 'function': salt_and_pepper_noise},
             'jpg comp.':{'init_value':101, 'min':1, 'max':101, 'function':jpeg_compression},
             'rotation':{'min':-180, 'max':180, 'function':rotation},
    diff --git a/docs/_build/html/_modules/IQM_Vis/transforms/additive_noise.html b/docs/_build/html/_modules/IQM_Vis/transforms/additive_noise.html
    index acbf7ff..1e1d196 100644
    --- a/docs/_build/html/_modules/IQM_Vis/transforms/additive_noise.html
    +++ b/docs/_build/html/_modules/IQM_Vis/transforms/additive_noise.html
    @@ -116,7 +116,7 @@ 

    Source code for IQM_Vis.transforms.additive_noise

    # must return x_noisey, additive_noise pass - def __call__(self, img, param=None): + def __call__(self, img, param=0): ''' will return a noisy image with noise level according to 'param' highest noise will be returned if noise level is too low acccording to acceptable_percent @@ -133,7 +133,7 @@

    Source code for IQM_Vis.transforms.additive_noise

    will return the highest noise level if noise level is too low acccording to acceptable_percent ''' for _ in range(self.max_iter): - x_noisey, additive_noise = self._make_noisey_image(img, np=np) + x_noisey, additive_noise = self._make_noisey_image(img) # check noise level and actual noise level reduced after clipping expected_noise = np.sqrt(np.mean(np.square(additive_noise))) if self.reject_low_noise == False: @@ -169,7 +169,7 @@

    Source code for IQM_Vis.transforms.additive_noise

    def _make_noisey_image(self, img): if self.param <= 0: - return img, 0 + return img, 0.0 if self.seed: np.random.seed(42) noise = np.random.randn(*img.shape) @@ -197,7 +197,7 @@

    Source code for IQM_Vis.transforms.additive_noise

    def _make_noisey_image(self, img): if self.param <= 0: - return img, 0 + return img, 0.0 if self.seed: np.random.seed(42) additive_noise = np.random.normal( @@ -240,6 +240,14 @@

    Source code for IQM_Vis.transforms.additive_noise

    image[probs < (prob / 2)] = black image[probs > 1 - (prob / 2)] = white return np.clip(image, 0, 1)
    + + +if __name__ == '__main__': + import numpy as np + image = np.random.rand(256, 256, 3) + noise = Gaussian_noise() + noise(image, 0) + # noise(image, 0.1)
    diff --git a/docs/_build/html/_modules/IQM_Vis/transforms/effects.html b/docs/_build/html/_modules/IQM_Vis/transforms/effects.html index 3fdcb38..c767623 100644 --- a/docs/_build/html/_modules/IQM_Vis/transforms/effects.html +++ b/docs/_build/html/_modules/IQM_Vis/transforms/effects.html @@ -133,14 +133,14 @@

    Source code for IQM_Vis.transforms.effects

         return np.clip(image.astype(np.float32) / 255.0, 0, 1)
    -
    [docs]def jpeg_compression(image, compression=90): +
    [docs]def jpeg_compression(image, compression=101): '''encode image using jpeg then decode Args: image (np.array): image to be compressed compression (int): amount of jpeg compression, higher is better quality. 101 returns identity image. - (Defaults to 90) + (Defaults to 101) Returns: image (np.array): jpeg compressed image @@ -272,13 +272,14 @@

    Source code for IQM_Vis.transforms.effects

         return np.clip(cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)/255, 0, 1)
     
     
    -
    [docs]def blur(image, kernel_size=7): +
    [docs]def blur(image, kernel_size=1): '''Gaussian Blur on an image Args: image (np.array): image to be rotated kernel_size (int): size of the convolutional kernel, will be converted - to an odd number. (Defaults to 7) + to an odd number. 1 is no blur. + (Defaults to 1) Returns: image (np.array): rotated image diff --git a/docs/_build/html/_modules/index.html b/docs/_build/html/_modules/index.html index f925c07..bc7adda 100644 --- a/docs/_build/html/_modules/index.html +++ b/docs/_build/html/_modules/index.html @@ -101,8 +101,10 @@

    All modules for which code is available

  • IQM_Vis.examples.new_api
  • IQM_Vis.examples.simple
  • IQM_Vis.metrics
  • - +
    • IQM_Vis.metrics.SSIM.ssim @@ -636,8 +659,6 @@

      I

    • module
    - - @@ -836,15 +857,13 @@

    L

    M

    @@ -965,7 +990,7 @@

    M

    N

      @@ -977,7 +1002,7 @@

      N

      O

      + + + + + + + + + diff --git a/docs/_build/html/searchindex.js b/docs/_build/html/searchindex.js index 4e358a6..9d5f259 100644 --- a/docs/_build/html/searchindex.js +++ b/docs/_build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["IQM_Vis","IQM_Vis.UI","IQM_Vis.data_handlers","IQM_Vis.examples","IQM_Vis.examples.images","IQM_Vis.metrics","IQM_Vis.metrics.SSIM","IQM_Vis.transforms","IQM_Vis.utils","Tutorials","about","getting_started","index","modules","notebooks/Tutorial_1-making_the_UI","notebooks/Tutorial_2-Customisation","notebooks/Tutorial_3-Advanced-Customisations","notebooks/Tutorial_4-running_an_experiment","what-are-IQMs"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":5,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.viewcode":1,nbsphinx:4,sphinx:56},filenames:["IQM_Vis.rst","IQM_Vis.UI.rst","IQM_Vis.data_handlers.rst","IQM_Vis.examples.rst","IQM_Vis.examples.images.rst","IQM_Vis.metrics.rst","IQM_Vis.metrics.SSIM.rst","IQM_Vis.transforms.rst","IQM_Vis.utils.rst","Tutorials.rst","about.rst","getting_started.rst","index.rst","modules.rst","notebooks/Tutorial_1-making_the_UI.ipynb","notebooks/Tutorial_2-Customisation.ipynb","notebooks/Tutorial_3-Advanced-Customisations.ipynb","notebooks/Tutorial_4-running_an_experiment.ipynb","what-are-IQMs.rst"],objects:{"":[[0,0,0,"-","IQM_Vis"]],"IQM_Vis.UI":[[1,0,0,"-","custom_widgets"],[1,0,0,"-","experiment_mode"],[1,0,0,"-","images"],[1,0,0,"-","layout"],[1,0,0,"-","main"],[1,0,0,"-","threads"],[1,0,0,"-","utils"],[1,0,0,"-","widgets"]],"IQM_Vis.UI.custom_widgets":[[1,1,1,"","ClickLabel"],[1,1,1,"","ProgressBar"]],"IQM_Vis.UI.custom_widgets.ClickLabel":[[1,2,1,"","clicked"],[1,3,1,"","mousePressEvent"]],"IQM_Vis.UI.experiment_mode":[[1,1,1,"","make_experiment"],[1,1,1,"","reset_image_widget_to_black"],[1,4,1,"","sort_list"]],"IQM_Vis.UI.experiment_mode.make_experiment":[[1,3,1,"","calc_max_comparisons"],[1,3,1,"","change_experiment_images"],[1,3,1,"","click_completed"],[1,3,1,"","clicked_image"],[1,3,1,"","closeEvent"],[1,3,1,"","experiment_layout"],[1,3,1,"","finish_experiment"],[1,3,1,"","get_all_images"],[1,3,1,"","get_metric_scores"],[1,3,1,"","get_single_transform_im"],[1,3,1,"","init_style"],[1,3,1,"","partition"],[1,3,1,"","quick_sort"],[1,3,1,"","quit"],[1,2,1,"","reset_clicked_image"],[1,3,1,"","reset_experiment"],[1,3,1,"","save_experiment"],[1,2,1,"","saved_experiment"],[1,3,1,"","setup_experiment"],[1,3,1,"","show_all_images"],[1,3,1,"","start_experiment"],[1,3,1,"","swap_inds"],[1,3,1,"","toggle_experiment"]],"IQM_Vis.UI.experiment_mode.reset_image_widget_to_black":[[1,3,1,"","change_to_solid"],[1,2,1,"","completed"],[1,3,1,"","stop"]],"IQM_Vis.UI.images":[[1,1,1,"","images"],[1,4,1,"","message_on_plot"]],"IQM_Vis.UI.images.images":[[1,3,1,"","change_data"],[1,3,1,"","change_data_click_im"],[1,3,1,"","change_metric_correlations_graph"],[1,3,1,"","change_metric_range_graph"],[1,3,1,"","change_preview_images"],[1,3,1,"","change_to_data_num"],[1,3,1,"","change_to_specific_trans"],[1,3,1,"","completed_range_results"],[1,3,1,"","display_images"],[1,3,1,"","display_metric_correlation_plot"],[1,3,1,"","display_metric_images"],[1,3,1,"","display_metric_range_plot"],[1,3,1,"","display_metrics"],[1,3,1,"","display_metrics_graph"],[1,3,1,"","display_metrics_text"],[1,3,1,"","display_radar_plots"],[1,3,1,"","get_metrics_over_all_trans_with_init_values"],[1,3,1,"","init_worker_thread"],[1,3,1,"","load_experiment_from_dir"],[1,3,1,"","load_human_experiment"],[1,3,1,"","load_new_images_folder"],[1,3,1,"","load_new_single_image"],[1,3,1,"","plot_metric_range_mlp"],[1,3,1,"","plot_radar_graph"],[1,3,1,"","plot_radar_mlp"],[1,3,1,"","redo_plots"],[1,2,1,"","request_range_work"],[1,3,1,"","set_preview_images"],[1,3,1,"","set_save_dir_mpl"],[1,3,1,"","stopped_range_worker"],[1,3,1,"","update_datastore_image_list"],[1,2,1,"","view_correlation_instance"]],"IQM_Vis.UI.layout":[[1,1,1,"","layout"]],"IQM_Vis.UI.layout.layout":[[1,3,1,"","init_layout"],[1,3,1,"","init_style"]],"IQM_Vis.UI.main":[[1,1,1,"","make_app"],[1,4,1,"","set_checked_menu_from_iterable"]],"IQM_Vis.UI.main.make_app":[[1,3,1,"","change_save_folder"],[1,3,1,"","clear_all_cache_data"],[1,3,1,"","closeEvent"],[1,3,1,"","construct_UI"],[1,3,1,"","get_menu_checkboxes"],[1,3,1,"","load_all_metric_images"],[1,3,1,"","load_all_metrics"],[1,3,1,"","load_all_transforms"],[1,3,1,"","make_menu"],[1,3,1,"","make_status_bar"],[1,3,1,"","quit"],[1,3,1,"","reset_correlation_data"]],"IQM_Vis.UI.threads":[[1,1,1,"","get_range_results_worker"]],"IQM_Vis.UI.threads.get_range_results_worker":[[1,2,1,"","completed"],[1,2,1,"","current_image"],[1,3,1,"","do_work"],[1,2,1,"","progress"],[1,3,1,"","stop"],[1,2,1,"","stopped"]],"IQM_Vis.UI.utils":[[1,4,1,"","add_layout_to_tab"]],"IQM_Vis.UI.widgets":[[1,1,1,"","custom_float_validator"],[1,4,1,"","get_float_validator"],[1,4,1,"","is_almost_float"],[1,4,1,"","is_float"],[1,4,1,"","make_float_from_text"],[1,1,1,"","widgets"]],"IQM_Vis.UI.widgets.custom_float_validator":[[1,3,1,"","validate"]],"IQM_Vis.UI.widgets.widgets":[[1,3,1,"","change_display_im_display_brightness"],[1,3,1,"","change_display_im_rgb_brightness"],[1,3,1,"","change_display_im_size"],[1,3,1,"","change_graph_size"],[1,3,1,"","change_human_scores_after_exp"],[1,3,1,"","change_num_steps"],[1,3,1,"","change_plot_lims"],[1,3,1,"","change_post_processing"],[1,3,1,"","change_pre_processing"],[1,3,1,"","change_text_exp_trans"],[1,3,1,"","change_text_export_trans"],[1,3,1,"","colour_lineedit"],[1,3,1,"","disable_settings_button"],[1,3,1,"","display_slider_num"],[1,3,1,"","edit_slider_vals"],[1,3,1,"","enable_settings_button"],[1,3,1,"","export_trans_images"],[1,3,1,"","generic_value_change"],[1,3,1,"","init_widgets"],[1,3,1,"","launch_experiment"],[1,3,1,"","make_slider_range"],[1,3,1,"","open_mlp_new"],[1,3,1,"","reset_slider_group"],[1,3,1,"","reset_sliders"],[1,3,1,"","set_image_name_text"],[1,3,1,"","update_image_settings"],[1,3,1,"","update_progress"],[1,3,1,"","update_status_bar"]],"IQM_Vis.data_handlers":[[2,0,0,"-","data_api"],[2,0,0,"-","data_api_abstract"]],"IQM_Vis.data_handlers.data_api":[[2,1,1,"","cache_metric_call"],[2,4,1,"","cache_tracked"],[2,1,1,"","dataset_holder"],[2,4,1,"","get_image_name"]],"IQM_Vis.data_handlers.data_api.cache_metric_call":[[2,3,1,"","__call__"]],"IQM_Vis.data_handlers.data_api.dataset_holder":[[2,3,1,"","add_metric"],[2,3,1,"","add_metric_image"],[2,3,1,"","clear_all_cache"],[2,3,1,"","get_image_dataset_list"],[2,3,1,"","get_image_to_transform"],[2,3,1,"","get_image_to_transform_name"],[2,3,1,"","get_metric_images"],[2,3,1,"","get_metrics"],[2,3,1,"","get_reference_image"],[2,3,1,"","get_reference_image_by_index"],[2,3,1,"","get_reference_image_name"],[2,3,1,"","get_reference_unprocessed"],[2,3,1,"","load_image_list"]],"IQM_Vis.data_handlers.data_api_abstract":[[2,1,1,"","base_dataloader"],[2,1,1,"","base_dataset_loader"]],"IQM_Vis.data_handlers.data_api_abstract.base_dataloader":[[2,3,1,"","get_image_to_transform"],[2,3,1,"","get_image_to_transform_name"],[2,3,1,"","get_metric_images"],[2,3,1,"","get_metrics"],[2,3,1,"","get_reference_image"],[2,3,1,"","get_reference_image_name"],[2,5,1,"","metric_images"],[2,5,1,"","metrics"]],"IQM_Vis.data_handlers.data_api_abstract.base_dataset_loader":[[2,3,1,"","get_reference_image_by_index"]],"IQM_Vis.examples":[[3,0,0,"-","all"],[3,0,0,"-","dataset"],[3,0,0,"-","dists"],[3,0,0,"-","experiment"],[4,0,0,"-","images"],[3,0,0,"-","kodak"],[3,0,0,"-","multiple"],[3,0,0,"-","new_api"],[3,0,0,"-","simple"]],"IQM_Vis.examples.all":[[3,4,1,"","run"]],"IQM_Vis.examples.dataset":[[3,4,1,"","run"]],"IQM_Vis.examples.dists":[[3,4,1,"","correct"],[3,4,1,"","load_and_calibrate_image"],[3,4,1,"","run"]],"IQM_Vis.examples.experiment":[[3,4,1,"","run"]],"IQM_Vis.examples.kodak":[[3,4,1,"","run"]],"IQM_Vis.examples.multiple":[[3,4,1,"","run"]],"IQM_Vis.examples.new_api":[[3,4,1,"","run"]],"IQM_Vis.examples.simple":[[3,4,1,"","run"]],"IQM_Vis.metrics":[[5,0,0,"-","IQMs"],[6,0,0,"-","SSIM"],[5,4,1,"","get_all_IQM_params"],[5,4,1,"","get_all_metric_images"],[5,4,1,"","get_all_metrics"]],"IQM_Vis.metrics.IQMs":[[5,1,1,"","DISTS"],[5,1,1,"","LPIPS"],[5,1,1,"","MAE"],[5,1,1,"","MSE"],[5,1,1,"","MS_SSIM"],[5,1,1,"","NLPD"],[5,1,1,"","RMSE"],[5,1,1,"","SSIM"],[5,4,1,"","make_kernel_odd"],[5,1,1,"","one_over_PSNR"]],"IQM_Vis.metrics.IQMs.DISTS":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.IQMs.LPIPS":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.IQMs.MAE":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.IQMs.MSE":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.IQMs.MS_SSIM":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.IQMs.NLPD":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.IQMs.RMSE":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.IQMs.SSIM":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.IQMs.one_over_PSNR":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.SSIM":[[6,0,0,"-","ssim"]],"IQM_Vis.metrics.SSIM.ssim":[[6,1,1,"","MS_SSIM"],[6,1,1,"","SSIM"],[6,4,1,"","gaussian_filter"],[6,4,1,"","ms_ssim"],[6,4,1,"","ssim"]],"IQM_Vis.metrics.SSIM.ssim.MS_SSIM":[[6,3,1,"","forward"],[6,2,1,"","training"]],"IQM_Vis.metrics.SSIM.ssim.SSIM":[[6,3,1,"","forward"],[6,2,1,"","training"]],"IQM_Vis.transforms":[[7,0,0,"-","additive_noise"],[7,0,0,"-","affine"],[7,0,0,"-","effects"],[7,4,1,"","get_all_transforms"]],"IQM_Vis.transforms.additive_noise":[[7,1,1,"","Gaussian_noise"],[7,1,1,"","noise_hypersphere"],[7,4,1,"","salt_and_pepper_noise"]],"IQM_Vis.transforms.affine":[[7,4,1,"","rotation"],[7,4,1,"","x_shift"],[7,4,1,"","y_shift"],[7,4,1,"","zoom_image"]],"IQM_Vis.transforms.effects":[[7,4,1,"","binary_threshold"],[7,4,1,"","blur"],[7,4,1,"","brightness"],[7,4,1,"","brightness_hsv"],[7,4,1,"","contrast"],[7,4,1,"","hue"],[7,4,1,"","jpeg_compression"],[7,4,1,"","saturation"]],"IQM_Vis.ui_wrapper":[[0,4,1,"","check_pyqt_install_deps"],[0,1,1,"","make_UI"],[0,4,1,"","test_datastore_attributes"],[0,1,1,"","transform_wrapper"]],"IQM_Vis.ui_wrapper.make_UI":[[0,3,1,"","show"]],"IQM_Vis.ui_wrapper.transform_wrapper":[[0,3,1,"","__call__"]],"IQM_Vis.utils":[[8,0,0,"-","gui_utils"],[8,0,0,"-","image_utils"],[8,0,0,"-","plot_utils"],[8,0,0,"-","save_utils"]],"IQM_Vis.utils.gui_utils":[[8,1,1,"","MplCanvas"],[8,4,1,"","change_im"],[8,4,1,"","get_image_pair_name"],[8,4,1,"","get_metric_image_name"],[8,4,1,"","get_resolutions"],[8,4,1,"","get_trans_dict_from_str"],[8,4,1,"","get_transformed_image_name"],[8,4,1,"","str_to_len"]],"IQM_Vis.utils.image_utils":[[8,4,1,"","calibrate_brightness"],[8,4,1,"","crop_centre"],[8,4,1,"","get_transform_image"],[8,4,1,"","load_image"],[8,4,1,"","resize_image"],[8,4,1,"","resize_to_longest_side"],[8,4,1,"","save_image"]],"IQM_Vis.utils.plot_utils":[[8,1,1,"","bar_plotter"],[8,4,1,"","click_scatter"],[8,4,1,"","compute_metric_for_human_correlation"],[8,4,1,"","compute_metrics_over_range"],[8,4,1,"","compute_metrics_over_range_single_trans"],[8,4,1,"","get_all_single_transform_params"],[8,4,1,"","get_all_slider_values"],[8,4,1,"","get_correlation_plot"],[8,4,1,"","get_radar_plots_avg_plots"],[8,4,1,"","get_transform_range_plots"],[8,4,1,"","hover_scatter"],[8,1,1,"","line_plotter"],[8,1,1,"","radar_plotter"],[8,1,1,"","scatter_plotter"],[8,4,1,"","update_annot"]],"IQM_Vis.utils.plot_utils.bar_plotter":[[8,3,1,"","plot"],[8,3,1,"","set_plot_lims"],[8,3,1,"","set_style"],[8,3,1,"","show"]],"IQM_Vis.utils.plot_utils.line_plotter":[[8,3,1,"","plot"],[8,3,1,"","set_plot_lims"],[8,3,1,"","set_style"],[8,3,1,"","show"]],"IQM_Vis.utils.plot_utils.radar_plotter":[[8,3,1,"","plot"],[8,3,1,"","set_plot_lims"],[8,3,1,"","set_style"],[8,3,1,"","show"]],"IQM_Vis.utils.plot_utils.scatter_plotter":[[8,3,1,"","plot"],[8,3,1,"","set_plot_lims"],[8,3,1,"","set_style"],[8,3,1,"","show"]],"IQM_Vis.utils.save_utils":[[8,6,1,"","DEFAULT_SAVE_DIR"],[8,4,1,"","get_IQM_file"],[8,4,1,"","get_human_scores_file"],[8,4,1,"","get_human_times_file"],[8,4,1,"","get_image_name_from_human_scores"],[8,4,1,"","get_image_processing_file"],[8,4,1,"","get_original_image_file"],[8,4,1,"","get_original_unprocessed_image_file"],[8,4,1,"","get_transform_functions_file"],[8,4,1,"","get_transform_params_file"],[8,4,1,"","load_json_dict"],[8,4,1,"","load_obj"],[8,4,1,"","make_name_for_trans"],[8,4,1,"","save_and_merge_df_as_csv"],[8,4,1,"","save_df_as_csv"],[8,4,1,"","save_experiment_results"],[8,4,1,"","save_json_dict"],[8,4,1,"","save_obj"]],IQM_Vis:[[1,0,0,"-","UI"],[2,0,0,"-","data_handlers"],[3,0,0,"-","examples"],[5,0,0,"-","metrics"],[7,0,0,"-","transforms"],[0,0,0,"-","ui_wrapper"],[8,0,0,"-","utils"],[0,0,0,"-","version"]]},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","attribute","Python attribute"],"3":["py","method","Python method"],"4":["py","function","Python function"],"5":["py","property","Python property"],"6":["py","data","Python data"]},objtypes:{"0":"py:module","1":"py:class","2":"py:attribute","3":"py:method","4":"py:function","5":"py:property","6":"py:data"},terms:{"0":[0,1,5,6,7,8,11,14,15,16],"01":[5,6],"03":[5,6],"1":[0,1,5,6,7,8,11,12,15,16],"10":11,"100":[7,8,15],"101":7,"11":[0,1,5,6,8,11],"128":8,"13":11,"14":11,"180":[5,15],"2":[6,7,8,12,16],"200":3,"2016_hvei":5,"250":8,"255":[6,7],"2x":[7,8],"3":[6,8,11,12,15],"300":1,"39":15,"4":[5,6,12,15,16],"41":15,"5":[1,5,6,7,8,14,15,16],"50":7,"512":3,"6":[1,16],"7":[1,7,11,16],"8":16,"9":[7,11],"90":7,"abstract":2,"byte":2,"class":[0,1,2,5,6,7,8,16],"default":[2,5,7,8,14,16],"do":[2,8,10,12,14],"float":[6,7,8,15,16],"function":[0,1,2,6,7,8,14,15,16,18],"import":[11,14,15,16,18],"int":[1,6,7,15],"new":[1,6,11,14],"return":[0,5,6,7,8,15,16,17],"true":[0,1,3,5,6,8,15],"try":6,"while":6,A:16,For:[2,15,16],If:[2,11,17],In:[14,15,16,17,18],It:[5,10,11,18],On:17,The:[5,10,14,17,18],Then:[11,16],There:[11,18],These:[12,15,18],To:[14,15,17],__call__:[0,2,5,16],__init__:16,_base_nois:7,_max:1,_min:1,_plot:8,_redo_plot:1,a0:1,a1:1,a_tran:1,ab:16,abc:2,abl:12,about:[1,16],abov:16,absolut:5,acceler:10,acceptable_perc:7,access:[0,10],accord:[6,18],achiev:[2,10],across:8,action_stor:1,activ:11,ad:[7,10,15],add:[1,7,14,16],add_layout_to_tab:1,add_metr:2,add_metric_imag:2,additive_nois:[0,13],adher:18,adjust:[7,14,16],advanc:16,advantag:10,affin:[0,13],after:[2,8,14],afterward:6,against:[10,17],aim:18,al:5,alex:5,algorithm:[10,17,18],align:5,all:[0,1,2,5,6,7,8,13,14,17],all_metr:5,all_param:5,alongsid:[1,7],alreadi:2,also:[10,15,16,18],although:6,alwai:0,amount:7,an:[0,1,2,5,7,10,14,15],anaconda:11,analys:[10,12],analysi:[1,10,15],angl:7,ani:[10,12,14,16],annot:8,anyth:16,api:[0,2],app:1,append_char:8,append_dataset:1,appli:[1,2,14,18],apt:11,ar:[0,1,2,5,7,10,11,12,16,17,18],arbitrari:5,area:7,arg:[0,1,16],argument:[5,16],around:[7,11],arr:2,arrai:[1,2,5,7,8,16],aspect:15,associ:5,att:16,attempt:18,attribut:[0,16],automat:10,avaiabl:3,avail:[5,7],averag:6,avoid:0,ax:8,b:[7,14,17],b_tran:1,backend:[5,8,10],backend_qtagg:8,bar:14,bar_nam:8,bar_plott:8,base:[0,1,2,5,6,7,8],base_dataload:2,base_dataset_load:2,basic:15,batch:[5,6],been:2,befor:[14,15],behav:12,behaviour:18,being:[8,18],below:5,benchmark:18,best:[8,11,18],better:7,between:[0,1,5,18],beyond:7,binari:7,binary_threshold:7,black:[1,7,14],blank:14,blueprint:2,blur:[6,7,15],boarder:14,bool:[0,5,6,8],border:8,both:[2,18],bound:16,box:10,bright:[7,15,16],brightness_hsv:7,buffer:2,button:[1,17],c:[6,11],cach:2,cache_metric_cal:2,cache_track:2,calc_max_comparison:1,calc_rang:1,calcul:[1,2,10,14],calibr:[10,17],calibrate_bright:8,call:[0,2,5,6,14,16],callabl:[2,16],can:[1,10,11,12,14,15,16,17,18],candela:14,capabilit:10,captur:18,care:6,categoris:18,centr:[7,8],chang:[1,8,14,15],change_data:1,change_data_click_im:1,change_display_im_display_bright:1,change_display_im_rgb_bright:1,change_display_im_s:1,change_experiment_imag:1,change_graph_s:1,change_human_scores_after_exp:1,change_im:8,change_metric_correlations_graph:1,change_metric_range_graph:1,change_num_step:1,change_plot_lim:1,change_post_process:1,change_pre_process:1,change_preview_imag:1,change_save_fold:1,change_text_exp_tran:1,change_text_export_tran:1,change_to_data_num:1,change_to_solid:1,change_to_specific_tran:1,change_trans_value_sign:8,channel:6,check_pyqt_install_dep:0,checkbox:1,checked_metr:1,checked_transformation_param:1,choos:5,clash:11,clear_all_cach:2,clear_all_cache_data:1,click:[1,8,14,17],click_complet:1,click_scatt:8,clickabl:1,clicked_imag:1,clicklabel:1,clip:[7,16],closeev:1,code:[5,8,11],collect:10,colour:1,colour_lineedit:1,com:[5,14,15,16,17],commun:2,comp:15,compar:[10,15,17,18],comparison:[5,10,16],compat:5,complet:1,completed_range_result:1,comprehens:12,compress:7,comput:[6,8,14],compute_metric_for_human_correl:8,compute_metrics_over_rang:8,compute_metrics_over_range_single_tran:8,conda:11,conduct:[10,12],conflict:11,conform:[10,12],connect_func:1,consist:18,constant:6,construct_ui:1,constructor:2,contain:[8,14,17],content:13,context:18,contrast:7,control:5,conveni:10,conver:7,convert:[2,7],convolut:7,copi:14,correct:[0,3,10,17],correl:[8,10,17,18],correspond:[8,14,17],could:11,cover:10,crash:0,creat:[1,6,11,18],crop:[2,8,10,14],crop_centr:8,crope:8,crucial:10,css_file:1,csv:[8,17],cuda:11,current:8,current_imag:1,cursor0:11,custom:[1,10,15,16],custom_bright:16,custom_float_valid:1,custom_mae_class:16,custom_mae_funct:16,custom_widget:[0,13],customis:[12,17],d:6,data:[0,1,2,8,10,12,18],data_api:[0,8,13],data_api_abstract:[0,13],data_handl:[0,13],data_rang:6,data_stor:[0,1,8],dataset:[0,1,8,10,13,16],dataset_hold:2,debug:0,decod:7,decreas:7,deep:[5,18],def:16,default_save_dir:[0,1,8],defin:[6,15,16],degre:7,demonstr:[11,12],depend:11,depth:12,design:10,desir:[10,15],despit:18,detail:[10,12],develop:10,deviat:7,df:8,dict:[0,1,2,5,7,8],dict_:8,dictionari:[2,15,16],differ:[2,6,12],digit:7,dimens:5,dingkeyan93:5,dir:8,directori:14,disable_settings_button:1,disagre:17,disp_len:1,displai:[10,17],display_bright:[1,8],display_imag:1,display_metr:1,display_metric_correlation_plot:1,display_metric_imag:1,display_metric_range_plot:1,display_metrics_graph:1,display_metrics_text:1,display_radar_plot:1,display_slider_num:1,dissimilar:5,dist:[0,5,13],distanc:18,distor:12,distort:[7,10,12,15,16,18],distribut:6,do_work:1,doc:[0,8,14,15,16,17],document:[10,15],doe:11,doesn:0,don:11,down:1,download:11,downsiz:5,dpi:8,drop:1,dummi:16,dummy_arg:16,e:[5,6,11,12,14,16,18],each:[7,8],earli:5,edit_slider_v:1,effect:[0,12,13],element:1,empir:18,en:5,enabl:10,enable_settings_button:1,encod:7,entri:1,environ:11,epsilon:7,error:[5,8,11,16,18],es:5,et:5,etc:[0,17],euclidean:18,ev:1,evalu:[5,10,12,18],event:[1,8],everi:6,everyth:[15,17],exactli:16,exampl:[0,2,5,11,13,15,16,18],expand:16,expect:12,expens:18,experi:[0,1,8,12,13,18],experiment:18,experiment_layout:1,experiment_mod:[0,13],export_trans_imag:1,expos:10,extent:1,extra:16,extrem:18,f:15,facilit:[10,12],fail:10,fals:[0,1,5,6,7,8],featur:[10,12],feel:15,figur:8,figurecanvasqtagg:8,file:[2,3,8,14,15,17],file_path:2,filepath:15,fill:7,finish_experi:1,first:[11,17,18],firstli:12,fix:8,float32:7,folder:[1,14,17],follow:16,forc:6,form:[10,16],former:6,forward:6,frame:8,framework:10,free:15,fresh:11,from:[1,2,5,8,10,11,14,17,18],fucntion:2,func:2,further:[10,12],g:[5,6,11,12,14,16],gain:5,gan:5,gather:18,gauss:6,gaussian:7,gaussian_filt:6,gaussian_nois:7,gener:[2,5,10,17],generic_value_chang:1,geometr:[5,7],get:[0,1,5,6,7,8,15],get_all_imag:1,get_all_iqm_param:5,get_all_metr:5,get_all_metric_imag:5,get_all_single_transform_param:8,get_all_slider_valu:8,get_all_transform:7,get_correlation_plot:8,get_float_valid:1,get_human_scores_fil:8,get_human_times_fil:8,get_image_dataset_list:2,get_image_nam:2,get_image_name_from_human_scor:8,get_image_pair_nam:8,get_image_processing_fil:8,get_image_to_transform:2,get_image_to_transform_nam:2,get_iqm_fil:8,get_menu_checkbox:1,get_metr:2,get_metric_imag:2,get_metric_image_nam:8,get_metric_scor:1,get_metrics_over_all_trans_with_init_valu:1,get_original_image_fil:8,get_original_unprocessed_image_fil:8,get_radar_plots_avg_plot:8,get_range_results_work:1,get_reference_imag:2,get_reference_image_by_index:2,get_reference_image_nam:2,get_reference_unprocess:2,get_resolut:8,get_single_transform_im:1,get_trans_dict_from_str:8,get_transform_functions_fil:8,get_transform_imag:8,get_transform_params_fil:8,get_transform_range_plot:8,get_transformed_image_nam:8,getter:8,github:[5,12,14,15,16,17],give:[5,17,18],given:[1,5,7,8,18],go:[14,15,17],goal:18,gpu:[10,11],graph:[0,1,8,10,12],graphic:[10,18],greycal:3,grip:15,group:18,gui:10,gui_util:[0,13],h:[6,7],ha:[10,17],half:8,handl:10,handler:0,hardwar:10,hashabl:2,have:[2,5,7,8,11,12,14,16,18],head:11,helper:8,here:[0,16,17],high:1,higher:[1,7],highest:10,hold:8,home:[0,1,8,15,16],hook:6,horizont:7,hover_scatt:8,how:[5,8,12,14,15,17],html:15,http:[1,5,14,15,16,17],hue:7,human:[17,18],human_exp_csv:2,human_scor:8,hyperspher:7,i:[1,18],ident:7,ignor:6,illustr:12,im:8,im_comp:[5,16],im_ref:[5,16],imag:[0,2,3,5,6,7,8,10,12,13,16,17,18],image1:15,image2:15,image_display_s:1,image_list:[0,1,2,15,16],image_list_to_transform:2,image_load:2,image_nam:1,image_path:8,image_post_process:2,image_postprocess:1,image_pre_process:2,image_preprocess:1,image_util:[0,13],img:[3,8],implement:10,improv:10,includ:[10,14,15,16],increas:7,ind:[1,8],index:[2,5,8,11,12,18],individu:8,info:1,info_item:1,inform:[15,17],init:[1,15],init_layout:1,init_styl:1,init_valu:[7,15,16],init_widget:1,init_worker_thread:1,initi:8,initialis:[1,16],input:[0,2,6,15,16],input_str:1,inspect:12,instal:0,instanc:[5,6],instead:[6,8,15],interact:18,interfac:[6,10],invari:18,investig:12,io:15,ipynb:[14,15,16,17],iqm:[0,1,2,8,11,13,14,15,16,17],iqm_scores_df:8,iqm_vi:[11,12,14,15,16],is_almost_float:1,is_float:1,item:[8,14],iter:1,its:[0,7,8],itself:18,ival:1,j:1,jpeg:[0,7,15],jpeg_compress:[7,15],jpg:15,just:[8,18],k1:[5,6],k2:[5,6],k:6,keep_siz:8,kei:[1,2,8,16],kernel:[5,6,7,15],kernel_s:7,keyword:5,know:11,kodak:[0,13,16],kodim01:16,kodim02:16,kwarg:[0,1,2,5,7,16],l1:16,label:[1,8],laparra:5,lapeva:5,laplacian:5,larger:6,later:[15,16],latest:11,latter:6,launch:[14,17],launch_experi:1,layout:[0,13],learn:[5,18],left:1,lend:18,length:8,less:7,let:[15,16],level:6,librari:[0,11],libxcb:11,light:1,like:[11,16,18],lim:8,line_plott:8,linux:0,list1:1,list2:1,list:[0,1,2,6,8,15],literatur:18,littl:15,load:[2,8,11,17],load_all_metr:1,load_all_metric_imag:1,load_all_transform:1,load_and_calibrate_imag:3,load_experiment_from_dir:1,load_human_experi:1,load_imag:[2,8],load_image_list:2,load_json_dict:8,load_new_images_fold:1,load_new_single_imag:1,load_obj:8,loader:2,local:[5,15],longest:8,look:8,loss:[5,18],low:1,lower:1,lpip:5,lumin:[5,10,14,17],mae:[5,15,16],mai:18,main:[0,13,14,15,16,17],main_menu:1,make:[0,8,11,12,17],make_app:1,make_experi:1,make_float_from_text:1,make_kernel_odd:5,make_menu:1,make_name_for_tran:8,make_slider_rang:1,make_status_bar:1,make_ui:[0,11,14,15,16],maker:15,maketh:1,making_the_ui:14,manag:[10,12],mani:10,matplotlib:8,matt:[0,1,8,15,16],mattclifford1:[14,15,16,17],max:[7,8,15,16],max_it:7,max_lumin:3,maximum:14,mean:[5,16,18],measur:[5,14,18],menu:[1,14,17],messag:1,message_on_plot:1,meta_dict:3,meter:14,method:8,metric:[0,1,2,3,8,10,12,13,17,18],metric_imag:[0,1,2,15],metric_param:[0,1,8,16],metric_range_graph:1,metric_scor:8,metrics_avg_graph:[0,1],metrics_info_format:[0,1],metrics_nam:8,metrics_to_us:[2,8],might:[16,17],mild:5,mimic:18,min:[7,8,15,16],miss:11,model:18,modul:[12,13],more:[10,15],most:17,mousepressev:1,mpl_canva:1,mplcanva:8,ms:6,ms_ssim:[5,6],mse:[5,15],mse_imag:15,mssim_kernel_s:5,much:18,multi:5,multipl:[0,13],must:5,mutabl:2,n:[6,11,14,17],name:[1,2,7,8],nan:6,navig:14,necessari:18,need:[0,1,2,6,8,14,15,16,17],neg:6,net:1,network:5,new_api:[0,13],newer:11,nlpd:5,nlpd_k:5,nn:6,nois:[5,7],noise_hyperspher:7,noise_ratio:5,non:[8,15],none:[0,1,2,6,8],nonneg:6,nonnegative_ssim:6,normal:[6,7,8,15],normalis:[5,15],note:[5,8,16],notebook:[14,15,16,17],now:[11,15,16],np:[5,7,8,16],num_imag:1,num_images_scroll_show:1,num_step:[1,8],num_step_experi:1,num_steps_rang:[0,1],number:[7,14],numpi:[2,8,10,16],nvidia:11,object:[0,1,2,5,8,16,18],observ:18,obtain:18,odd:[7,15],off:16,offer:12,often:18,onc:17,one:6,one_over_psnr:5,onli:[7,8,14,15,17],open_mlp_new:1,opencv:10,oper:[5,15,18],option:[1,2,6,10,15,17],order:[1,10,17],ordin:10,org:5,origin:8,other:[8,10],our:[12,16],out:[7,8,10],over:[5,8,11,14,15],overridden:6,overse:18,own:[15,16,17],packag:[11,12,13,15,16],packg:14,pair:[5,10],pairwis:17,paper:[5,12],param1:16,param:[1,6,16],param_group:1,paramet:[2,5,7,8,12,14,16,18],paramt:[8,14],parent:1,particip:[10,17],particular:10,partit:1,pass:[6,15,16],past:14,patch:5,path:[1,2,8,15],paus:1,pbar_sign:8,pdf:5,peak:5,peak_sign:5,peel:16,peic:15,pepper:7,per:14,perceiv:[10,18],percentag:[7,8],percept:18,perceptu:[5,18],perform:[6,12,18],pick:10,pickl:8,pickle_path:8,pip:11,pivot:1,pixel:[5,7],pkl:8,place:14,platform:11,plethora:18,plot:[1,8,10,17],plot_metric_range_mlp:1,plot_radar_graph:1,plot_radar_mlp:1,plot_util:[0,13],plu:8,plugin:11,png:16,point:[1,5,8,11,17],polar:8,post:8,practition:[10,12,18],pre:10,premis:18,presenc:18,press:[1,17],pretrain:5,preview_num:1,previou:17,principl:18,print:15,prob:7,probabl:7,problem:11,procedur:12,process:[8,10,15,18],produc:[14,18],profil:18,progress:1,progressbar:1,project:[0,14,15],properti:[0,2,10,12],proport:7,propos:5,provid:[5,10,12,14,15],psnr:5,psychophys:18,purpos:1,put:16,pypi:11,pyqt6:[0,1,8,10],pyqt:1,pyramid:5,python:[10,11,14],pythontutori:1,pytorch:[5,10,11],qcloseev:1,qlabel:1,qmainwindow:1,qmouseev:1,qobject:1,qprogressbar:1,qt:11,qtcore:1,qtgui:1,qthread:1,qtwidget:1,qualit:[15,18],qualiti:[5,7,10,12,15,18],quantit:18,quick:[10,17],quick_sort:1,quit:1,qvalid:1,radar:8,radar_nam:8,radar_plott:8,radiu:7,ranc:8,random:7,rang:[1,6,7,8,14,15,16,18],rate:18,ratio:5,read:[12,17],readi:17,real:10,recent:18,recip:6,recommend:[7,11,14],recreat:18,recurs:10,redo_plot:1,reduc:5,reduct:5,ref:2,refer:[2,5,8,10,16,18],regist:6,reinstal:11,reject_low_nois:7,relev:11,relu:6,remain:18,repons:12,request_range_work:1,requir:[0,1,11,14,15,17,18],reset_clicked_imag:1,reset_correlation_data:1,reset_experi:1,reset_image_widget_to_black:1,reset_slid:1,reset_slider_group:1,resiz:[8,10],resize_imag:8,resize_to_longest_sid:8,respect:[10,18],respons:[6,18],restrict_opt:[0,1],result:[1,6,8,10,12],results_ord:8,return_dict:8,return_imag:[5,15],reult:8,rgb:8,rgb_bright:[1,8],right:1,rmse:5,robust:5,root:5,rotat:[2,7,10,14,15],round:12,run:[3,6,10,11,12,14],running_an_experi:17,s:[15,16,18],salt:7,salt_and_pepper_nois:7,same:[2,5,16,18],sampl:[5,7],sat:7,satur:7,save:[1,8,14,17],save_and_merge_df_as_csv:8,save_df_as_csv:8,save_dir:8,save_experi:1,save_experiment_result:8,save_imag:8,save_json_dict:8,save_obj:8,save_util:[0,13],saved_experi:1,scalar:[5,6,15],scale:5,scale_factor:[7,8],scatter:8,scatter_plott:8,scenario:[12,18],score:[1,5,10,16,17],scratch:11,screen:[10,14],script:14,second:18,secondli:12,see:[10,12,15,17],select:[10,12,14,17],self:[0,1,2,16],send:8,sent:1,serv:18,set:[1,12,17],set_checked_menu_from_iter:1,set_image_name_text:1,set_plot_lim:8,set_preview_imag:1,set_save_dir_mpl:1,set_styl:8,setup:[1,17],setup_experi:1,shape:16,shift:7,ship:0,should:[6,11],show:[0,8,10,16,17],show_all_imag:1,shown:[16,17],side:8,sigma:[5,6],signal:[1,5,8],silent:6,similar:[5,15,17,18],simpl:[0,10,12,13],simpler:8,simplest:18,sinc:[2,6,15],singl:[8,16],single_trans_dict:1,size:[3,5,6,7,8,10,17],size_averag:6,skimag:7,skip:11,sliders_dict:1,small:[5,8],smaller:14,smoother:1,so:[0,1,8,10,11],softwar:[12,18],solv:11,some:[11,14,15],sort:[10,17],sort_list:1,sourc:[0,1,2,3,5,6,7,8],space:18,spacial:[12,15],spatial_dim:6,specif:[10,18],specifi:[8,15],spider:8,squar:[5,7,8,14,16,18],squeez:5,ssim:[0,5,12,15,18],ssim_imag:15,ssim_kernel_s:5,stanard:10,standard:[7,10],start:[7,15,16,17],start_experi:1,state:1,std:7,step:11,still:16,stop:1,stop_flag:8,stopped_range_work:1,storag:10,store:[2,15,16],str:[0,1,5],str_to_len:8,straightforward:10,strictli:5,string:8,structur:[5,18],style:1,subclass:[1,6],submodul:13,subpackag:13,subtract:5,sudo:11,sum:5,sure:[0,11,12,16,17],swap_ind:1,system:5,t:[0,6,11],tab:[1,14],take:[5,6,10,14,16,17],task:10,tell:16,tensor:6,test:[0,1,12],test_datastore_attribut:0,text:[1,8],textur:5,than:[1,7],theh:14,thei:[0,2,16,17,18],them:[0,6,15,16],thi:[2,6,8,10,11,14,15,16,17,18],thing:17,thread:[0,13],threshold:7,through:[10,12,14,15,17],time:1,times_taken:8,timescal:10,todo:[0,8],toggle_experi:1,too:18,toolbox:12,torch:6,torchaudio:11,torchvis:11,tradit:18,train:6,tran:[1,2,8],trans_nam:8,trans_str:[1,8],trans_str_valu:8,transform:[0,1,2,3,5,8,10,12,13,17],transform_funct:8,transform_param:8,transform_valu:8,transform_wrapp:0,transformation_nam:8,transformed_imag:2,translat:[7,10],tree:[14,15,16,17],truthfulli:10,tupl:6,tutori:10,tutorial_1:14,tutorial_2:15,tutorial_3:16,tutorial_4:17,two:[5,12,15,18],txt:1,type:[5,6,7,8],ubuntu:11,ubyt:8,ui:[0,2,5,8,12,13,15,17],ui_wrapp:13,unchang:18,under:12,underli:10,understand:[10,12],undistort:10,union:6,unsort:1,until:17,up:[1,12],update_annot:8,update_datastore_image_list:1,update_image_set:1,update_progress:1,update_status_bar:1,us:[1,2,5,7,8,10,11,12,14,15,16,17],usag:0,user:[0,7,10,12,17],usual:6,util:[0,2,13],utilis:18,uv:5,v:1,valero:5,valid:1,valu:[2,5,6,7,8,14,15,16],var_nam:8,var_valu:8,varianc:5,variou:12,version:[11,13],vertic:7,vgg:5,vi:[0,1,2,8,11,14,15,16,17,18],via:2,video:12,view:[10,12,14,15,16,17],view_correlation_inst:1,virtual:11,visibl:18,visit:12,visual:[5,12],visualis:[10,12],w:6,wa:8,wai:12,want:[15,17],warn:0,waves1:[0,15],waves2:[0,15],waves3:0,we:[0,1,2,11,14,15,16,17,18],websit:11,weight:6,well:[10,11,12],what:[0,16],when:[1,5,8,14,15,17],where:18,whether:5,which:[2,5,8,10,11,12,18],whole:[8,14,15,16,17],why:18,widget:[0,8,13],widget_ax:1,widget_ind:1,widget_nam:1,wiki:5,wikipedia:5,win:6,win_sigma:6,win_siz:6,window:[1,6],within:[6,14,16],without:12,word:16,work:11,worker:1,world:10,would:[11,14],wrap:0,write:[0,8,12],www:[1,5],x:[6,8],x_label:8,x_shift:7,y:[6,8,11],y_label:8,y_shift:7,you:[6,11,12,14,15,16,17],your:[15,17],zero:15,zoom:[7,8],zoom_imag:7},titles:["IQM_Vis package","IQM_Vis.UI package","IQM_Vis.data_handlers package","IQM_Vis.examples package","IQM_Vis.examples.images package","IQM_Vis.metrics package","IQM_Vis.metrics.SSIM package","IQM_Vis.transforms package","IQM_Vis.utils package","Tutorials","About IQM-Vis","Getting Started","IQM-Vis documentation","IQM_Vis","Tutorial 1: Making the UI","Tutorial 2: Simple Customisation","Tutorial 3: Customisation Details","Tutorial 4: Running an Experiment","IQMs"],titleterms:{"1":14,"2":15,"3":16,"4":17,"function":10,For:18,about:[10,12],ad:14,additive_nois:7,affin:7,all:[3,15],an:[12,17,18],analysi:12,bright:14,built:10,choos:18,code:12,common:11,content:[0,1,2,3,4,5,6,7,8],correl:12,custom_widget:1,customis:[15,16],data_api:2,data_api_abstract:2,data_handl:2,dataset:3,detail:16,differ:18,dispali:14,displai:14,dist:3,document:12,effect:7,exampl:[3,4],experi:[3,10,14,17],experiment_mod:1,finsih:17,get:[11,12],graph:14,gui_util:8,how:18,human:[10,12],imag:[1,4,14,15],image_util:8,indic:12,info:17,instal:11,iqm:[5,10,12,18],iqm_vi:[0,1,2,3,4,5,6,7,8,13],issu:11,kodak:3,layout:1,load:14,main:1,make:[14,16],max:14,metric:[5,6,14,15,16],modul:[0,1,2,3,4,5,6,7,8],multipl:3,new_api:3,offer:10,other:14,own:14,packag:[0,1,2,3,4,5,6,7,8],percept:[10,12],plot_util:8,post:14,pre:14,process:14,put:15,qualit:12,quantit:12,result:17,rgb:14,run:17,save_util:8,screen:17,set:14,simpl:[3,15],size:14,softwar:10,sourc:12,ssim:6,start:[11,12],step:14,submodul:[0,1,2,3,5,6,7,8],subpackag:[0,3,5],tabl:12,task:18,test:11,thread:1,togeth:15,transform:[7,14,15,16],tutori:[9,12,14,15,16,17],type:18,ui:[1,14,16],ui_wrapp:0,util:[1,8],version:0,vi:[10,12],visualis:17,what:[10,12,18],widget:1,your:[14,18]}}) \ No newline at end of file +Search.setIndex({docnames:["IQM_Vis","IQM_Vis.UI","IQM_Vis.data_handlers","IQM_Vis.examples","IQM_Vis.examples.images","IQM_Vis.metrics","IQM_Vis.metrics.SSIM","IQM_Vis.transforms","IQM_Vis.utils","Tutorials","about","getting_started","index","modules","notebooks/Tutorial_1-making_the_UI","notebooks/Tutorial_2-Customisation","notebooks/Tutorial_3-Advanced-Customisations","notebooks/Tutorial_4-running_an_experiment","what-are-IQMs"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":5,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.viewcode":1,nbsphinx:4,sphinx:56},filenames:["IQM_Vis.rst","IQM_Vis.UI.rst","IQM_Vis.data_handlers.rst","IQM_Vis.examples.rst","IQM_Vis.examples.images.rst","IQM_Vis.metrics.rst","IQM_Vis.metrics.SSIM.rst","IQM_Vis.transforms.rst","IQM_Vis.utils.rst","Tutorials.rst","about.rst","getting_started.rst","index.rst","modules.rst","notebooks/Tutorial_1-making_the_UI.ipynb","notebooks/Tutorial_2-Customisation.ipynb","notebooks/Tutorial_3-Advanced-Customisations.ipynb","notebooks/Tutorial_4-running_an_experiment.ipynb","what-are-IQMs.rst"],objects:{"":[[0,0,0,"-","IQM_Vis"]],"IQM_Vis.UI":[[1,0,0,"-","custom_widgets"],[1,0,0,"-","experiment_mode"],[1,0,0,"-","images"],[1,0,0,"-","layout"],[1,0,0,"-","main"],[1,0,0,"-","threads"],[1,0,0,"-","utils"],[1,0,0,"-","widgets"]],"IQM_Vis.UI.custom_widgets":[[1,1,1,"","ClickLabel"],[1,1,1,"","ProgressBar"]],"IQM_Vis.UI.custom_widgets.ClickLabel":[[1,2,1,"","clicked"],[1,3,1,"","mousePressEvent"]],"IQM_Vis.UI.experiment_mode":[[1,1,1,"","make_experiment"],[1,1,1,"","reset_image_widget_to_black"],[1,4,1,"","sort_list"]],"IQM_Vis.UI.experiment_mode.make_experiment":[[1,3,1,"","calc_max_comparisons"],[1,3,1,"","change_experiment_images"],[1,3,1,"","click_completed"],[1,3,1,"","clicked_image"],[1,3,1,"","closeEvent"],[1,3,1,"","experiment_layout"],[1,3,1,"","finish_experiment"],[1,3,1,"","get_all_images"],[1,3,1,"","get_metric_scores"],[1,3,1,"","get_single_transform_im"],[1,3,1,"","init_style"],[1,3,1,"","partition"],[1,3,1,"","quick_sort"],[1,3,1,"","quit"],[1,2,1,"","reset_clicked_image"],[1,3,1,"","reset_experiment"],[1,3,1,"","save_experiment"],[1,2,1,"","saved_experiment"],[1,3,1,"","setup_experiment"],[1,3,1,"","show_all_images"],[1,3,1,"","start_experiment"],[1,3,1,"","swap_inds"],[1,3,1,"","toggle_experiment"]],"IQM_Vis.UI.experiment_mode.reset_image_widget_to_black":[[1,3,1,"","change_to_solid"],[1,2,1,"","completed"],[1,3,1,"","stop"]],"IQM_Vis.UI.images":[[1,1,1,"","images"],[1,4,1,"","message_on_plot"]],"IQM_Vis.UI.images.images":[[1,3,1,"","change_data"],[1,3,1,"","change_data_click_im"],[1,3,1,"","change_metric_correlations_graph"],[1,3,1,"","change_metric_range_graph"],[1,3,1,"","change_preview_images"],[1,3,1,"","change_to_data_num"],[1,3,1,"","change_to_specific_trans"],[1,3,1,"","completed_range_results"],[1,3,1,"","display_images"],[1,3,1,"","display_metric_correlation_plot"],[1,3,1,"","display_metric_images"],[1,3,1,"","display_metric_range_plot"],[1,3,1,"","display_metrics"],[1,3,1,"","display_metrics_graph"],[1,3,1,"","display_metrics_text"],[1,3,1,"","display_radar_plots"],[1,3,1,"","get_metrics_over_all_trans_with_init_values"],[1,3,1,"","init_worker_thread"],[1,3,1,"","load_experiment_from_dir"],[1,3,1,"","load_human_experiment"],[1,3,1,"","load_new_images_folder"],[1,3,1,"","load_new_single_image"],[1,3,1,"","plot_metric_range_mlp"],[1,3,1,"","plot_radar_graph"],[1,3,1,"","plot_radar_mlp"],[1,3,1,"","redo_plots"],[1,2,1,"","request_range_work"],[1,3,1,"","set_preview_images"],[1,3,1,"","set_save_dir_mpl"],[1,3,1,"","stopped_range_worker"],[1,3,1,"","update_datastore_image_list"],[1,2,1,"","view_correlation_instance"]],"IQM_Vis.UI.layout":[[1,1,1,"","layout"]],"IQM_Vis.UI.layout.layout":[[1,3,1,"","init_layout"],[1,3,1,"","init_style"]],"IQM_Vis.UI.main":[[1,1,1,"","make_app"],[1,4,1,"","set_checked_menu_from_iterable"]],"IQM_Vis.UI.main.make_app":[[1,3,1,"","change_save_folder"],[1,3,1,"","clear_all_cache_data"],[1,3,1,"","closeEvent"],[1,3,1,"","construct_UI"],[1,3,1,"","get_menu_checkboxes"],[1,3,1,"","load_all_metric_images"],[1,3,1,"","load_all_metrics"],[1,3,1,"","load_all_transforms"],[1,3,1,"","make_menu"],[1,3,1,"","make_status_bar"],[1,3,1,"","quit"],[1,3,1,"","reset_correlation_data"]],"IQM_Vis.UI.threads":[[1,1,1,"","get_range_results_worker"]],"IQM_Vis.UI.threads.get_range_results_worker":[[1,2,1,"","completed"],[1,2,1,"","current_image"],[1,3,1,"","do_work"],[1,2,1,"","progress"],[1,3,1,"","stop"],[1,2,1,"","stopped"]],"IQM_Vis.UI.utils":[[1,4,1,"","add_layout_to_tab"]],"IQM_Vis.UI.widgets":[[1,1,1,"","custom_float_validator"],[1,4,1,"","get_float_validator"],[1,4,1,"","is_almost_float"],[1,4,1,"","is_float"],[1,4,1,"","make_float_from_text"],[1,1,1,"","widgets"]],"IQM_Vis.UI.widgets.custom_float_validator":[[1,3,1,"","validate"]],"IQM_Vis.UI.widgets.widgets":[[1,3,1,"","change_display_im_display_brightness"],[1,3,1,"","change_display_im_rgb_brightness"],[1,3,1,"","change_display_im_size"],[1,3,1,"","change_graph_size"],[1,3,1,"","change_human_scores_after_exp"],[1,3,1,"","change_num_steps"],[1,3,1,"","change_plot_lims"],[1,3,1,"","change_post_processing"],[1,3,1,"","change_pre_processing"],[1,3,1,"","change_text_exp_trans"],[1,3,1,"","change_text_export_trans"],[1,3,1,"","colour_lineedit"],[1,3,1,"","disable_settings_button"],[1,3,1,"","display_slider_num"],[1,3,1,"","edit_slider_vals"],[1,3,1,"","enable_settings_button"],[1,3,1,"","export_trans_images"],[1,3,1,"","generic_value_change"],[1,3,1,"","init_widgets"],[1,3,1,"","launch_experiment"],[1,3,1,"","make_slider_range"],[1,3,1,"","open_mlp_new"],[1,3,1,"","reset_slider_group"],[1,3,1,"","reset_sliders"],[1,3,1,"","set_image_name_text"],[1,3,1,"","update_image_settings"],[1,3,1,"","update_progress"],[1,3,1,"","update_status_bar"]],"IQM_Vis.data_handlers":[[2,0,0,"-","data_api"],[2,0,0,"-","data_api_abstract"]],"IQM_Vis.data_handlers.data_api":[[2,1,1,"","cache_metric_call"],[2,4,1,"","cache_tracked"],[2,1,1,"","dataset_holder"],[2,4,1,"","get_image_name"]],"IQM_Vis.data_handlers.data_api.cache_metric_call":[[2,3,1,"","__call__"]],"IQM_Vis.data_handlers.data_api.dataset_holder":[[2,3,1,"","add_metric"],[2,3,1,"","add_metric_image"],[2,3,1,"","clear_all_cache"],[2,3,1,"","get_image_dataset_list"],[2,3,1,"","get_image_to_transform"],[2,3,1,"","get_image_to_transform_name"],[2,3,1,"","get_metric_images"],[2,3,1,"","get_metrics"],[2,3,1,"","get_reference_image"],[2,3,1,"","get_reference_image_by_index"],[2,3,1,"","get_reference_image_name"],[2,3,1,"","get_reference_unprocessed"],[2,3,1,"","load_image_list"]],"IQM_Vis.data_handlers.data_api_abstract":[[2,1,1,"","base_dataloader"],[2,1,1,"","base_dataset_loader"]],"IQM_Vis.data_handlers.data_api_abstract.base_dataloader":[[2,3,1,"","get_image_to_transform"],[2,3,1,"","get_image_to_transform_name"],[2,3,1,"","get_metric_images"],[2,3,1,"","get_metrics"],[2,3,1,"","get_reference_image"],[2,3,1,"","get_reference_image_name"],[2,5,1,"","metric_images"],[2,5,1,"","metrics"]],"IQM_Vis.data_handlers.data_api_abstract.base_dataset_loader":[[2,3,1,"","get_reference_image_by_index"]],"IQM_Vis.examples":[[3,0,0,"-","all"],[3,0,0,"-","dataset"],[3,0,0,"-","dists"],[3,0,0,"-","experiment"],[4,0,0,"-","images"],[3,0,0,"-","kodak"],[3,0,0,"-","multiple"],[3,0,0,"-","new_api"],[3,0,0,"-","simple"]],"IQM_Vis.examples.all":[[3,4,1,"","run"]],"IQM_Vis.examples.dataset":[[3,4,1,"","run"]],"IQM_Vis.examples.dists":[[3,4,1,"","correct"],[3,4,1,"","load_and_calibrate_image"],[3,4,1,"","run"]],"IQM_Vis.examples.experiment":[[3,4,1,"","run"]],"IQM_Vis.examples.kodak":[[3,4,1,"","run"]],"IQM_Vis.examples.multiple":[[3,4,1,"","run"]],"IQM_Vis.examples.new_api":[[3,4,1,"","run"]],"IQM_Vis.examples.simple":[[3,4,1,"","run"]],"IQM_Vis.metrics":[[6,0,0,"-","SSIM"],[5,4,1,"","get_all_IQM_params"],[5,4,1,"","get_all_metric_images"],[5,4,1,"","get_all_metrics"],[5,0,0,"-","metric_utils"],[5,0,0,"-","non_perceptual"],[5,0,0,"-","perceptual_DL"],[5,0,0,"-","perceptual_trad"]],"IQM_Vis.metrics.SSIM":[[6,0,0,"-","ssim"]],"IQM_Vis.metrics.SSIM.ssim":[[6,1,1,"","MS_SSIM"],[6,1,1,"","SSIM"],[6,4,1,"","gaussian_filter"],[6,4,1,"","ms_ssim"],[6,4,1,"","ssim"]],"IQM_Vis.metrics.SSIM.ssim.MS_SSIM":[[6,3,1,"","forward"],[6,2,1,"","training"]],"IQM_Vis.metrics.SSIM.ssim.SSIM":[[6,3,1,"","forward"],[6,2,1,"","training"]],"IQM_Vis.metrics.non_perceptual":[[5,1,1,"","MAE"],[5,1,1,"","MSE"],[5,1,1,"","RMSE"],[5,1,1,"","one_over_PSNR"]],"IQM_Vis.metrics.non_perceptual.MAE":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.non_perceptual.MSE":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.non_perceptual.RMSE":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.non_perceptual.one_over_PSNR":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.perceptual_DL":[[5,1,1,"","DISTS"],[5,1,1,"","LPIPS"]],"IQM_Vis.metrics.perceptual_DL.DISTS":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.perceptual_DL.LPIPS":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.perceptual_trad":[[5,1,1,"","MS_SSIM"],[5,1,1,"","NLPD"],[5,1,1,"","SSIM"]],"IQM_Vis.metrics.perceptual_trad.MS_SSIM":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.perceptual_trad.NLPD":[[5,3,1,"","__call__"]],"IQM_Vis.metrics.perceptual_trad.SSIM":[[5,3,1,"","__call__"]],"IQM_Vis.transforms":[[7,0,0,"-","additive_noise"],[7,0,0,"-","affine"],[7,0,0,"-","effects"],[7,4,1,"","get_all_transforms"]],"IQM_Vis.transforms.additive_noise":[[7,1,1,"","Gaussian_noise"],[7,1,1,"","noise_hypersphere"],[7,4,1,"","salt_and_pepper_noise"]],"IQM_Vis.transforms.affine":[[7,4,1,"","rotation"],[7,4,1,"","x_shift"],[7,4,1,"","y_shift"],[7,4,1,"","zoom_image"]],"IQM_Vis.transforms.effects":[[7,4,1,"","binary_threshold"],[7,4,1,"","blur"],[7,4,1,"","brightness"],[7,4,1,"","brightness_hsv"],[7,4,1,"","contrast"],[7,4,1,"","hue"],[7,4,1,"","jpeg_compression"],[7,4,1,"","saturation"]],"IQM_Vis.ui_wrapper":[[0,4,1,"","check_pyqt_install_deps"],[0,1,1,"","make_UI"],[0,4,1,"","test_datastore_attributes"],[0,1,1,"","transform_wrapper"]],"IQM_Vis.ui_wrapper.make_UI":[[0,3,1,"","show"]],"IQM_Vis.ui_wrapper.transform_wrapper":[[0,3,1,"","__call__"]],"IQM_Vis.utils":[[8,0,0,"-","gui_utils"],[8,0,0,"-","image_utils"],[8,0,0,"-","plot_utils"],[8,0,0,"-","save_utils"]],"IQM_Vis.utils.gui_utils":[[8,1,1,"","MplCanvas"],[8,4,1,"","change_im"],[8,4,1,"","get_image_pair_name"],[8,4,1,"","get_metric_image_name"],[8,4,1,"","get_resolutions"],[8,4,1,"","get_trans_dict_from_str"],[8,4,1,"","get_transformed_image_name"],[8,4,1,"","str_to_len"]],"IQM_Vis.utils.image_utils":[[8,4,1,"","calibrate_brightness"],[8,4,1,"","crop_centre"],[8,4,1,"","get_transform_image"],[8,4,1,"","load_image"],[8,4,1,"","resize_image"],[8,4,1,"","resize_to_longest_side"],[8,4,1,"","save_image"]],"IQM_Vis.utils.plot_utils":[[8,1,1,"","bar_plotter"],[8,4,1,"","click_scatter"],[8,4,1,"","compute_metric_for_human_correlation"],[8,4,1,"","compute_metrics_over_range"],[8,4,1,"","compute_metrics_over_range_single_trans"],[8,4,1,"","get_all_single_transform_params"],[8,4,1,"","get_all_slider_values"],[8,4,1,"","get_correlation_plot"],[8,4,1,"","get_radar_plots_avg_plots"],[8,4,1,"","get_transform_range_plots"],[8,4,1,"","hover_scatter"],[8,1,1,"","line_plotter"],[8,1,1,"","radar_plotter"],[8,1,1,"","scatter_plotter"],[8,4,1,"","update_annot"]],"IQM_Vis.utils.plot_utils.bar_plotter":[[8,3,1,"","plot"],[8,3,1,"","set_plot_lims"],[8,3,1,"","set_style"],[8,3,1,"","show"]],"IQM_Vis.utils.plot_utils.line_plotter":[[8,3,1,"","plot"],[8,3,1,"","set_plot_lims"],[8,3,1,"","set_style"],[8,3,1,"","show"]],"IQM_Vis.utils.plot_utils.radar_plotter":[[8,3,1,"","plot"],[8,3,1,"","set_plot_lims"],[8,3,1,"","set_style"],[8,3,1,"","show"]],"IQM_Vis.utils.plot_utils.scatter_plotter":[[8,3,1,"","plot"],[8,3,1,"","set_plot_lims"],[8,3,1,"","set_style"],[8,3,1,"","show"]],"IQM_Vis.utils.save_utils":[[8,6,1,"","DEFAULT_SAVE_DIR"],[8,4,1,"","get_IQM_file"],[8,4,1,"","get_human_scores_file"],[8,4,1,"","get_human_times_file"],[8,4,1,"","get_image_name_from_human_scores"],[8,4,1,"","get_image_processing_file"],[8,4,1,"","get_original_image_file"],[8,4,1,"","get_original_unprocessed_image_file"],[8,4,1,"","get_transform_functions_file"],[8,4,1,"","get_transform_params_file"],[8,4,1,"","load_json_dict"],[8,4,1,"","load_obj"],[8,4,1,"","make_name_for_trans"],[8,4,1,"","save_and_merge_df_as_csv"],[8,4,1,"","save_df_as_csv"],[8,4,1,"","save_experiment_results"],[8,4,1,"","save_json_dict"],[8,4,1,"","save_obj"]],IQM_Vis:[[1,0,0,"-","UI"],[2,0,0,"-","data_handlers"],[3,0,0,"-","examples"],[5,0,0,"-","metrics"],[7,0,0,"-","transforms"],[0,0,0,"-","ui_wrapper"],[8,0,0,"-","utils"],[0,0,0,"-","version"]]},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","attribute","Python attribute"],"3":["py","method","Python method"],"4":["py","function","Python function"],"5":["py","property","Python property"],"6":["py","data","Python data"]},objtypes:{"0":"py:module","1":"py:class","2":"py:attribute","3":"py:method","4":"py:function","5":"py:property","6":"py:data"},terms:{"0":[0,1,5,6,7,8,11,14,15,16],"01":[5,6],"03":[5,6],"1":[0,1,5,6,7,8,11,12,15,16],"10":11,"100":[7,8,15],"101":7,"11":[0,1,5,6,8,11],"128":8,"13":11,"14":11,"180":[5,15],"2":[6,7,8,12,16],"200":3,"2016_hvei":5,"250":8,"255":[6,7],"2x":[7,8],"3":[6,8,11,12,15],"300":1,"39":15,"4":[5,6,12,15,16],"41":15,"5":[1,5,6,7,8,14,15,16],"50":7,"512":3,"6":[1,16],"7":[1,11,16],"8":16,"9":[7,11],"abstract":2,"byte":2,"class":[0,1,2,5,6,7,8,16],"default":[2,5,7,8,14,16],"do":[2,8,10,12,14],"float":[6,7,8,15,16],"function":[0,1,2,5,6,7,8,14,15,16,18],"import":[11,14,15,16,18],"int":[1,6,7,15],"new":[1,6,11,14],"return":[0,5,6,7,8,15,16,17],"true":[0,1,3,5,6,8,15],"try":6,"while":6,A:16,For:[2,15,16],If:[2,11,17],In:[14,15,16,17,18],It:[5,10,11,18],On:17,The:[5,10,14,17,18],Then:[11,16],There:[11,18],These:[12,15,18],To:[14,15,17],__call__:[0,2,5,16],__init__:16,_base_nois:7,_max:1,_min:1,_plot:8,_redo_plot:1,a0:1,a1:1,a_tran:1,ab:16,abc:2,abl:12,about:[1,16],abov:16,absolut:5,acceler:10,acceptable_perc:7,access:[0,10],accord:[6,18],achiev:[2,10],across:8,action_stor:1,activ:11,ad:[7,10,15],add:[1,7,14,16],add_layout_to_tab:1,add_metr:2,add_metric_imag:2,additive_nois:[0,13],adher:18,adjust:[7,14,16],advanc:16,advantag:10,affin:[0,13],after:[2,8,14],afterward:6,against:[10,17],aim:18,al:5,alex:5,algorithm:[10,17,18],align:5,all:[0,1,2,5,6,7,8,13,14,17],all_metr:5,all_param:5,alongsid:[1,7],alreadi:2,also:[10,15,16,18],although:6,alwai:0,amount:7,an:[0,1,2,5,7,10,14,15],anaconda:11,analys:[10,12],analysi:[1,10,15],angl:7,ani:[10,12,14,16],annot:8,anyth:16,api:[0,2],app:1,append_char:8,append_dataset:1,appli:[1,2,14,18],apt:11,ar:[0,1,2,5,7,10,11,12,16,17,18],arbitrari:5,area:7,arg:[0,1,16],argument:[5,16],around:[7,11],arr:2,arrai:[1,2,5,7,8,16],aspect:15,associ:5,att:16,attempt:18,attribut:[0,16],automat:10,avaiabl:3,avail:[5,7],averag:6,avoid:0,ax:8,b:[7,14,17],b_tran:1,backend:[5,8,10],backend_qtagg:8,bar:14,bar_nam:8,bar_plott:8,base:[0,1,2,5,6,7,8],base_dataload:2,base_dataset_load:2,basic:15,batch:[5,6],been:2,befor:[14,15],behav:12,behaviour:18,being:[8,18],below:5,benchmark:18,best:[8,11,18],better:7,between:[0,1,5,18],beyond:7,binari:7,binary_threshold:7,black:[1,7,14],blank:14,blueprint:2,blur:[6,7,15],boarder:14,bool:[0,5,6,8],border:8,both:[2,18],bound:16,box:10,bright:[7,15,16],brightness_hsv:7,buffer:2,button:[1,17],c:[6,11],cach:2,cache_metric_cal:2,cache_track:2,calc_max_comparison:1,calc_rang:1,calcul:[1,2,10,14],calibr:[10,17],calibrate_bright:8,call:[0,2,5,6,14,16],callabl:[2,16],can:[1,10,11,12,14,15,16,17,18],candela:14,capabilit:10,captur:18,care:6,categoris:18,centr:[7,8],chang:[1,8,14,15],change_data:1,change_data_click_im:1,change_display_im_display_bright:1,change_display_im_rgb_bright:1,change_display_im_s:1,change_experiment_imag:1,change_graph_s:1,change_human_scores_after_exp:1,change_im:8,change_metric_correlations_graph:1,change_metric_range_graph:1,change_num_step:1,change_plot_lim:1,change_post_process:1,change_pre_process:1,change_preview_imag:1,change_save_fold:1,change_text_exp_tran:1,change_text_export_tran:1,change_to_data_num:1,change_to_solid:1,change_to_specific_tran:1,change_trans_value_sign:8,channel:6,check_pyqt_install_dep:0,checkbox:1,checked_metr:1,checked_transformation_param:1,choos:5,clash:11,clear_all_cach:2,clear_all_cache_data:1,click:[1,8,14,17],click_complet:1,click_scatt:8,clickabl:1,clicked_imag:1,clicklabel:1,clip:[7,16],closeev:1,code:[5,8,11],collect:10,colour:1,colour_lineedit:1,com:[5,14,15,16,17],commun:2,comp:15,compar:[10,15,17,18],comparison:[5,10,16],compat:5,complet:1,completed_range_result:1,comprehens:12,compress:7,comput:[5,6,8,14],compute_metric_for_human_correl:8,compute_metrics_over_rang:8,compute_metrics_over_range_single_tran:8,conda:11,conduct:[10,12],conflict:11,conform:[10,12],connect_func:1,consist:18,constant:6,construct_ui:1,constructor:2,contain:[8,14,17],content:13,context:18,contrast:7,control:5,conveni:10,conver:7,convert:[2,7],convolut:7,copi:14,correct:[0,3,10,17],correl:[8,10,17,18],correspond:[8,14,17],could:11,cover:10,crash:0,creat:[1,6,11,18],crop:[2,8,10,14],crop_centr:8,crope:8,crucial:10,css_file:1,csv:[8,17],cuda:11,current:8,current_imag:1,cursor0:11,custom:[1,10,15,16],custom_bright:16,custom_float_valid:1,custom_mae_class:16,custom_mae_funct:16,custom_widget:[0,13],customis:[12,17],d:6,data:[0,1,2,8,10,12,18],data_api:[0,8,13],data_api_abstract:[0,13],data_handl:[0,13],data_rang:6,data_stor:[0,1,8],dataset:[0,1,8,10,13,16],dataset_hold:2,debug:0,decod:7,decreas:7,deep:[5,18],def:16,default_save_dir:[0,1,8],defin:[6,15,16],degre:7,demonstr:[11,12],depend:11,depth:12,design:10,desir:[10,15],despit:18,detail:[10,12],develop:10,deviat:7,df:8,dict:[0,1,2,5,7,8],dict_:8,dictionari:[2,15,16],differ:[2,6,12],digit:7,dimens:5,dingkeyan93:5,dir:8,directori:14,disable_settings_button:1,disagre:17,disp_len:1,displai:[10,17],display_bright:[1,8],display_imag:1,display_metr:1,display_metric_correlation_plot:1,display_metric_imag:1,display_metric_range_plot:1,display_metrics_graph:1,display_metrics_text:1,display_radar_plot:1,display_slider_num:1,dissimilar:5,dist:[0,5,13],distanc:18,distor:12,distort:[7,10,12,15,16,18],distribut:6,do_work:1,doc:[0,8,14,15,16,17],document:[10,15],doe:11,doesn:0,don:11,down:1,download:11,downsiz:5,dpi:8,drop:1,dummi:16,dummy_arg:16,e:[5,6,11,12,14,16,18],each:[7,8],earli:5,edit_slider_v:1,effect:[0,12,13],element:1,empir:18,en:5,enabl:10,enable_settings_button:1,encod:7,entri:1,environ:11,epsilon:7,error:[5,8,11,16,18],es:5,et:5,etc:[0,17],euclidean:18,ev:1,evalu:[5,10,12,18],event:[1,8],everi:6,everyth:[15,17],exactli:16,exampl:[0,2,11,13,15,16,18],expand:16,expect:12,expens:18,experi:[0,1,8,12,13,18],experiment:18,experiment_layout:1,experiment_mod:[0,13],export_trans_imag:1,expos:10,extent:1,extra:16,extrem:18,f:15,facilit:[10,12],fail:10,fals:[0,1,5,6,7,8],featur:[10,12],feel:15,figur:8,figurecanvasqtagg:8,file:[2,3,8,14,15,17],file_path:2,filepath:15,fill:7,finish_experi:1,first:[11,17,18],firstli:12,fix:8,float32:7,folder:[1,14,17],follow:16,forc:6,form:[10,16],former:6,forward:6,frame:8,framework:10,free:15,fresh:11,from:[1,2,5,8,10,11,14,17,18],fucntion:2,func:2,further:[10,12],g:[5,6,11,12,14,16],gain:5,gan:5,gather:18,gauss:6,gaussian:7,gaussian_filt:6,gaussian_nois:7,gener:[2,5,10,17],generic_value_chang:1,geometr:[5,7],get:[0,1,5,6,7,8,15],get_all_imag:1,get_all_iqm_param:5,get_all_metr:5,get_all_metric_imag:5,get_all_single_transform_param:8,get_all_slider_valu:8,get_all_transform:7,get_correlation_plot:8,get_float_valid:1,get_human_scores_fil:8,get_human_times_fil:8,get_image_dataset_list:2,get_image_nam:2,get_image_name_from_human_scor:8,get_image_pair_nam:8,get_image_processing_fil:8,get_image_to_transform:2,get_image_to_transform_nam:2,get_iqm_fil:8,get_menu_checkbox:1,get_metr:2,get_metric_imag:2,get_metric_image_nam:8,get_metric_scor:1,get_metrics_over_all_trans_with_init_valu:1,get_original_image_fil:8,get_original_unprocessed_image_fil:8,get_radar_plots_avg_plot:8,get_range_results_work:1,get_reference_imag:2,get_reference_image_by_index:2,get_reference_image_nam:2,get_reference_unprocess:2,get_resolut:8,get_single_transform_im:1,get_trans_dict_from_str:8,get_transform_functions_fil:8,get_transform_imag:8,get_transform_params_fil:8,get_transform_range_plot:8,get_transformed_image_nam:8,getter:8,github:[5,12,14,15,16,17],give:[5,17,18],given:[1,5,7,8,18],go:[14,15,17],goal:18,gpu:[10,11],graph:[0,1,8,10,12],graphic:[10,18],greycal:3,grip:15,group:18,gui:10,gui_util:[0,13],h:[6,7],ha:[10,17],half:8,handl:10,handler:0,hardwar:10,hashabl:2,have:[2,5,7,8,11,12,14,16,18],head:11,helper:[5,8],here:[0,16,17],high:1,higher:[1,7],highest:10,hold:8,home:[0,1,8,15,16],hook:6,horizont:7,hover_scatt:8,how:[5,8,12,14,15,17],html:15,http:[1,5,14,15,16,17],hue:7,human:[17,18],human_exp_csv:2,human_scor:8,hyperspher:7,i:[1,18],ident:7,ignor:6,illustr:12,im:8,im_comp:[5,16],im_ref:[5,16],imag:[0,2,3,5,6,7,8,10,12,13,16,17,18],image1:15,image2:15,image_display_s:1,image_list:[0,1,2,15,16],image_list_to_transform:2,image_load:2,image_nam:1,image_path:8,image_post_process:2,image_postprocess:1,image_pre_process:2,image_preprocess:1,image_util:[0,13],img:[3,8],implement:10,improv:10,includ:[10,14,15,16],increas:7,ind:[1,8],index:[2,5,8,11,12,18],individu:8,info:1,info_item:1,inform:[15,17],init:[1,15],init_layout:1,init_styl:1,init_valu:[7,15,16],init_widget:1,init_worker_thread:1,initi:8,initialis:[1,16],input:[0,2,6,15,16],input_str:1,inspect:12,instal:0,instanc:[5,6],instead:[6,8,15],interact:18,interfac:[6,10],invari:18,investig:12,io:15,ipynb:[14,15,16,17],iqm:[0,1,2,5,8,11,14,15,16,17],iqm_scores_df:8,iqm_vi:[11,12,14,15,16],is_almost_float:1,is_float:1,item:[8,14],iter:1,its:[0,7,8],itself:18,ival:1,j:1,jpeg:[0,7,15],jpeg_compress:[7,15],jpg:15,just:[8,18],k1:[5,6],k2:[5,6],k:6,keep_siz:8,kei:[1,2,8,16],kernel:[5,6,7,15],kernel_s:7,keyword:5,know:11,kodak:[0,13,16],kodim01:16,kodim02:16,kwarg:[0,1,2,5,7,16],l1:16,label:[1,8],laparra:5,lapeva:5,laplacian:5,larger:6,later:[15,16],latest:11,latter:6,launch:[14,17],launch_experi:1,layout:[0,13],learn:[5,18],left:1,lend:18,length:8,less:7,let:[15,16],level:6,librari:[0,11],libxcb:11,light:1,like:[11,16,18],lim:8,line_plott:8,linux:0,list1:1,list2:1,list:[0,1,2,6,8,15],literatur:18,littl:15,load:[2,8,11,17],load_all_metr:1,load_all_metric_imag:1,load_all_transform:1,load_and_calibrate_imag:3,load_experiment_from_dir:1,load_human_experi:1,load_imag:[2,8],load_image_list:2,load_json_dict:8,load_new_images_fold:1,load_new_single_imag:1,load_obj:8,loader:2,local:[5,15],longest:8,look:8,loss:[5,18],low:1,lower:1,lpip:5,lumin:[5,10,14,17],mae:[5,15,16],mai:18,main:[0,13,14,15,16,17],main_menu:1,make:[0,8,11,12,17],make_app:1,make_experi:1,make_float_from_text:1,make_menu:1,make_name_for_tran:8,make_slider_rang:1,make_status_bar:1,make_ui:[0,11,14,15,16],maker:15,maketh:1,making_the_ui:14,manag:[10,12],mani:10,matplotlib:8,matt:[0,1,8,15,16],mattclifford1:[14,15,16,17],max:[7,8,15,16],max_it:7,max_lumin:3,maximum:14,mean:[5,16,18],measur:[5,14,18],menu:[1,14,17],messag:1,message_on_plot:1,meta_dict:3,meter:14,method:8,metric:[0,1,2,3,8,10,12,13,17,18],metric_imag:[0,1,2,15],metric_param:[0,1,8,16],metric_range_graph:1,metric_scor:8,metric_util:[0,13],metrics_avg_graph:[0,1],metrics_info_format:[0,1],metrics_nam:8,metrics_to_us:[2,8],might:[16,17],mild:5,mimic:18,min:[7,8,15,16],miss:11,model:18,modul:[12,13],more:[10,15],most:17,mousepressev:1,mpl_canva:1,mplcanva:8,ms:6,ms_ssim:[5,6],mse:[5,15],mse_imag:15,mssim_kernel_s:5,much:18,multi:5,multipl:[0,13],must:5,mutabl:2,n:[6,11,14,17],name:[1,2,7,8],nan:6,navig:14,necessari:18,need:[0,1,2,6,8,14,15,16,17],neg:6,net:1,network:5,new_api:[0,13],newer:11,nlpd:5,nlpd_k:5,nn:6,nois:[5,7],noise_hyperspher:7,noise_ratio:5,non:[8,15],non_perceptu:[0,13],none:[0,1,2,6,8],nonneg:6,nonnegative_ssim:6,normal:[6,7,8,15],normalis:[5,15],note:[5,8,16],notebook:[14,15,16,17],now:[11,15,16],np:[5,7,8,16],num_imag:1,num_images_scroll_show:1,num_step:[1,8],num_step_experi:1,num_steps_rang:[0,1],number:[7,14],numpi:[2,8,10,16],nvidia:11,object:[0,1,2,5,8,16,18],observ:18,obtain:18,odd:[7,15],off:16,offer:12,often:18,onc:17,one:6,one_over_psnr:5,onli:[7,8,14,15,17],open_mlp_new:1,opencv:10,oper:[5,15,18],option:[1,2,6,10,15,17],order:[1,10,17],ordin:10,org:5,origin:8,other:[8,10],our:[12,16],out:[7,8,10],over:[5,8,11,14,15],overridden:6,overse:18,own:[15,16,17],packag:[11,12,13,15,16],packg:14,pair:[5,10],pairwis:17,paper:[5,12],param1:16,param:[1,6,16],param_group:1,paramet:[2,5,7,8,12,14,16,18],paramt:[8,14],parent:1,particip:[10,17],particular:10,partit:1,pass:[6,15,16],past:14,patch:5,path:[1,2,8,15],paus:1,pbar_sign:8,pdf:5,peak:5,peak_sign:5,peel:16,peic:15,pepper:7,per:14,perceiv:[10,18],percentag:[7,8],percept:18,perceptu:[5,18],perceptual_dl:[0,13],perceptual_trad:[0,13],perform:[6,12,18],pick:10,pickl:8,pickle_path:8,pip:11,pivot:1,pixel:[5,7],pkl:8,place:14,platform:11,plethora:18,plot:[1,8,10,17],plot_metric_range_mlp:1,plot_radar_graph:1,plot_radar_mlp:1,plot_util:[0,13],plu:8,plugin:11,png:16,point:[1,5,8,11,17],polar:8,post:8,practition:[10,12,18],pre:10,premis:18,presenc:18,press:[1,17],pretrain:5,preview_num:1,previou:17,principl:18,print:15,prob:7,probabl:7,problem:11,procedur:12,process:[8,10,15,18],produc:[14,18],profil:18,progress:1,progressbar:1,project:[0,14,15],properti:[0,2,10,12],proport:7,propos:5,provid:[5,10,12,14,15],psnr:5,psychophys:18,purpos:1,put:16,pypi:11,pyqt6:[0,1,8,10],pyqt:1,pyramid:5,python:[10,11,14],pythontutori:1,pytorch:[5,10,11],qcloseev:1,qlabel:1,qmainwindow:1,qmouseev:1,qobject:1,qprogressbar:1,qt:11,qtcore:1,qtgui:1,qthread:1,qtwidget:1,qualit:[15,18],qualiti:[5,7,10,12,15,18],quantit:18,quick:[10,17],quick_sort:1,quit:1,qvalid:1,radar:8,radar_nam:8,radar_plott:8,radiu:7,ranc:8,random:7,rang:[1,6,7,8,14,15,16,18],rate:18,ratio:5,read:[12,17],readi:17,real:10,recent:18,recip:6,recommend:[7,11,14],recreat:18,recurs:10,redo_plot:1,reduc:5,reduct:5,ref:2,refer:[2,5,8,10,16,18],regist:6,reinstal:11,reject_low_nois:7,relev:11,relu:6,remain:18,repons:12,request_range_work:1,requir:[0,1,11,14,15,17,18],reset_clicked_imag:1,reset_correlation_data:1,reset_experi:1,reset_image_widget_to_black:1,reset_slid:1,reset_slider_group:1,resiz:[8,10],resize_imag:8,resize_to_longest_sid:8,respect:[10,18],respons:[6,18],restrict_opt:[0,1],result:[1,6,8,10,12],results_ord:8,return_dict:8,return_imag:[5,15],reult:8,rgb:8,rgb_bright:[1,8],right:1,rmse:5,robust:5,root:5,rotat:[2,7,10,14,15],round:12,run:[3,6,10,11,12,14],running_an_experi:17,s:[15,16,18],salt:7,salt_and_pepper_nois:7,same:[2,5,16,18],sampl:7,sat:7,satur:7,save:[1,8,14,17],save_and_merge_df_as_csv:8,save_df_as_csv:8,save_dir:8,save_experi:1,save_experiment_result:8,save_imag:8,save_json_dict:8,save_obj:8,save_util:[0,13],saved_experi:1,scalar:[5,6,15],scale:5,scale_factor:[7,8],scatter:8,scatter_plott:8,scenario:[12,18],score:[1,5,10,16,17],scratch:11,screen:[10,14],script:14,second:18,secondli:12,see:[10,12,15,17],select:[10,12,14,17],self:[0,1,2,16],send:8,sent:1,serv:18,set:[1,12,17],set_checked_menu_from_iter:1,set_image_name_text:1,set_plot_lim:8,set_preview_imag:1,set_save_dir_mpl:1,set_styl:8,setup:[1,17],setup_experi:1,shape:16,shift:7,ship:0,should:[6,11],show:[0,8,10,16,17],show_all_imag:1,shown:[16,17],side:8,sigma:[5,6],signal:[1,5,8],silent:6,similar:[5,15,17,18],simpl:[0,10,12,13],simpler:8,simplest:18,sinc:[2,6,15],singl:[8,16],single_trans_dict:1,size:[3,5,6,7,8,10,17],size_averag:6,skimag:7,skip:11,sliders_dict:1,small:[5,8],smaller:14,smoother:1,so:[0,1,8,10,11],softwar:[12,18],solv:11,some:[11,14,15],sort:[10,17],sort_list:1,sourc:[0,1,2,3,5,6,7,8],space:18,spacial:[12,15],spatial_dim:6,specif:[10,18],specifi:[8,15],spider:8,squar:[5,7,8,14,16,18],squeez:5,ssim:[0,5,12,15,18],ssim_imag:15,ssim_kernel_s:5,stanard:10,standard:[7,10],start:[7,15,16,17],start_experi:1,state:1,std:7,step:11,still:16,stop:1,stop_flag:8,stopped_range_work:1,storag:10,store:[2,15,16],str:[0,1,5],str_to_len:8,straightforward:10,strictli:5,string:8,structur:[5,18],style:1,subclass:[1,6],submodul:13,subpackag:13,subtract:5,sudo:11,sum:5,sure:[0,11,12,16,17],swap_ind:1,system:5,t:[0,6,11],tab:[1,14],take:[5,6,10,14,16,17],task:10,tell:16,tensor:6,test:[0,1,12],test_datastore_attribut:0,text:[1,8],textur:5,than:[1,7],theh:14,thei:[0,2,16,17,18],them:[0,6,15,16],thi:[2,6,8,10,11,14,15,16,17,18],thing:17,thread:[0,13],threshold:7,through:[10,12,14,15,17],time:1,times_taken:8,timescal:10,todo:[0,8],toggle_experi:1,too:18,toolbox:12,torch:6,torchaudio:11,torchvis:11,tradit:18,train:6,tran:[1,2,8],trans_nam:8,trans_str:[1,8],trans_str_valu:8,transform:[0,1,2,3,5,8,10,12,13,17],transform_funct:8,transform_param:8,transform_valu:8,transform_wrapp:0,transformation_nam:8,transformed_imag:2,translat:[7,10],tree:[14,15,16,17],truthfulli:10,tupl:6,tutori:10,tutorial_1:14,tutorial_2:15,tutorial_3:16,tutorial_4:17,two:[5,12,15,18],txt:1,type:[5,6,7,8],ubuntu:11,ubyt:8,ui:[0,2,8,12,13,15,17],ui_wrapp:13,unchang:18,under:12,underli:10,understand:[10,12],undistort:10,union:6,unsort:1,until:17,up:[1,12],update_annot:8,update_datastore_image_list:1,update_image_set:1,update_progress:1,update_status_bar:1,us:[1,2,5,7,8,10,11,12,14,15,16,17],usag:0,user:[0,7,10,12,17],usual:6,util:[0,2,13],utilis:18,uv:5,v:1,valero:5,valid:1,valu:[2,5,6,7,8,14,15,16],var_nam:8,var_valu:8,varianc:5,variou:12,version:[11,13],vertic:7,vgg:5,vi:[0,1,2,8,11,14,15,16,17,18],via:2,video:12,view:[10,12,14,15,16,17],view_correlation_inst:1,virtual:11,visibl:18,visit:12,visual:[5,12],visualis:[10,12],w:6,wa:8,wai:12,want:[15,17],warn:0,waves1:[0,15],waves2:[0,15],waves3:0,we:[0,1,2,11,14,15,16,17,18],websit:11,weight:6,well:[10,11,12],what:[0,16],when:[1,5,8,14,15,17],where:18,whether:5,which:[2,5,8,10,11,12,18],whole:[8,14,15,16,17],why:18,widget:[0,8,13],widget_ax:1,widget_ind:1,widget_nam:1,wiki:5,wikipedia:5,win:6,win_sigma:6,win_siz:6,window:[1,6],within:[6,14,16],without:12,word:16,work:11,worker:1,world:10,would:[11,14],wrap:0,write:[0,8,12],www:[1,5],x:[6,8],x_label:8,x_shift:7,y:[6,8,11],y_label:8,y_shift:7,you:[6,11,12,14,15,16,17],your:[15,17],zero:15,zoom:[7,8],zoom_imag:7},titles:["IQM_Vis package","IQM_Vis.UI package","IQM_Vis.data_handlers package","IQM_Vis.examples package","IQM_Vis.examples.images package","IQM_Vis.metrics package","IQM_Vis.metrics.SSIM package","IQM_Vis.transforms package","IQM_Vis.utils package","Tutorials","About IQM-Vis","Getting Started","IQM-Vis documentation","IQM_Vis","Tutorial 1: Making the UI","Tutorial 2: Simple Customisation","Tutorial 3: Customisation Details","Tutorial 4: Running an Experiment","IQMs"],titleterms:{"1":14,"2":15,"3":16,"4":17,"function":10,For:18,about:[10,12],ad:14,additive_nois:7,affin:7,all:[3,15],an:[12,17,18],analysi:12,bright:14,built:10,choos:18,code:12,common:11,content:[0,1,2,3,4,5,6,7,8],correl:12,custom_widget:1,customis:[15,16],data_api:2,data_api_abstract:2,data_handl:2,dataset:3,detail:16,differ:18,dispali:14,displai:14,dist:3,document:12,effect:7,exampl:[3,4],experi:[3,10,14,17],experiment_mod:1,finsih:17,get:[11,12],graph:14,gui_util:8,how:18,human:[10,12],imag:[1,4,14,15],image_util:8,indic:12,info:17,instal:11,iqm:[10,12,18],iqm_vi:[0,1,2,3,4,5,6,7,8,13],issu:11,kodak:3,layout:1,load:14,main:1,make:[14,16],max:14,metric:[5,6,14,15,16],metric_util:5,modul:[0,1,2,3,4,5,6,7,8],multipl:3,new_api:3,non_perceptu:5,offer:10,other:14,own:14,packag:[0,1,2,3,4,5,6,7,8],percept:[10,12],perceptual_dl:5,perceptual_trad:5,plot_util:8,post:14,pre:14,process:14,put:15,qualit:12,quantit:12,result:17,rgb:14,run:17,save_util:8,screen:17,set:14,simpl:[3,15],size:14,softwar:10,sourc:12,ssim:6,start:[11,12],step:14,submodul:[0,1,2,3,5,6,7,8],subpackag:[0,3,5],tabl:12,task:18,test:11,thread:1,togeth:15,transform:[7,14,15,16],tutori:[9,12,14,15,16,17],type:18,ui:[1,14,16],ui_wrapp:0,util:[1,8],version:0,vi:[10,12],visualis:17,what:[10,12,18],widget:1,your:[14,18]}}) \ No newline at end of file
        @@ -1059,7 +1084,7 @@

        R

      • resize_to_longest_side() (in module IQM_Vis.utils.image_utils)
      • -
      • RMSE (class in IQM_Vis.metrics.IQMs) +
      • RMSE (class in IQM_Vis.metrics.non_perceptual)
      • rotation() (in module IQM_Vis.transforms.affine)
      • @@ -1157,7 +1182,7 @@

        S

      • sort_list() (in module IQM_Vis.UI.experiment_mode)
      • -
      • SSIM (class in IQM_Vis.metrics.IQMs) +
      • SSIM (class in IQM_Vis.metrics.perceptual_trad)
        • (class in IQM_Vis.metrics.SSIM.ssim) diff --git a/docs/_build/html/modules.html b/docs/_build/html/modules.html index 08b1955..9663930 100644 --- a/docs/_build/html/modules.html +++ b/docs/_build/html/modules.html @@ -126,7 +126,10 @@

          IQM_VisIQM_Vis.metrics package

        • diff --git a/docs/_build/html/objects.inv b/docs/_build/html/objects.inv index 96af66f2da13043fe31c206c32700f663b7c2635..5d252030891a01673e7afbb0b7e6c69c0b7001d3 100644 GIT binary patch delta 8800 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 W2N{3QE34N1s7Bca4*w706W&cbl*qFH delta 8684 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%0D|HZ68twKE%r4cMvoR@uwys+%^YQeeMwHj&t| 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 Karl2VN!-bh9HBq} diff --git a/docs/_build/html/py-modindex.html b/docs/_build/html/py-modindex.html index 650cde1..53abdf0 100644 --- a/docs/_build/html/py-modindex.html +++ b/docs/_build/html/py-modindex.html @@ -174,7 +174,22 @@

          Python Module Index

          - IQM_Vis.metrics.IQMs + IQM_Vis.metrics.metric_utils +
          + IQM_Vis.metrics.non_perceptual +
          + IQM_Vis.metrics.perceptual_DL +
          + IQM_Vis.metrics.perceptual_trad