From 6b5ea5931dd894862b6f18bf9637e1fd78dac3b1 Mon Sep 17 00:00:00 2001 From: Bernat Gabor Date: Wed, 27 Jul 2011 17:52:27 +0000 Subject: [PATCH] Added the "Mask operations on matrices" tutorial (with its sample). Plus modified some other core tutorials. --- doc/conf.py | 1 + .../basic_linear_transform.rst | 10 +- .../how_to_scan_images/how_to_scan_images.rst | 4 +- .../images/resultMatMaskFilter2D.png | Bin 0 -> 26482 bytes .../mat-mask-operations.rst | 135 ++++++++++++++++-- .../random_generator_and_text.rst | 68 +++++---- .../images/matMaskFilter2DOp.png | Bin 0 -> 9132 bytes .../table_of_content_core.rst | 21 ++- .../gausian_median_blur_bilateral_filter.rst | 2 +- .../discrete_fourier_transform.cpp | 2 +- .../mat_mask_operations.cpp | 86 +++++++++++ 11 files changed, 274 insertions(+), 55 deletions(-) create mode 100644 doc/tutorials/core/mat-mask-operations/images/resultMatMaskFilter2D.png create mode 100644 doc/tutorials/core/table_of_content_core/images/matMaskFilter2DOp.png create mode 100644 samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp diff --git a/doc/conf.py b/doc/conf.py index f54919f97c..e6ea3962a4 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -355,6 +355,7 @@ extlinks = {'cvt_color': ('http://opencv.willowgarage.com/documentation/cpp/imgp 'imgprocfilter':('http://opencv.itseez.com/modules/imgproc/doc/filtering.html#%s', None), 'svms':('http://opencv.itseez.com/modules/ml/doc/support_vector_machines.html#%s', None), 'xmlymlpers':('http://opencv.itseez.com/modules/core/doc/xml_yaml_persistence.html#%s', None), + 'filtering':('http://opencv.itseez.com/modules/imgproc/doc/filtering.html#%s', None), 'point_polygon_test' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-pointpolygontest%s', None) } diff --git a/doc/tutorials/core/basic_linear_transform/basic_linear_transform.rst b/doc/tutorials/core/basic_linear_transform/basic_linear_transform.rst index d5c9a268d6..cb605d0ccc 100644 --- a/doc/tutorials/core/basic_linear_transform/basic_linear_transform.rst +++ b/doc/tutorials/core/basic_linear_transform/basic_linear_transform.rst @@ -8,13 +8,15 @@ Goal In this tutorial you will learn how to: -* Access pixel values +.. container:: enumeratevisibleitemswithsquare -* Initialize a matrix with zeros + + Access pixel values -* Learn what :saturate_cast:`saturate_cast <>` does and why it is useful + + Initialize a matrix with zeros -* Get some cool info about pixel transformations + + Learn what :saturate_cast:`saturate_cast <>` does and why it is useful + + + Get some cool info about pixel transformations Cool Theory ================= diff --git a/doc/tutorials/core/how_to_scan_images/how_to_scan_images.rst b/doc/tutorials/core/how_to_scan_images/how_to_scan_images.rst index 675f80c2ff..e521b828e8 100644 --- a/doc/tutorials/core/how_to_scan_images/how_to_scan_images.rst +++ b/doc/tutorials/core/how_to_scan_images/how_to_scan_images.rst @@ -58,6 +58,8 @@ Another issue is how do we measure time? Well OpenCV offers two simple functions t = ((double)getTickCount() - t)/getTickFrequency(); cout << "Times passed in seconds: " << t << endl; +.. _How_Image_Stored_Memory: + How the image matrix is stored in the memory? ============================================= @@ -175,5 +177,5 @@ Finally, you may watch a sample run of the program on the `video posted - + diff --git a/doc/tutorials/core/mat-mask-operations/images/resultMatMaskFilter2D.png b/doc/tutorials/core/mat-mask-operations/images/resultMatMaskFilter2D.png new file mode 100644 index 0000000000000000000000000000000000000000..cebbb4c33a274aa793fe1a703f4e8f42b16a7961 GIT binary patch literal 26482 zcmV)kK%l>gP)mQyM`4TVDlClDj;?d+V4lprJ{ zy?9@dW+$(8R)0|&4FLs-JOwmHAeVeQv$L}RR{&a$5lR>iypAN1TMwnFt{fE*BQgzn zP;WCdH;QyRqHtAIBuCra+c_yKzf(PePZPhKYpiS$oK-DWS6e73Wy8hA5fd6f10%q# zhK58M8yZO)E)1u}hbt{JiI0=k*Vn$8WTT5qJ1jVTGX<+_COS8I2bI& z-}Ed$8$v@yJ0v!}m0M3kOq5nDu5>s67ytmq01pi$oK_n^OE)YSEISJ%R!b0uk)4;k zWy7R^Z*gJwwHxG>(gjpj-{|^7F;g+9Vn?080Q( zdIcgJBhs*2t8E;dO$yPlR+~Qx4+9HC1S-v~V*~~X9~T@G6F!YR3wWT(q-q<>t6Xnx zZJbXN%c)e&vVDLL-=*5~;Qc|ppL&l&; zot~X}GYpApIL)tXd#^Y@s6kOQNuP8$6bTamtN^LGyZ}Q0Ekg@I7aTrMCle0|oseIx zb}6qc6}QaaTq+ZvL-c2ON+!3M(lshcq%hJ3NIp3yfMDYH_Hq00001VoOIvTXejY zGynhq32;bRa{vGi!~g&e!~vBn4jTXfAOJ~3K~#9!?7a^_Q)ikk9y?0FnrhGiRH%oh zU>LQEX;UDhz|T;sK^om`fa0JLho+Mdw8l_tMJ$*)D#5`

(pi8|18urPvm5yolf| zq*f=*j-6~QUR-p_GMG`LO^2I_-uL~^NdUF8yR-e>y?3^+AvsA-lJEJR_j&((=Ol9S z^JDXmoUhBz&wn+4=FI%rv32=%`LX9?XVz&Jao+pUr<{l_At52}MZCjV6tRWF;VcT_ zEc!I$M-f|o6hXGPa6&@hVa|K+!EWRlE)nE<(H647`Of}*CWr;&yt?XN3)Wo*LUyj& zx$0kM{x)`J`-=S7v#~R0MgtRzm|a7*ED8y{3^%qc!V7C#LMFcNpT7HmF)!Y-3xWwm;JmXXB7zg~TF9h#7I7why6BydzbHZ=g-kRg=cDtnb*K=S zrb&4H37L^k-g_+sUHY9xTi#g&6BohE`fFRzZ*j*(K;V{;*FME*9!zE#yKrAU}MHwZOwfPI@hZq;?F3A@4w> zTJ-6A@4#i!JD>jdA>=h^KL9^W`D+k7J|&6$9jt_2gWBg44utR5Lf-q)q%E&O)Q`YS zfP}n`bYSwuZOGFYLVzwv3|J76q6;3xU;+;l zg-jxW<-JKEaDnKuh{QFl-ri&0h;)%~4doJf5tdbp9ud&Cpj@%+gEUV*6-CB*54|Pi zzX>7cZ{<@W{!;w+zn&1ycT@BoA>R@59UeZ_mLh2r{*px#+i2u7O`aeua!HN~_oVvP{f}IN&?p(N& zHQZi0Wof}eanqmmwoOeO`1dD`?C^ilObAuqw*6VdsCsk#`t_Xr6_C-K4|^=LrVj8b|JfQ{@U***gyaCKWAO$ z99aMA!}jj0uYUCF?FalaA8UMK0yK+-rfI2ES_Kvv8L3jSUjJts^LmvE-VEOp-Woo@ zVj&+U*1$(IBk*f{GBFS+lZm6nGBmS>ukkZm(b2SO%A0qHA^ZuG|Nfl`Gd|`~;6>uo z@NxppvQ;V_gN4@g?=f~?X5dok)~yx+P8GcCX|dlNaIp0C3j~&u`c=FDA+Hibh>auVK}N{fQKL=&3B%X3peFLcM?!o)+>*)s z8ky|P^>41%`20YKSSQ?{SY3K}ScrQ}h35Na7h zEL#~$g1jKSsy|`DC&ylfe2ga~z)1S~vtXAmpFIS&^eiNVf~AL+UYq_j*!1`nZ~gkI zrwJ#AKH}_LF>~g-D^|R_qF`p-p;sZl=hw|7_Up?GA!Brm7f4l5Adg~$^Cy!C=i#SS zEGaC$ASE(Thz#dX<|Bke!-Y>20-Ole=cn_eFG>!+-LKkLYytgJWJ zC;g$LqvMA^{9)zHYbSq*7JqFfXXA?e{MFkp=f8SBKmXdh3s<+Fhhq51<+_=#UcTcG z^6@Bje3Lc;nf)6x`lA>L>STgSEI^3Bp8|!4n9nL?N;IPonb;Ryuym+X>+`hH( z$i}4eZ?5>~Dd&NZrFZ<}=-@vbtR5Yz$YlR%g?xjC7)mAtE}w=k;Ddu{WPFTXe!wR7 zu{p%2iI%0aIYc8C_@|^V%$gEgSFrwU`u4Xv*RSuq^ThhjDetG>A%r|25C4ShvGvat z$2Z7i93^6sNuu985S>m6i1a(_?;L#NJmmf(jR^ZTYo@>EH3~;E}u{N zXhmKAwX-QNtiQbT$dR4rS%r+3hXwig_o?IGDtkGBJ^wA02s98^U3Ma%-Hu9}o6)z+gLR;YWm!_V#vYN%He!>mY2c&X1irGi4?a!cC{iM9t*i7!|TPppR@Fd2lbDF==~$~cq-IXx?D>Dldvo_ZqdP}X*m)ek%< zk8hEVZ-`uDlwc}}zQgblWMq6j4gm};>(IhiUqwQK9Xj^xGx07a^#=%fgg*XLrPVhV zT#u-KaSTMPvhgMkn#?B_n5ST#fDQn_9$^cttRq=R05-`W2+gD&8y^@jSl%8Lko=SYAu!c-JKN!dK7u*_2%g%B4>7iCRqRKB z%{SgiVYYYv53~a24mjQFSD8KPQr4|oSHQfsu3+D~H^^)2cCLy|DcG12c%QoVv+cq6 z{}!ySfGFh7LY$!XoplV3*t(DE+6w}oQ}^390+{M%zwrk1_{?^KV`uDxIAUWzTeog@ z-592JGBYWwQc~JijlE~ep@P_N6UP`KAJxrXH@kgjL2MoTYj00k^#;xu+^Jjj%U`al z!$-m1*td>=s!J(<^V-K7le+L;{`dYN>+<*h;oW@lmg_dgwyz`aQkSxCXa4MsWdD8p z@;7dLW)&-p*ws_AR@Z%N&NYFMx`H=WwHNFR;F$f!P9O(I`P*Oq632yi>SpiTw-a}m z8T&yJ;CO2DP6o&2fBoL~&LgR@`5V^(+ya6dFy#|WvH7cJ)fF6>wU3>e*p#d(E51D( zb>j(%g?UGVt-76XyYH93+)1W#)ibkZ&3fY_GJ^bdvwj(yk6Z1Vw|{T-_qJ~)(pt4{ z_Ut25R^&6z1pii%m*($WSFo!64Kg+RX3gHX?wO5*vy_6Yg$vuiO&q|2h9%^q*#yQc zobMC{5)pXaZvn=vePl2=ud{X%9I;*7zxV2||3UFT@X;0PHvaa=lvS)_wIA8Ja}|rJ zU{%3J#8d}PwehoO_7U$)S#kDILBY3(V*(*5INoQTc?M=U|F_SOJL}-HK8oG>2JrD) z;wS~MIcwc-akJg=#=1B5&00$ovThwv^$g>3b^CU%Zr_)}Dx^Jj_Bt~7eLqJ-Lh4pS z?{=ghpYgG8S0M+0kaf=x9J67*Q)Uq$vxwIeteW-AzS(3mW#c~J26>tpTmBN_Xd?=l zJ!@wED)bt7%lso7Q&QFiF~t&0NC@H}3Q2(`H0w~^w}@i`AvpSdZ+y0qxc|O&>wpg? zO6AWc=*R>Ez-OKzKGE)c2F;0%p1<#>vscafISH(F3%9-e**+%r)@A)*-)H+6Da=~e z-oEp7LP%`E!lf9n>b`x29Kam%#xt|tcw=2Ve!#kYfMXUDd-K}?Qa&4ke*VleKVL;= zRRNo`o=JR*=;p6B&YnfQ2Hd9er|b4@WM*LDuL77LM6|cJ&zeOZU$JoE*@ADVbH0U; zRTn#JV?KEhKOleKx;nA}0SP>tNg=?<&wpM(#@k->`s>`+U%#J%LHR)X#@X%dBrvSd zq_1vIVP@cvc>U^~WQW+gm+`${KSIJpO2N{lvEM3=@r2aXeFpQM&*1ndeW)Ms4y-)tQqnaA?d{BLv}@Aa3s_9+_T_(+zwZm?wJR1L zN~!xct1O0)Lo4duWj-!tT)uA)R91DMkd1-rr2XaD`ON0@B(#soPKQXI~jfbo1^8W+&AKLlbvK7#& z10gFO#*rWF9{!^^{wshWA@4)Ty0+uvN7=P&8#i7XXJ-Qk>JMdQJ@wR6*RDPFfL%Lu z=qy~09617avZjzF%%{jpv$Ei!Lua!BdmcGLHnWaAY}@fDC+y1J&ANPf!d_3E4ZNCp zIP2_FS%;=X%RnJ_-W-qP8jOEBToA|fkH=8JID#h}Tt33!2qL)_0CE<-1cK&i^ti;8f~b@bJ~2G@{YRQlPfYNqrq0d!h3c8YJU|+Se7wFGi!xBcsOH# zwhGG{wR|NQMNvw%NojRAHjb9@ctW@c@k|^v_G}mnpD+D}6KP;4i$v`eaw4~GrIc2D z$Znx%J_%WOz8W|9HRFLSW^r6(aj4}U^Z$2RBeN<2NJS$v`Y{|Ch(jlU(N_$qnUM%5 zPcEwn9kdB~jdEF)n<6;qP=nQ*5l(p#1pEbXFhC*>GM1;Ls=hdcbB&efXh7B9WWZ%@%5C zs5B!yyfLF91FW<(qp>jqu1vblPTgFZS5`5gl~-}BR%@9%qjAV2r|HqgP?v9Xz+^IM z%%{|*fzpc6QTHhPS$S^QaJ#)$tI#SGTJ6>`gTZs~F~-Wu%0w<*GEkzb;+sPa zHmi_RB{vBeg`7NoJSQ^;u5#`n5P~CT&&@rs-OU1#e0Y!nVm^>=aU+h#F&w3(Lyhpj z(9fRe?2H!J%iIH6mjG}GdG3mgA(Lj17L6vG#Uiy_tu@JglrEibp-iTJa7wouaai3I zc5f4ZhQp;)h z^s>p5M{6V&k-Ky>Bh*(mI-pjoO>##>6eStOSv5{fEqB$koE!l+=jlG8yQAdg0qTp~gk6&a;o zyItrGuNl?)c)*8AZPHREo!AEc6dtP8%FJeuTrR7JNM@tz0hAY9h{xkuA04a+ACuiR zW}T}SsPI~8nM-a0!B?>g`RebEAJ6>itKs7b=v>6Lh-2;DbF+KTV+054gWy2F8VYX& zeOzUM5FBtl@LcCl(3>)nlR+OGt9x>W+N-h)dEweJlSjo1MXxf`h6B+mtJ@u(94ePZ zM^}fMPs=E;GSVUoHD$OF2l^L#jE98~077t-xn1clSFdT*D+IB7GU+=?(kyo)3gB6p&Z8VWQ$1ilo&QNi+I()mTmLbz5wXooZc50@%OdBBI- zZIW9nKoAC#j0)BG+!;6#p)#edYO6p{#jAmAz;kfWtj1EDH~{hgWmT0LP%({ye_ya12z>g>W?)RtaPv7Hfcz zAk=rf6$vwo8a}UBUi{r7qdmcmAVw7HLfCR$g7z0vK(OBJyewC5j>k>3^gl>3p zXw)4_3oDXE8PyivfJIbe^0;;BDr=}Y{f^FTR*sHhyb-$9;35@jt- zF<|gwL{)0l-cnP2B&C(vl$4=fT4ke^N|FU1b}V9&&T3t!8J!9s+blAzQiFuNc`{)? zz}Ub0D8X@W_&9?jr~76%=0XU;MC*t{O_h?2&fusZDUk`hzlahN9C9Y?UTqv0b<4#n z;AC?0X#A@e7PT1T}q6>aiZy~-iOR%sPYK@@&4 z7xIEQM4dW+x>@3{PBtldsw$bs%M!Bx`0k>jWko2Gn#LP}fK zn5V9Du?ag9NkU!AlpxsX*xA4+&(TS_1k& zKJ27MygJY;acjX07I(7CO;pylKW^#=b@%ilgVW^%Smv8nZ5{wP)eIg%%>rV zlnxo(yg{uJ-HzeIim9H5u0{HUez{Jk=`_2@`Ep{pK`CGfIR)}S9Lw~_0SBZJD1f_( zXYCK*xVZ-%%P`ar3FILhP$_<4hj=B|Y9Vf68XWqWho=rTcnqg`13HmX?hOys$*k38 znE-@uPIjA29*w3NvN^%guO5Ih%SxsHSRiyOsUhezMAbt=Ym+sI1L|FC07pelw9cHa z^Y~?_Ps=ps0k8COAcyRRClPMvjEI)x9)jQig|C%k4rMN`mlYv&;j9ilJUBrwmFS&kf}w z4V{*fI&BlWDQMbU617@6NO{K*;#ESaUj{Wb*yK{J8P6P{tEy}^l}I43w?*S2-1X2; z0gjyg1jq0g4vbk4u2>v<9=p^(1cgOuX#hunl8Ovdx&?%utd>|ffa59<)=Sf7z#$h^ zfX{_0M?-ZUo3QMnvLZY*-RFVw*GJd;sR5-Iaad^!O;a{A6wRZh$-UKLiODVC2XR0< z!c!_qee9m>9<9jGM*moLS|(MgR8YJN%vvj}kfKu4u#;j7-hkATQ6Lp2t(L}om;pjJ)zB7+JQOObWbLSFbfDMcqM#>EP7dug8?+v+ z+z>tlH87U%6!a28FKsf&q~6gXt=TUYNCiG0?Y7x$EE1vB>qS0zL@LM%KthU?YRH@x zACp7YXMT?U1m*ki@c<6!uDb8#usAT0?76w-;Khu|6{XnP5-M1~YOElYA_OdGUM0Xs z##Q)dQoAjK+TPQmvSbg>WTARBE+16($rejO@l!00mQ%yS436V#2#%Xr`gRkETy*yXj{e5*jEXVO zLS|rmG!Jk{Tm%Qmr?FQl5}K+{(>#-oR{MCp(Gt&ShN(9_+NF^wJ(QU;RabYqlz?ME z3js=KReH=a$n74DAN0#Bv)To6FX%gf!&WxhnBg76F*zfAXu!bd`~5OGZK1{~1T>B! z4-&Hf-f-sr{ee^hjC5a`+z&v;I@2$79wN@suh~+r#7QRJExx|(#6(m#0Bcn zJS~(5Kx8Z-w@;z5OyJEu6nxGwY1_L4?Rr#ye+4MLG}uG2I2u79beUQXG66oWR$L8F z?zK>(CYJ&Ds8&l1RH(=2gRCKP(=s^-!Y!bOpl~qxPs^9p-gxfhaov))u?`M{rcX4Qrb{YDKWPBEIuFU)Ylg!41fN4O8^H}zH5#b zt+}U193&qS9G5PZ_E(fv3{AiRj+T-9vucSjBh>W^8uCaZJe;f>gfdYlk@AM_NYrw- zw%W(Hl$u3C5#Ow)Ldyhn8Q_Sf-Mv5F!T})x4q=lwgYtMNTyf#?gtS@gs*ki8lqN6F zs@!{N(43Y(HQsb=S)*Hk&{!*HU~ROUN+c0}&)Jod~vv00t^YTm`}!3zy~= zL!_ucJ|+i&K-G9Pytmp_Rw|dc2BFZxG|}5x1EESTal1`siMpmj>lqv^9e{*k8dVw$ zK9`yYsWDwgQ8@o)rfLHW(CRip+NUt2Vur8_V79$pC0QBr1{NBH$VyrAbG@d4A&RmX zEVPoQ`4(C%hLEK>vOY5pTnj4R01k$lo4^X<*ng8`k(-Y#F2hwF00IGn!GYE9)r{oo zYLUBFB9TCVoLrHdoctzaMw3TQmkp)MC@s%aEfb9ndFX-AQJz}n(`c<_fTPoA^YA$w zUQN2(YHez=4nW$k$8lm6A{6ie2I3eE;)q1o;#r02=aPpY15h+&pq1V#etnf(4umXS zk^e6E6)3_}0_AOJ~3K~!?|=rFV)N3n)K&Mczf%~)oCZ1H4Lkp#*sh7b@)bv2Z@ z*q}p06%IJ6Ysx0WePzagwx(w9-k+Vk=pNF_EOMV*tv1kJbEsQgot`dN%A~-9x>~LT zhp|E|He;1FTBC)AUJ3OIq-&H&DJ}wAZC;cSseI)p;WGx*5{cX=flrB)4tAO`hh(ik znfLjr;Zu1>Vc>`+VP3+T2XNq8&|^`+2S_9Ugn$7c;Xl*4cv_c4&M7Oa2v4p~?vy|P z>($ckfzX=%y^HshNO(i?)1z{kTwW@pg)W_YG&%i!v-Na6$e};oj5vf;wGQhro*Qsz z2PmP`XBzT)sm4*j;YA!?XtbavDdS0=+nbzhq9hWRZ_p*DtWvsD2ZX$Ne&(-lBOj+e zZ|TtAzCCXqIM;3#M*`qrf)+a0!NvU*llv#&K)-qp1kx{;pgx9@89pvTVjRuT{&7!9 znsGzYl}i!{t(Mbjtw9FGt;^%qrgw@dHSkde>7K?4e$=BA%cNGyLw6+!rOr2aJmPjrBbU7*{3#u$YaVp_9CADeyVc}@ndjOtVrqUXc?;zz5ZWL<$*?^YJ^mBYTi8PbFpe9>vNbzpx0%Vg9s%-MlgVt zR##WkkU=1!m#V|VP0*K5o(yDkDEj)GBiv@=uCM#9L}^bOv_6B}0-d1ROslI6Q1}8L z6h|CSm2y7(p-3JQ(w;|s2t^UX^+n<_tH9FS-N2$ z)P;PQ(&Zcu^zNsB%(w9j9+?W4tn4DYs>#hNq4F1{N<%$u$94maf}N|d;KB^=We!?lK!Cby6cUTpU=!MXNK)ihX%j~ZWv`D3 zS)YSG5Xa{%j@xT8({dnW741$StBh-){H;6*wQu+0{{Dbxk=x0=2da5$*F~6JsEALN z{A}^$y^0MR)*79C&CSNP!l}hyI~TmZSnZ=Jvz)FsC=H#$&^rUwe27B=+{REd z&|wM%w;}^~L-nrq&>UftmE0r8c*#J)-XVZ zp>rooT2M3YFG3vqqvYzz6+|YCRFZWPVXxc`0trw4$2&xgjw+$%a>;#$ zdKnzmO?@5MR;xl*WFgSLTCU*?S z!O0gdLJ@e8WW~~}P!Z~AksJbVnc9>*=ZVU=P2~=Uv$+s(aCa3qJDR6%h->@oO4I?L z$Y7x9(O$6^7d`+$X|E2#uRB9q4@JE}t?fOa!;=f3&ZxrPa9{{=^lQy7pFv9paZr#E zt=1Q%LaWz8No88ft2KMJvP&mv9UXZHBCqB4=STI!^G>Cuk#+>Hc4NV~KL^8BH%f$5 zTK&jL4V3cz7onST*U-3}T&h-|jDtjOY;ZUnt=SI8)Eka7#pOn4T-@_lqTHYXFSL*9 z(jf|vl&O=eQ6C^`%A~cp00DyV`>?|W7*y$~o04lKTAxoYu~Y?Cu$#b>q*5Ey?MkYi zvd|X3OfEiMZ_w}snzK_*DilCQ2jWP`(`P2kOY7Kud-rX`0i`@Ll9|KexOuQ2PnxNL zuA_#uRuZkwUZci?-GJl6xciC)#zKdqu(cKZE4O^=^z!C5z>yTiqqX%kkAg~nC<6*| zUTJc*&IfsL$V3@D0^flHI{ez1W-b}Bu#6fiEpvOcP@+TY=aU9k;;nY8)B+J0a6lLr zNcpEdW>0-!>10^nf@1$X@8~H=iARTrPbGYQn;c=sHM%vptd+n5*?Xy<30VC#HBfeH z)itg`ca0nPxY}5;SK;Iu9geW#V;gps@0#jJow_OeuG87q^ZfUtE*dDiRh_KWdgNMz z*IEPJB(#AQYKqp%m6RF3ux2*PMI-`w@zjkn9_@o3>8vOcNwb@)HWPnf^Fg0Eo6d?6Jfk4F^J`_Ua#X}<;tAMsy`24Lj z${j+mO@5grB#*VD|I(2L$$fZOpO%(Zl5qU?Jgl>h=P;R_oP%;{az()U0gGHBAEl9x zimMfSHo=den*s zrnFj^euFt$XZFaH$^nyHYoaJ6F6@$DO+p5kh>QKMlAI|-c!8209;n9)U&a!`!Z>yG z^OGf~PPOFRzMZD;NK43JaNH{*IQDddcL5=R%GK zg<-c^jjhui%`s=DIhwf(lH%H)pC1(^47Ca^8rj@IS_=)Jy1G~Gwpxd@O0@@)xKbRg z(|9~0>wq>HA}Qh^70K9FWEmVJ+7TQ=tIF!7>iLwizP>)NmUT3*Lyti8ijMgBVUS2i zQb$@x8aS4|q^Rf~9@9lS_7~-VM4+nz5LYX3HT3FL(1~Pm8HC}hdrxjU1DSm4lCB#u zVPUr#91T+)j$6&f1gIS(2WtsJW=kH!qSLs{c8 zLlyzynQEZ(@Vc3r3k$0nwFI)gT&u+sf2?IZEV$G%9|b`h0yha+OS3ZbF!sKkm-n+{_a2;#h2mB6ui`2?*F`*TbanC{ zvo|=M;8w?O9J@6&mmAic>TvAh8W;4%^~AlN8MTT$R`L6Zb(1wyV1yitM&H6CIGEmnkiCjC&Z%KjZ!9_7 zb-2qBb_>)ob;G8Qr}sI5kSj$X5j@ceN&r7rg*C}Koz6g2hic7QHzW(ckM_FNa_DV! zW|s>(C67xk2L|8{7+?UKOMYDoT1JYj4$A?R&t=9vJhA{GijKTf07RkJcO-nCIS-1H zf6-4bNz3f`L+0+|_jd0mi*swbfsmWfuMb@f;DC(^2*r~pXZ%KytuW>`cimXhwWP~2 zH5YMY-`(+6pR=v+`JSTJUyibZiUz86(XuKI&n<_P;j-$g)fx{>yIeDu#{m_JsDj;2vrJKd_{e%#o zA9MqRxLo+>hhWDOO8sWB9Di5?$n(6Y5ePI3w`cw}i=*Rn0HTjSnJ}DrN*@okR!2!@ z&YFaT1jGSs?BBl^fGoz-7Q?R+r6U{&VOJmPTCPtlT#~yaYl{ouG4J8-vV)o zT|Ri+>}N2zT+ofx@PsOVv`Zoez+$slvo#p9^4@+Mu)N)Z%}9&>_&jK<^ewk<&l?`T zeLOR*BnLSuD(c2V3j1^R9#osc!^x=*0Xj-ziXFy=8!;c8IC1WSt`lL?KHku_q0eY+ zZZkTa+{F2F=A4Y`PxcJj$*H13-bIN=F7wfLp%Av3~xpe+*bGPYS$OnQz2rhE$ z5ULXmI+$PQpF6jcJT5obnglXFV35niW_i6dKuF%(gc88<`KdhpnuOc)ZfEM}B|yxA zG*a^1R|(Lr@6W{Z=Wg!L+;dP1IKqQC`mgq97PmT#%~MZw9g8`3;zn04cgK#z;`qM4 zW(Zl%w!~#~=FC4hIaw!H37J$TlJthkaDhQcn?pTfk=N84{e^$7q|+st`-NWzTLC(8y&?L51Yybtv>~N^I#!YiZHz zZ|n7G`gy@!dsaQ44FWJ%9YLW@v~J31)NS0*F?*UB`}PpKCqQRoq%06T@|s zJB&5+miCu6{>CwNK|^6~%&~LX$6C*I<<8FT z+mYBD(*}hJ-~h*(v24!#IW_4nAvswTVen{yh^I6_k`@iVVy*FjzexOZqs{o+cOdY& zP+R$Br!9C2vW)NZ0}hQp+CNu=q`2U&+{>x*$pwD?Y4K@~oZ4O&BqWdJqa{xtpOn_p zk)-cPN=i!0OvqHEWs;~>#2n*6J9zNm;){4{GBWa;n~JtVOdcnWffdJ`$UbA-(N_pg z1t5Tr#KgoIGnUPd^7ksSxNujH6PrgVgWRJvnQ)C=?jq61Zw6iCuZjtzDl4ZcQbmeG zt5g6F0u8#k%szhqHox4ZwOM_>dRqFTv`YG-3<+6rXg9EF$DG8kf)WdlNmW^7 z8i{1?AOtg)e=dUq%2XwX4x(QQNAo5aWOjX8d>VLGTH0LCMX1Y zs+)W8AbU5SBm3AvJZG*H`1n~&pR+LR#^J*s90MH3vSW;(Z*F;C8_)qjxBz6?ycx@0 zpDQ0IwcGQ$kHM#JQW9d-g#6i#Ybw zlvWHudY`;^`KA)%)Gnw>PMkaO!HMGK<%!${iH_m`j*-Mf?!0-+ihku87yumPg!o>M zPp}fgkxYgt&~I>bW|=@Fs!}yEXI3-oBtq1P*sL4WboyPG*EMFpM(5I*wN{%zDp3N% zLYpi=$Y0~|N$IQa$om{h_hCqdc#x+Bd~5i2kzQYfCp4~snh|<-a?&!Mw|uE)=zs3j zPmL*WNWF3RgI3_3i%Z*DMN!&eS_wHXo?B@XvTx}Voy-KCk z?zPi`L5a`j8x#Np5e;5O4&vY!NpNvQNx=i#ZHF!vew#a1AnkZ!? zhqNz+90I|r17j8xjGyPl>ra6$)_i_6Z=~b*CHmXDGePVLMMVkS%-X|276-)NtG_w5 zD|>^n5a^hF4p7XV{c#_++!)WzR&Y`3ZOvR~$%ua0jQzV`cFA>k(pH5!)GQI%-QZ<* zRh3{6>O!%PFQ~HHq18~*z=9V$aW9@4038Wx#OD`FG#VFr)?A6?3rLA#d9_+dTYRS> zdVA&4tbA4>Z|Bv%jWvAU+t9Rk#CNpBKV6bA+|r`>eNqXsu^T$w${btfFytp+ULXh zha^!25Uga;kfL!-#2|q%h6|At+^3Ncm4N(y84v=wUZR5-4F9UNN*gFl4mrd^2zhtu z6+#H9v7nHLGArrxj_ExKIr^g|)323eG8N;RlCPjwM@G62KE~kKbMT9c9c_sXVM|W5 z9)n1=eCpH&hqI4sY-`@k9Vz5;xoyrwMNgc5By-u7HLpW~q(+&`{T7~=^2sS$iQl;a zX{)f&^HORYw^A)P01lr8T0VmC9rmizPCW zLPA!bUzP_MT|vUuDG0oIPfyS6n4XlG2{E|i_9>`U=Hap2v=Xwuh>nG4kOLhDqkdC6 zTT$2**45hDx}&QV0&w=GkM)oSn+x^Rm-n?L)+Q6%DmKt zDRQD1Dx1i_02BZlJgeOXd1Vk!im^6DM%tA4TUiFo6MU#z#6Ah6bhEz`DijP}&@g&w znE^r@C1VJg|JP6|5*%x>WBK)R z6R+X2xT7^@$&K8Yu&`r?m)v^Gv7~%Cw=c2TxY@y-em8L>O`pi^Ns5c_iQf%4=0r)L zsE|l_!cmi5=!GI4fEWx03zR8?gCZ+9o3#o80N@bNDvnBJlTsKEd>|u>7zXYeoU0LQ zT%FOR1b`GD>J`eM+_EYSEFpP+oyWF@9b^suer4qoSFZHTnKS46-=7n(m(ea=di~{> z4dV8zmUMx|04K#$!*;dyK}o`0V5}V(Np!|3?k6U;ITd|vPRQy-MVEjO z2}CP3jYm3^7@=s9t&0B1Afyx<{z#hAYqMjNf>6e30zNDjJj)02NR zBm`0lYJ`?i21C71Bd};v&S%y_$a)*Y)(`cVNABOROqw$XaUc*J{}(KZs1Gk84xnQ3 z;;6;HIeNx1HSBQljjoszpb}%4W9Qx41>D*N@wFrK<~i?YSB|vkd*bfScj^HL^oB0K zgvNz9yU<-q!2n?BRd#xCP(sr}3wRg65mwPsJV8##u>nqtPww*p4i&*6VQ^qF5fdC* zrAkau+WLAnWa(>>k{0MbDz99Dv5#2~8oM22<>fEP?WJy`gPRJ3VE#DK)s=he)~;R9 z2DUX90w0@`6p+jl6Z?Kw$&GWCESq1n|Me)zpw~?qXrXnKqU|Jecx_g@2srRs1_cnb zAc(<(B8kN-wA$!FpTLJF%POr+e6eJ3&<}%We#25i6yo<7q4!%K0mR11t}5 z%=vy0$ny-00FLhy96v=Ea|l6~^tmIcVPS_`j~#>Z>c*|G++Dk%>nJn=j(L64lS*cc zB-YL-C`pWqb7oc+?azqYl$M6nhUMdg*A@jN^qv<2`N0EAFp zf0@-xZCH8g)Fp=xpEv<2Wcj%r#kU-V4#6W5*0=Bm!0g6;<y+KR6z z6!(FUdGj-KqDHA23zoKS7_<`O6|@{SkqweJEvm8u9}s?(w9Q^6s zu%`9aScMRIq35u2tTdNgK4 zv&%yXeX@E^)~kdNgz)@0DyB`FhDcswjZiX?6L>+JBPohI z9DhrStm0!a|}= zOq;zaQcBbI$Vk+O&@QBD$mc@4jRQF7Dh_k_#s-l=AQSj-X#yGX`?g^|1V~z&^t6<- zoh9V?fEvD@2IFV0UwY|bLIRA$K{VwS-oSMJK^N4#%U{^BW5@CxA44Lntp%6jwkZ^e z3lz@U#5Snjfs*@imGdieE|u}DZY37GFz+Jb{N&_Hl?q%+Wo5nzVr^0ZN?Q{=2@y>+<8izc)Ch~CCoZnX*_;Tu zyzB4>9~?dbI9}M%n!TfSdLqPK?z|DGc9TXHBq<>L_VnoEpws0lzN#$RTZZQXphCQ; z3!BhpQwi}DQ3MjH!XwQ#p^5|4P$FxS)F!o|e#lSl;(>IF%uIeB9ZE*Cc$*HBA#57( zg)AY@Gs7Q0_Rn5=00@hOiNQVKSLI=cKR8x=?!<``=U&*6oxNkn3p*4LuSleFwke#@ zg+O2EjEloXphQLGGGJse526*+AP{{;c59PWrDD(84IEIzuirM=ZFU3&b#J5vP)N*$a@PsO z03EoN1=N)6o|iNyYO&JG6N&6X<|`~#5~Gk5+t?SO0Sp2qZU*%(m<>7-i$x0iL<;<7 zF_elL5Qm2OFJ#PeYD^*17EEJN+{MdFcfqm7aq=}Avj9mP;&>kT2!HIK#qc}Ue z_|~l*vtMW}P#6^>Bek_7SSGghDfA=YTy0$BgB#a#|KMj&L|t^#fI|d);BpmyV@*YV ze*#844u=KXa|EKa;?D!yRFO)GFSXe?O;W$+G~m#=#H4L|1=}>v z9#Y7dZ$00WSO{70gJV!!wLyr2;+9e>wOXaj{{dkpi*rQl9s_tI zL&y^^F*pd2yN|#zEr5e@uAY{WCE!@+5XTGIt;JKjHoVZfVcL$qK7~_XsBaljJUxQT zKxy|C@kHp{Wh3)@x@SCb>8B!Qgm^f?N<51Ifsv{>3=Tl2s-mqRax2IjK&Su*uwu1R zAQ`9{Jp>0fB)BFCIJDBHKvMtg?%lf&5whtaAdE`-7R2q^)qsSYLmV;1xv36EYHI3| z)ZF;C=J@!{iseatcb#O3RN+*#kpm(lJy#S(^X6ZQDr1gN37M}+Sc81nh)UR>H&InZ zLRROfL?rLqY$9BE6hM1L+pRVWW)kv0EHTGUTzK|8O9)~he?bt41CcNhU?Ps^Z=Gv~ zIe|5$UdMc7kJ2AQI3#bS(^9h(m0~@&pPkYk-iKHhq&Z5&7#e zMgU6>H|z%1yXaS~#WA~(jnvex?9{OG&BnIA@qm++M|M<}C&f9*svOv| z5$+7`m3jAbE-i*S3NMI*{hAk4x^@u+sYvn*Ggwc7*qb78wTmV&o&^fyS*OmV#%W{0U3QN@B0T zzm)>MkLW{;Us0M!NI)S$950Ol8Hd9OVqkF;$7JU^a;GnksYM)193M}=JMZJSmK7{a zg1p|xX*G9>Hd%Ib%3}@Z>}s_E%m3 zASC)i{iq!yWSq($(g;Hcse~CIF%IZz52MhR7suQvOfBzQzPS*AG&D4nEBfNI=W+WK z;7~?jVx&*8EHP1kKQZzC{K{oLnLvne?8lZEk=w@jfQr}#sGzj6se&-Z*~);uLQFsk zVY$H;AS4DO*2MAOeFzBCBEIB2w+S2zi}u!Y*)cKP!t%bm(~mZwV>J|RR@|-p_~wkh z_!7W@A=jByr03oTES1YjW+<*4q&b18Yh}VJjWB3T?9i29&kOBGm55Su9>B4Zy$ay4 zgS{e<`Q;LSdm}t)n58KrwFa zOWcv2mbgiQH7|4|BO^VPP|V-IA2)y5viVmImN7Ax;eaIq%3OvJXrQV{dt$emDuHD?= zs7-AE?=q$>Pq;h1V`S5{7R1pqGBPizWJcTcD~WNH(BoF_S!Y9%u9(Xqz@{*f1d@A`%dLUt-~n8+a<*2f#;+!vTbp zuWeY{kXq;{Y$$X%a+@8^BiO0q(ObP9a^d|rC;Z*N-vgdCzw+c{A;H0%3(9cAWDTsU zBJn@n1bIBj$CKz>gqD>o7$#(~w@?nV3dtofVm6K8AV4+*2_Zo6dZhM7SJ($#m_e2= zcR0!$nv0EvYu7@NrElOmjM>fx$4J6FZnHB@-&Rrr)rtN-w2N`~6MK3<>WL+bg=Fkr zW}z3)55=ruMKDnP;;9W#0k3=(hJ4{c92W=>Mkg!`Ldq*umI;IqC}WhIIddjhubg2c z7W|cyj_`wH=ay#|hc%S%DtD}ni8rP~fkLES*sytRGZ)jjk@O$XCH5taw8iP~qtq*V zDi`CooV|=ZfD;idLYWJ3EuN|7trPfo{KADNFTme*HgE-ERe%x#L@KQsBV@y_@vgNg z2;>a@3*eXrIKplm{u^8sUB3KQVR`v3$J!0korMj021jjb`R3+ABLL}Z!!8PN#9f=w z7FU8HYvf9g;vm6c7jmqq5x_y?(FDMuA~>2jO;sue2U2kT@y8#3^7@6x85mElydDsE zz_(VuB6vkmC1`qxkRX&ZyUvWWV90XZ2)ohM^#R7++%QLT`E*Fn5`>7=X4H=)qSo7z^lfp8iSv^x=K~>8W$gExNu^~Yhtu(Ukl5!EMu3j%EE^Y) zkL!$wT}SV_{$xPz<79$)L^@s}K_I)%FgO?}7FD%S0 zR;&dsnz?HW8=$jt7@N6Jnm~UGHG5j3e#Y-h+CU*Q;-8p*rKjg0&&J@u*ekRH9au6# z9c*K9ARSL)w7S6f)w35MgFJcR+3Od;uYU3*6L+5_*8m{|*%1h;wvQ1qQ6EgedVr8= zUmF{c4m|#`JU1*1qSUSUW(ZfCHy1+q-E4&D<;ab9aPjPhHU&srpM>it5Vt@qDD`FY z50F9qZNyzDxi>D zqL2*}2tf}E8Y6XQ*o_;Ya1T4D=X2V9wY?g7UCl+VW3=pHjv)Y zwZ?_40FGT_*>D1mY0j_X8g7I^*^W4N+-i;~Zv%&Nl-D{Gn+uz3YuDD+rWO`wE6SZQ z3cwN1ENKxOZAmi{D-#jN{3rmRva?@VQQDZFWdR%*#Rv{a9*;l%<(JIJFI@i;uZZ3e z$4UV569&hV3?~8s{B7AjK4h`Bi#3!wL&?;sjAI!cxj@LdV~{|W$D}rtV{rvRYVF!) zD1O%#VrnnWZg%YIQ$Pm-zEzv3Ppow+a1{uW$o>13D3K^$;CnYjC`2Q6paqwDv2)ow znp4Z00SNlm+GhA$3%nE-p4s7Sh%s)~7bbF@fTILTt<62$xEXPACCl!Y0FGrZ^Vrk) zSR5i|Z4n%+=>Z&%ql0}3f7kJ$FF_(dfSmFy@BvN*T#(X>so_<@91>Lct{@>(cLfzf z2mvULu&~3R^K-|RXG5tAmvZRZ8_H22$PL7;)LJOD97eKUV&vB9A(iyS>AA~$5-Z#8 zFPi~CqTG?piOM8I*_pK;_F$n39P9d%tjb~V7f|0nWl#~NlYl%HvaVkbP!i}v&g>e8 z1CQ}f-8JpZh6ix;HH3vN`I~bw=gwunfB;epa}~7>sWI`J3sD>d$I)8IBMK)TkcRRk z4I-x2|AfV{WkOQl#gZ|m67;DvQv)~_aB{6Q<= zI9JR~#bqDIbbWJSYWdouA76v+ux%}(bF@K^#pTwv;pzJbr%y5CrM?*iN8*ebIZ=kc z-^#3=VCusqQ581nHUb22AP*P*3Y_Xoq~pR*pCx#Jqn|!baQx~?W`z#;cqPzXjU!|i zj5(l<4P!A2bib_EvUnDg>=m?&jJ;l>1s-pDRptKoY4X zr!C@wuQN%J=!8z>J`l2O_v=8&i^vI{?P|4-{n#_&0D%ypf5~JKq~QXS<9|v**AE`Y z3iwxp(7v-N@j*fYI5q@SjzBPrObq~;x?p*EVb{51p!4EvBjSj8+S%Fyer0S(RFt5H z8KLIFl-N)Xo~7qvM-`_~IQ!yfI2HF3@6QJuGm4@R$BSDdIYRs@DmjUlDIbYrJ&W=6 z@xMZk!r_0(==;kH+aRl7fAULUSKR9-xczJfr)bfT@T)zT6G_2j+yt(0MEnx)MD2D_|N?)h5%@`jS4`d{jBytsy z(-X1Fy%bdsIDTA@Sgh<%rQ;!6#6bwTKG%KHE8+O1E5+DQz9>{`YNo33rh;c2qp$mW% z10UG`F)JpH*5ap|AuS>y|GTa$h;8FcufYa2BT*|6$iWgJQblZ$(Rcw{wNMBPP?NZV zYytsO&kR=Vws2{UEO*%uo`p$30oSXcArCN+5AGrAG(Ln{7}^>;j;)|#j25O~>%fJ< zjx~q@7Ax=~bLS8$sEburhoDg3_s@`&-R#8T$j*gN?|3(JjI%=-LZonlK2n%5Z}X$~mT z=(SjjHRkzYix7t6CDTT#C6YD>{Ly-5Yl7iJ2eKNPN~C02E#l%q!L^CLE6JLX1rY7H zA^QYX0X2#u8I=nKB&-Bhmf;I59t2{ei}gT#dgPyO-@OYQm)<(VbaJPIgN;m3vaqbE zW>N9-I}JeLM1MoKI6vYR$8lo~F6^i7goa&=kc%ID)rq}~4w8v0_*d!Z*{}GDU7^r} z)l4YV1uATn=8DB)GNZ0%i$YOm5|NFyj17EPTGD7Gf*!Y7%Z~aqbRq|flon(3EY({C z;}TJF>Gs{LbZGyLH#|bTip6{cBsdO}iQf@jhi5$^prq4ei=bwVweOvhwa~`#k}a-O z`7j+lweJ1B7_Y7-K*$D7s)0k5i>AO=`WDxuqV3`^iz^e?HN;=SVfgwEe9dO51{~Su zFmN11>xhfN`bT#e3g9>cPTT_lt%b$H6)h{bgAyqz0)bw2s1sqct+WLIFq1g$V+g^G z_~oDf*_$3Ao+w_vT52G3R*6jJo9C47nX zgi^Fm)O6IuR7ElD zFkjSlE6f5Ha3GyqB3J?)!-wL$M7(1tH%z84@e<_LhOr=F1d`HW4AM8jh%(n z>eAiH#j>yC=(N@x-GbUJ!jZ08IgYYQ!|M(Iaq`&ze)1o^NzcXGINYh6M+fra{%muD zPQ|UQE$>dy%t{q}-Bh-kO3f&m2F-s^ev9VAgOdH;Y{qA+aC1t&zS@=H;Vg0@;t9i1 zsDE_k+-+J>9*#3@9G6{zP(W?w?sn0gDpJEPD+u-MudD73+NZHH^9gz~SNZdHo zmN?cR7v3fp8O-H!I{=YB#!Q_EdHd7-mekwvz1&?sJa5=n?U!A2?q@Z#kWdvH@yhdb zlqt06wqn{Ff~_c!i&-?g@}^=dm0Bs=gg_DpK4is%Cv}wGdOZ-m_59>*^7V6sgWd1a zuV;6=TQ?)JoE2s(i{*Gn7ah?dJ9Id7BAmq`X<_-L)9J<-kiP^|GxNAqg5VK<<)Y2!f^x*`y#u5;d7OdE58pdy2q5 zXR7I|1oDW9XbOQN8mli31#jIrdG%5Y2Sxcy=Z?NhIG(XB5UN-X?kG;=>J3H&BtkeW z^t-V2v}KK5K87__g)7E)j$NisJ^%FWuV#~-sY%Ksq`O5)4*{ukb#2gdcbSwOD#Aci zO^G0A!AQW#LPSyI?rRboKFCzU07j{(6?g|2sSKBfqff3J1crN~XmOWr-MZEP54T+m z>^gV#VvCTlzaBEXQZ@v0e0L@I*s%RWOU99UU$iN^5CIJ|>a){{|b zbWvIiM8_A008a$O}T^gah{NiXx0^#kxZ*DvK&G!+}0=ES%%uCfj(W z*%rPi_I~mgZ-4dSp+OdVDIX#PIQGjL-^C7ROyI|lnq<>ERzr#{@2W)`?_G&x(MlC5 zZpjReY$_+{frR^Xn6z~8Drp7-hZK+tv76-aCT<2bDeDQSa5LIq58 z9M13O*j0tASGgQ)q?+F0IQYl~BIM1j)T@MeHt0>{%KPQn3eRs00LQ?BFJTmAEmD(L z>_h~OM?$8?Lz{TmY)UkrV|`T-NbD2nrJC8%(F%anx9ZtgX)9Jhe!l@AH~RnlFphT_ zA(t5riX+sllY6kG1x<^3Sf{Av;;_i79q?mDDtwGDsvBqO0i}6IoLX`9D9kQWO3niV`uC# z6!MGrI|^}elo!07&=q?3eoxOViqkT13{2RvYUjt5{^AJUr0l~0fp(lL_-^dELgptmUi zfeOgR?Sy9HIhY0CEjN=)**kDm4 zJ9h`94#U7~9b_<8pc42w(b8yu7qa#^u*9E!^^2QC$SZp~9u78+qlw%;D%QPS+Lf9L zndqZZO4dZ{w<1K0#CtN{K6U227J|Zg(~M}EFE5oe6S5g^Hm}42R}Kirh>HW){yEb#ieaRe>2DjG!xYa=9>-EY_<#@N@R|2Xow`oE1NkJNEMr-hAUJ2$_9l zWqGF9saZW`RNm!#18Y->?$81ZkcPW76y?o~$@Xm#vdoYw*yJBnts*5&E16p6#gk#` z2C|OCb=yr-PlZa>QJ+m4e2pAZcm{LO-+du>{i-x43FYg;SNEm!kkwbkY#6=V< zSV`uJMo&eD)_V_zV~cg#V;dR)BT>RJw=_+5_zfU1ARQbqb-O7# zH>$a+j%w?GxAdbyh6AfBy>sll%U-8GoBW>bkao`MDXX@6YGZR?Z6c{=lp^(oJR*rK zC99o$3gJlZ6t?IOx%!14GY>gr>MS*u59h_6{gk#~FB6W8 zHlfNHHpD7M3}NDm(08AuUct6CgV$`}5KwdtQ??1nI#yQf;K_@6ED#%6q_7x_#+Fcf zp^z4itAyjC3j{IOFNXCny>*DZ0XV2y4$K3jG=PKi!^(4moV8;O5|$mjq~qZu-Uiiv za-oGGb*NQug~hVM^QV5by0)1~YA9E#Kxg6!sI!yt>iW3GW8q_1ObDaOn#v@=FPAlO$xCLiTT@um4BUsJAr?+csRC z(;){1XndNs)wll7z2jR!EUVc0C%tpf`bYt#7nPUcAX4tMa6B6m!!8cW>LTkwSX|uB z4FUk?Sbm)o2>=JJ)4H^6wCdh69XP0$%SNVU&pOlv|H%m zD0lBk{O<1R>gt2gT1`+H4zq8?5Tr~ZU!d(m-V`Dc!@j<#Y9=}>MU!MektB2C#ny$d zXZ|k8a4bz13bEka*;~Nzyp3b>Vq58PyzhBGBCemw9p#GQK)$jb4U!w?2nWr9$k}yp zl4dy4W0yTb$kf|}ytcBCvdTP-vDP+MLm`c)Ef03;N03YZzjE~MaVN!IxQL?_cI^3qGUc(WhGyBU7hsr`Oa3GXK9;%V?fRr^AB*aAD!`Z}n zBTG3_M)uVNUqQ~QZA)kAq#?4QLjz`FabbodmrFk&wEd_600ZYqL_t&n zh%~C!So|0favgmLdB`Dcye5&d%pOL^6-v@abh5E~Q4T3a_S*V=Sh$^{4MRvCcU!h2 z3Sh`urDE2m=s~yMUKCyE1LdkP0)enkck2J+(W6J%!(If0o~oh=5SwCAsG?B`)Qr3C zrC)Lo-LZ6?k%2FFghE1Z9P5;iW#owcg&(Zv_HNfuZ`@7~x<*o_{k*Ks+4J z7>+T>gFM|&*@_Y_{rm}0l@S89`*ll4xuPn}#ZjAtt9alb{RWt*R4m@y>LN&N9_w zh*&>>g;47K<(;E+wQ!tfrp_{!=*;WlJmgVjy3j>2M;?M=3moV~NIIZ{^@y}tl|D>J z(p^|D+iG|Bp@CyRRNA$>mRAQhAKc52uAN}VmVl!&o^4M3`-*w|{=|>IHEG~0JY12X z5veI-U8z!YZyfq~@pW(Sm(QW{z~Ukb7L@MdIQ?r6hYRF~6tY+_6s;ynqk(XeCPHRFNcnpRDU&6#6MrgSJVnnwQ)8&DWds_s zqii8D$~36PH!CK)5Z~#<1~np@psAtR#1yWXcRuf(i^U3oMWpz%OXnY-r^c}VBqQVw zBjogHRX)-t6zEpppOT-TG-D zIz2Lsg>`n0aNM{x-~XS$amQO&E{-^4uFva!bc1Z;L&tJ*INjpJ?ezBh4d}&9^HdH{ z1gg|l(ePv}+#o`7PyhB$D8$pqEQ-{r(}5G&1P78# ztrqg4B52z0*DHAzrt@GPqC+}zMmFgQ)0??g-MK#Ho?~S?zp!*1#NdNf3|sV6~R}_=SO9J z<@iInVrK8lvacwhD-jfmBeo&&^e;ZsrzrO5)Q_WEQ`c!_eg4xg5a8#&9U3{i`0e>= z7l$kLU*B<^kS(k*e%RtXsTuv>_Dvc~>$yjed{~cPMw`1`<=Ax8&%xirW1`sD;ll2T djo` function. + +The Basic Method +================ + +Here's a function that will do this: + +.. code-block:: cpp + + void Sharpen(const Mat& myImage,Mat& Result) + { + CV_Assert(myImage.depth() == CV_8U); // accept only uchar images + + Result.create(myImage.size(),myImage.type()); + const int nChannels = myImage.channels(); + + for(int j = 1 ; j < myImage.rows-1; ++j) + { + const uchar* previous = myImage.ptr(j - 1); + const uchar* current = myImage.ptr(j ); + const uchar* next = myImage.ptr(j + 1); + + uchar* output = Result.ptr(j); + + for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i) + { + *output++ = saturate_cast(5*current[i] + -current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]); + } + } + + Result.row(0).setTo(Scalar(0)); + Result.row(Result.rows-1).setTo(Scalar(0)); + Result.col(0).setTo(Scalar(0)); + Result.col(Result.cols-1).setTo(Scalar(0)); + } + +At first we make sure that the input images data is in unsigned char format. For this we use the :utilitysystemfunctions:`CV_Assert ` function that throws an error when the expression inside it is false. + +.. code-block:: cpp + + CV_Assert(myImage.depth() == CV_8U); // accept only uchar images + +We create an output image with the same size and the same type than our input. As you can see at the :ref:`How_Image_Stored_Memory` section, depending on the number of channels we may have one or more subcolumns. We will iterate through them via pointers so the total number of elements depends from this number. + +.. code-block:: cpp + + Result.create(myImage.size(),myImage.type()); + const int nChannels = myImage.channels(); + +We'll use the plain C [] operator to access pixels. Because we need to access multiple rows at the same time we'll acquire the pointers for each of them (a previous, a current and a next line). We need another pointer to where we're going to save the calculation. Then simply access the right items with the [] operator. For moving the output pointer ahead we simply increase this (with one byte) after each operation: + +.. code-block:: cpp + + for(int j = 1 ; j < myImage.rows-1; ++j) + { + const uchar* previous = myImage.ptr(j - 1); + const uchar* current = myImage.ptr(j ); + const uchar* next = myImage.ptr(j + 1); + + uchar* output = Result.ptr(j); + + for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i) + { + *output++ = saturate_cast(5*current[i] + -current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]); + } + } + +On the borders of the image the upper notation results inexistent pixel locations (like minus one - minus one). In these points our formula is undefined. A simple solution is to do not apply the mask in these points and, for example, maintain the images previous values by copying these values over to these locations: + +.. code-block:: cpp + + Result.row(0).setTo(Scalar(0)); // The top row + Result.row(Result.rows-1).setTo(Scalar(0)); // The left column + Result.col(0).setTo(Scalar(0)); // The right column + Result.col(Result.cols-1).setTo(Scalar(0)); // The bottom row + +The filter2D function +===================== + +Applying such filters are so common in image processing that in OpenCV there exist a function that will take care of applying the mask (also called a kernel in some places). For this you first need to define a *Mat* object that holds the mask: + +.. code-block:: cpp + + Mat kern = (Mat_(3,3) << 0, -1, 0, + -1, 5, -1, + 0, -1, 0); + +Then call the :filtering:`filter2D ` function specifying the input, the output image and the kernell to use: + +.. code-block:: cpp + + filter2D(I, K, I.depth(), kern ); + +The function even has a fifth optional argument to specify the center of the kernel, and a sixth one for determining what to do in the regions where the operation is undefined (borders). Using this function has the advantage that it's shorter, more verbose and that because they are some optimization techniques implemented usually faster than the *hand method*. For example in my while the first one took only 13 milliseconds the second took around 31 milliseconds. Quite some difference. + +For example: + +.. image:: images/resultMatMaskFilter2D.png + :alt: A sample output of the program + :align: center + +You can download this source code from :download:`here <../../../../samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp>` or look in the OpenCV source code libraries sample directory at :file:`samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp`. + +Check out an instance of running the program on our `YouTube channel `_ . + +.. raw:: html + +

+ +
diff --git a/doc/tutorials/core/random_generator_and_text/random_generator_and_text.rst b/doc/tutorials/core/random_generator_and_text/random_generator_and_text.rst index 5e3f1dec65..fb487cab71 100644 --- a/doc/tutorials/core/random_generator_and_text/random_generator_and_text.rst +++ b/doc/tutorials/core/random_generator_and_text/random_generator_and_text.rst @@ -1,7 +1,7 @@ .. _Drawing_2: -Fancy Drawing! -**************** +Random generator and text with OpenCV +************************************* Goals ====== @@ -9,15 +9,15 @@ Goals In this tutorial you will learn how to: * Use the *Random Number generator class* (:rng:`RNG <>`) and how to get a random number from a uniform distribution. -* Display Text on an OpenCV window by using the function :put_text:`putText <>` +* Display text on an OpenCV window by using the function :put_text:`putText <>` Code ===== -* In the previous tutorial we drew diverse geometric figures, giving as input parameters such as coordinates (in the form of :point:`Points <>`), color, thickness, etc. You might have noticed that we gave specific values for these arguments. +* In the previous tutorial (:ref:`Drawing_1`) we drew diverse geometric figures, giving as input parameters such as coordinates (in the form of :point:`Points <>`), color, thickness, etc. You might have noticed that we gave specific values for these arguments. -* In this tutorial, we intend to use *random* values for the drawing parameters. Also, we intend to populate our image with a big number of geometric figures. Since we will be initializing them in a random fashion, this process will be automatic and made by using *loops* +* In this tutorial, we intend to use *random* values for the drawing parameters. Also, we intend to populate our image with a big number of geometric figures. Since we will be initializing them in a random fashion, this process will be automatic and made by using *loops* . -* This code is in your OpenCV sample folder. Otherwise you can grab it from `here `_ +* This code is in your OpenCV sample folder. Otherwise you can grab it from `here `_ . Explanation ============ @@ -81,27 +81,23 @@ Explanation .. code-block:: cpp - /** - * @function Drawing_Random_Lines - */ int Drawing_Random_Lines( Mat image, char* window_name, RNG rng ) { int lineType = 8; Point pt1, pt2; - for( int i = 0; i < NUMBER; i++ ) - { - pt1.x = rng.uniform( x_1, x_2 ); - pt1.y = rng.uniform( y_1, y_2 ); - pt2.x = rng.uniform( x_1, x_2 ); - pt2.y = rng.uniform( y_1, y_2 ); + for( int i = 0; i < NUMBER; i++ ) + { + pt1.x = rng.uniform( x_1, x_2 ); + pt1.y = rng.uniform( y_1, y_2 ); + pt2.x = rng.uniform( x_1, x_2 ); + pt2.y = rng.uniform( y_1, y_2 ); line( image, pt1, pt2, randomColor(rng), rng.uniform(1, 10), 8 ); - imshow( window_name, image ); + imshow( window_name, image ); if( waitKey( DELAY ) >= 0 ) - { return -1; } + { return -1; } } - return 0; } @@ -122,18 +118,18 @@ Explanation * As another observation, we notice that in the :line:`line <>` arguments, for the *color* input we enter: .. code-block:: cpp - - randomColor(rng) - + + randomColor(rng) + Let's check the function implementation: .. code-block:: cpp - static Scalar randomColor( RNG& rng ) - { + static Scalar randomColor( RNG& rng ) + { int icolor = (unsigned) rng; return Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 ); - } + } As we can see, the return value is an *Scalar* with 3 randomly initialized values, which are used as the *R*, *G* and *B* parameters for the line color. Hence, the color of the lines will be random too! @@ -192,21 +188,21 @@ Explanation int Displaying_Big_End( Mat image, char* window_name, RNG rng ) { Size textsize = getTextSize("OpenCV forever!", CV_FONT_HERSHEY_COMPLEX, 3, 5, 0); - Point org((window_width - textsize.width)/2, (window_height - textsize.height)/2); - int lineType = 8; + Point org((window_width - textsize.width)/2, (window_height - textsize.height)/2); + int lineType = 8; - Mat image2; + Mat image2; - for( int i = 0; i < 255; i += 2 ) - { - image2 = image - Scalar::all(i); - putText( image2, "OpenCV forever!", org, CV_FONT_HERSHEY_COMPLEX, 3, - Scalar(i, i, 255), 5, lineType ); + for( int i = 0; i < 255; i += 2 ) + { + image2 = image - Scalar::all(i); + putText( image2, "OpenCV forever!", org, CV_FONT_HERSHEY_COMPLEX, 3, + Scalar(i, i, 255), 5, lineType ); - imshow( window_name, image2 ); - if( waitKey(DELAY) >= 0 ) - { return -1; } - } + imshow( window_name, image2 ); + if( waitKey(DELAY) >= 0 ) + { return -1; } + } return 0; } diff --git a/doc/tutorials/core/table_of_content_core/images/matMaskFilter2DOp.png b/doc/tutorials/core/table_of_content_core/images/matMaskFilter2DOp.png new file mode 100644 index 0000000000000000000000000000000000000000..679592160849fd1a3cacdb3a101d28f223cbd6ac GIT binary patch literal 9132 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 z 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 literal 0 HcmV?d00001 diff --git a/doc/tutorials/core/table_of_content_core/table_of_content_core.rst b/doc/tutorials/core/table_of_content_core/table_of_content_core.rst index 845fe6224f..92c0acdafc 100644 --- a/doc/tutorials/core/table_of_content_core/table_of_content_core.rst +++ b/doc/tutorials/core/table_of_content_core/table_of_content_core.rst @@ -46,6 +46,25 @@ Here you will learn the about the basic building blocks of the library. A must r :width: 90pt ++ + .. tabularcolumns:: m{100pt} m{300pt} + .. cssclass:: toctableopencv + + =============== ====================================================== + |HowFilterIm| **Title:** :ref:`maskOperationsFilter` + + *Compatibility:* > OpenCV 2.0 + + *Author:* |Author_BernatG| + + You'll find out how to scan images with neighbor access and use the :filtering:`filter2D ` function to apply kernel filters on images. + + =============== ====================================================== + + .. |HowFilterIm| image:: images/matMaskFilter2DOp.png + :height: 90pt + :width: 90pt + + .. tabularcolumns:: m{100pt} m{300pt} .. cssclass:: toctableopencv @@ -171,10 +190,10 @@ Here you will learn the about the basic building blocks of the library. A must r ../mat - the basic image container/mat - the basic image container ../how_to_scan_images/how_to_scan_images + ../mat-mask-operations/mat-mask-operations ../adding_images/adding_images ../basic_linear_transform/basic_linear_transform ../basic_geometric_drawing/basic_geometric_drawing ../random_generator_and_text/random_generator_and_text - ../mat-mask-operations/mat-mask-operations ../discrete_fourier_transform/discrete_fourier_transform ../file_input_output_with_xml_yml/file_input_output_with_xml_yml \ No newline at end of file diff --git a/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.rst b/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.rst index 379ce0cc80..ef8500880b 100644 --- a/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.rst +++ b/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.rst @@ -216,7 +216,7 @@ Code Explanation ============= -#. Let's check the OpenCV functions that involve only the smoothing procedure, since the rest is already known by now. +#. Let's check the OpenCV functions that involve only the smoothing procedure, since the rest is already known by now. #. **Normalized Block Filter:** diff --git a/samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp b/samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp index e9eee6ed54..628b974032 100644 --- a/samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp +++ b/samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp @@ -18,7 +18,7 @@ void help(char* progName) int main(int argc, char ** argv) { - help(argv[0]); + help(argv[0]); const char* filename = argc >=2 ? argv[1] : "lena.jpg"; diff --git a/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp b/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp new file mode 100644 index 0000000000..6b18f95f97 --- /dev/null +++ b/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp @@ -0,0 +1,86 @@ +#include +#include +#include +#include + +using namespace std; +using namespace cv; + +void help(char* progName) +{ + cout << endl + << "This program shows how to filter images with mask: the write it yourself and the" + << "filter2d way. " << endl + << "Usage:" << endl + << progName << " [image_name -- default lena.jpg] [G -- grayscale] " << endl << endl; +} + + +void Sharpen(const Mat& myImage,Mat& Result); + +int main( int argc, char* argv[]) +{ + help(argv[0]); + const char* filename = argc >=2 ? argv[1] : "lena.jpg"; + + Mat I, J, K; + + if (argc >= 3 && !strcmp("G", argv[2])) + I = imread( filename, CV_LOAD_IMAGE_GRAYSCALE); + else + I = imread( filename, CV_LOAD_IMAGE_COLOR); + + namedWindow("Input", CV_WINDOW_AUTOSIZE); + namedWindow("Output", CV_WINDOW_AUTOSIZE); + + imshow("Input", I); + double t = (double)getTickCount(); + + Sharpen(I, J); + + t = ((double)getTickCount() - t)/getTickFrequency(); + cout << "Hand written function times passed in seconds: " << t << endl; + + imshow("Output", J); + cvWaitKey(0); + + Mat kern = (Mat_(3,3) << 0, -1, 0, + -1, 5, -1, + 0, -1, 0); + t = (double)getTickCount(); + filter2D(I, K, I.depth(), kern ); + t = ((double)getTickCount() - t)/getTickFrequency(); + cout << "Built-in filter2D time passed in seconds: " << t << endl; + + imshow("Output", K); + + cvWaitKey(0); + return 0; +} +void Sharpen(const Mat& myImage,Mat& Result) +{ + CV_Assert(myImage.depth() == CV_8U); // accept only uchar images + + const int nChannels = myImage.channels(); + Result.create(myImage.size(),myImage.type()); + + for(int j = 1 ; j < myImage.rows-1; ++j) + { + const uchar* previous = myImage.ptr(j - 1); + const uchar* current = myImage.ptr(j ); + const uchar* next = myImage.ptr(j + 1); + + uchar* output = Result.ptr(j); + + for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i) + { + *output++ = saturate_cast(5*current[i] + -current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]); + } + } + + Result.row(0).setTo(Scalar(0)); + Result.row(Result.rows-1).setTo(Scalar(0)); + Result.col(0).setTo(Scalar(0)); + Result.col(Result.cols-1).setTo(Scalar(0)); +} \ No newline at end of file