From 7e3490959a6055f248d3e0a060bb4bd6e3ad784d Mon Sep 17 00:00:00 2001 From: catree Date: Wed, 16 May 2018 14:05:39 +0200 Subject: [PATCH] Add Java and Python code for morphology tutorials. --- .../erosion_dilatation.markdown | 46 +++--- ...phology_1_Tutorial_Theory_Dilatation_2.png | Bin 1558 -> 0 bytes .../Morphology_1_Tutorial_Theory_Dilation.png | Bin 410 -> 923 bytes .../Morphology_1_Tutorial_Theory_Erosion.png | Bin 457 -> 844 bytes ...Morphology_1_Tutorial_Theory_Erosion_2.png | Bin 1533 -> 0 bytes ...ology_1_Tutorial_Theory_Original_Image.png | Bin 458 -> 1126 bytes .../Morphology_2_Tutorial_Theory_BlackHat.png | Bin 685 -> 1146 bytes .../Morphology_2_Tutorial_Theory_Closing.png | Bin 558 -> 2205 bytes ...Morphology_2_Tutorial_Theory_Closing_2.png | Bin 1383 -> 0 bytes .../Morphology_2_Tutorial_Theory_Gradient.png | Bin 5632 -> 1995 bytes .../Morphology_2_Tutorial_Theory_Opening.png | Bin 608 -> 2082 bytes ...Morphology_2_Tutorial_Theory_Opening_2.png | Bin 1341 -> 0 bytes .../Morphology_2_Tutorial_Theory_TopHat.png | Bin 617 -> 1531 bytes .../opening_closing_hats.markdown | 33 ++-- .../tutorial_code/ImgProc/Morphology_1.cpp | 2 +- .../tutorial_code/ImgProc/Morphology_2.cpp | 2 +- .../ImgProc/Smoothing/Smoothing.cpp | 70 ++++++-- .../erosion_dilatation/MorphologyDemo1.java | 155 ++++++++++++++++++ .../opening_closing_hats/MorphologyDemo2.java | 153 +++++++++++++++++ .../erosion_dilatation/morphology_1.py | 63 +++++++ .../opening_closing_hats/morphology_2.py | 48 ++++++ 21 files changed, 517 insertions(+), 55 deletions(-) delete mode 100644 doc/tutorials/imgproc/erosion_dilatation/images/Morphology_1_Tutorial_Theory_Dilatation_2.png delete mode 100644 doc/tutorials/imgproc/erosion_dilatation/images/Morphology_1_Tutorial_Theory_Erosion_2.png delete mode 100644 doc/tutorials/imgproc/opening_closing_hats/images/Morphology_2_Tutorial_Theory_Closing_2.png delete mode 100644 doc/tutorials/imgproc/opening_closing_hats/images/Morphology_2_Tutorial_Theory_Opening_2.png create mode 100644 samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java create mode 100644 samples/java/tutorial_code/ImgProc/opening_closing_hats/MorphologyDemo2.java create mode 100644 samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py create mode 100644 samples/python/tutorial_code/imgProc/opening_closing_hats/morphology_2.py diff --git a/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown b/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown index 515e6b26cb..8afcd2dea8 100644 --- a/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown +++ b/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown @@ -11,9 +11,6 @@ In this tutorial you will learn how to: - @ref cv::erode - @ref cv::dilate -Interesting fact ------------ - @note The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler. Morphological Operations @@ -38,19 +35,14 @@ Morphological Operations - As the kernel \f$B\f$ is scanned over the image, we compute the maximal pixel value overlapped by \f$B\f$ and replace the image pixel in the anchor point position with that maximal value. As you can deduce, this maximizing operation causes bright regions within an image to "grow" (therefore the - name *dilation*). Take the above image as an example. Applying dilation we can get: + name *dilation*). +- The dilatation operation is: \f$\texttt{dst} (x,y) = \max _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f$ + +- Take the above image as an example. Applying dilation we can get: ![](images/Morphology_1_Tutorial_Theory_Dilation.png) -The background (bright) dilates around the black regions of the letter. - -To better grasp the idea and avoid possible confusion, in this other example we have inverted the original -image such as the object in white is now the letter. We have performed two dilatations with a rectangular -structuring element of size `3x3`. - -![Left image: original image inverted, right image: resulting dilatation](images/Morphology_1_Tutorial_Theory_Dilatation_2.png) - -The dilatation makes the object in white bigger. +- The bright area of the letter dilates around the black regions of the background. ### Erosion @@ -58,31 +50,39 @@ The dilatation makes the object in white bigger. area of given kernel. - As the kernel \f$B\f$ is scanned over the image, we compute the minimal pixel value overlapped by \f$B\f$ and replace the image pixel under the anchor point with that minimal value. +- The erosion operation is: \f$\texttt{dst} (x,y) = \min _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f$ - Analagously to the example for dilation, we can apply the erosion operator to the original image - (shown above). You can see in the result below that the bright areas of the image (the - background, apparently), get thinner, whereas the dark zones (the "writing") gets bigger. + (shown above). You can see in the result below that the bright areas of the image get thinner, + whereas the dark zones gets bigger. ![](images/Morphology_1_Tutorial_Theory_Erosion.png) -In similar manner, the corresponding image results by applying erosion operation on the inverted original image (two erosions -with a rectangular structuring element of size `3x3`): - -![Left image: original image inverted, right image: resulting erosion](images/Morphology_1_Tutorial_Theory_Erosion_2.png) - -The erosion makes the object in white smaller. - Code ---- +@add_toggle_cpp This tutorial's code is shown below. You can also download it [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp) @include samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp +@end_toggle + +@add_toggle_java +This tutorial's code is shown below. You can also download it +[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java) +@include samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java +@end_toggle + +@add_toggle_python +This tutorial's code is shown below. You can also download it +[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py) +@include samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py +@end_toggle Explanation ----------- -# Most of the material shown here is trivial (if you have any doubt, please refer to the tutorials in - previous sections). Let's check the general structure of the program: + previous sections). Let's check the general structure of the C++ program: - Load an image (can be BGR or grayscale) - Create two windows (one for dilation output, the other for erosion) diff --git a/doc/tutorials/imgproc/erosion_dilatation/images/Morphology_1_Tutorial_Theory_Dilatation_2.png b/doc/tutorials/imgproc/erosion_dilatation/images/Morphology_1_Tutorial_Theory_Dilatation_2.png deleted file mode 100644 index bdca7c62339475cb30ee30ed690759dd1e54835c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1558 zcmV+x2I={UP)WFU8GbZ8()Nlj2>E@cM*00nwUL_t(|+U?!Ta@#r( zMNw0Q|NmuWlu1%DC6NI7vG&;4(ZxC3Xg*9GKR-XuAEf2^tR3HR970aa!x8`>7ytwV z00aYoU;yN0SOOq7XLk~J-iad^ppZ;n{WrTLLogS@^^69h%VoD@2k11|Dj z+$pL*NsIi`3&8-GE|(pWA{Y}18uf8?zX|4s#U~|zV5UlfWB`HzKrjFZ1^@_VJ|4IO z2nGPb0H`o&6O2PH#%O{8g7eO_5_QTp!2rqS^2yJcV1k9|`U^7kH(Fm!Fef{J zH`O8f^b#3@X%aL*Fa!dW>LkGcFwz1JD>H{=W-1Oz-1A>`nh3&Vt-cC6?S#uj$_9J6I_I@AKCOWf5!ILU?NNi zB!a5)dsr-=5%Qk(*;-F9JEs?7L8PwE>SI~KblWMQlMz3Y=U{>d>Mjy8zZ+?EJ%}^h z@*@{ypQKDMLBk{$J;?MqJjuJ^;3XGC>gsB_l$>C)?-b->ddc+fpY_!#QjkE21$TF1 zw%FeJe52ceJ@Y^|wIIUuvf|%-x3eag&4H2&DvG6?V0KI|#Dd)ia`f+mH^C4K5>6DW zPrbhFZ5zQvxL`&u1uLmGr^Dx$Yf7vhj2*+{iL$0w?n9;f<97N-QOWpVnGkF z?C9=Wxg6wjs z)ZvjK%)bln8xc`SE*&<*5jD(z7eC^csexF?WuaiM21*d9LHhPTOpVzUob{4SRofT8x{&?m0X00N~bg3Hp8z3^XWnV?V`GKgk2la zj5qst?CK-i4gl=xtZ90|1oO!vUy+M2vAQcWUk=}Oqn+|3@2W33GabRCUFZ~P#WfLf zK{UCTrh`l{4ti9ZT6|^j!U-nIxipa>%R%40t6>B~E|}SyZ#v}EsMrKUF32n{eZ3%< zvjulc8dc;$E&(T)Z$lv$m|O^EN;s{6frW)k9n#kYg1KX%kK+&)QXTmE`aa{%1@{-xh$5L;57FuF2EkZ-RF{ly z2M`Pp@pLK5w~rDGP*^lr&%+V`AQ%7y0{{dAfM5U+3;_JcA3*B%y~mug)Bpeg07*qo IM6N<$g5j*1WB>pF diff --git a/doc/tutorials/imgproc/erosion_dilatation/images/Morphology_1_Tutorial_Theory_Dilation.png b/doc/tutorials/imgproc/erosion_dilatation/images/Morphology_1_Tutorial_Theory_Dilation.png index dae930ec1ecf1781a157bc188fe828a7dbf0a1bd..4f0df79ed9ee88b48da9d8de8d6f23328ad067c1 100644 GIT binary patch literal 923 zcmZvbZ%h++7{^PPEq7f({r)t2GFhRB%A7o=u>1_^^Bf;9`}wK%liysbx1PS( zdFN7c6b&qcKi1~Eo&^7mHf)#emdkj{32-VS?b)m!iFuae$BKxUtoVh3?g;bs%E|8t# z;!D3;5qt}TY+~zXEgTCiQ*53y@}@1|%}A{S^_9i+U9Bb-O2*AA*6)Qxo_oI#P>bJ2 zP354ci7U(EbCPPHW*_*%0qNZB{geSgwZzpKdV*ILJjmf@&|jjf-S*dF#m(AF;Hw}s z?Dn0b+7Q$4f*vug2^eCU5)LC~uV6&XTY?HPKO%1P=-FbV#DwYhV%Qi|=uwlQ$0lm> zZFb((j@AKsKUF60h24RXLVCCU4U@a@9>nr6>P-`#PSQEV9_7*b1;dg!XcKLB;s@_g zlQV3jL`Q6rQsT{u8-ExzIeB!gh;A&{uY=jU5Qg9v336Iu!>qPIel99}^3s0*khZ|7 zaZWQ(-L=>>Op-4xNi%*-zoy*bf9b!uO;>UnXE56R!qg{e;#i;~YVrBvN&tHzVH5 zS+Scn@5<&O`c@FquN`h?k<(w#i8HQ_=iq}`i_UF&#^Eb^L*Vj|wtK<9MCoIm9|d>? zH=d5?nZ^6W3(`AlJzI1>a>vxH|hu`wa6@Uxjh{ii3NU!+HFd zqO(!-X2c`gwa<(GjHuqO?NunLCm_G9+-2niq>&poz~xoy)-J5cdQTE$TKIC5NrmZD zm}`~mV7aCeTx*F>w#3UfEg|0WmqJY8QN_l67p@i(3S8~W(y_ z)h$=chJ)gHaj?WyF+_<8F?|=fYfRS#=2s@t#Dv)SFk8hP`fu!LX5*`=@mFUe|9lJ2b7S?;6wXpR)naIe&(26K&Wg$x^qRV2%A6%xOvNDW2$`z3rggpv93AZdfgV|3)59n!dOU!PC`89#)7MRsC(DIWLm>z|| zD_!a3h!sEQO}Q)A2V7Z|`-tJei!wa<4?vGkMgX3LwTyBAED&BOBmhC!5_JXCEZoW< zfQhSvp9XJ0jei^=EEDy7eRK=N#VireW*nheB%1xfpqmxqVi839n}}|WxrLUAOBNcK zJ;KXiOK=RA;ITI0k qWLizkvlZrIVAe_4q7Zm@{s+SUm}B&I0fPVl002ovP6b4+LSTX_Evmo( diff --git a/doc/tutorials/imgproc/erosion_dilatation/images/Morphology_1_Tutorial_Theory_Erosion.png b/doc/tutorials/imgproc/erosion_dilatation/images/Morphology_1_Tutorial_Theory_Erosion.png index 755561023f399c6524be7a2e498541f0ba40ea06..18e997013703909d6531ecf629e4127f3ab24a19 100644 GIT binary patch literal 844 zcmZuwTS!xJ9A0$MZn|^qZ0nB4PPz-if=Vzo%Tv0VdR%jMQR`1xbg}keTV)qq)c)rz zg_<@fQp>jGqBu$ywi!kLBSb+j8iVlV9~7(`=V4++(y@qMdicKY_q}}ZyTR(p&GY9h znxj&w=2w)L)hK#QL07s$s+=yHqSLb~%1XDnrwu)u3;N4dGoB`YERQ;F$=|Y9O*h${ z0|nc!n<_QA!WHQS-uuU9)HuYI?c7?C{!JO2OR1_e<@zN(lkh86rK(!BY2mXtR#e*x8>IG5Ql9**g#!jbzr>h0)8AOAU-y-8|Hsh@*EUZ5{XwM;&* z(=6_MY%u3P)XTTf<3t~_LZ`^W82Ju(NEho9PB3REbAGVXodKrAY6fP8l&7cA0*CEUrfn&P=nm-oym;zF4m+M9dW%F zM$K|Rx=H?!BK$sPT+lL_&Vu#vJh2ZEcsnuIvP4-*T@6;tcTpRiLACuYMJ(|`<8V^XOG*4d%ZbQ>?C!O&rF%xsqSQUyJkz$Fq!th1OHUA X^KSg=fe**sQ*TniR+in{u)FOS`w4ej delta 443 zcmV;s0Yv`H2FU}E7=Hl+0000yGoF_K000J1OjJbx00960|E1ZV-2eaqen~_@RCr#+ z)WL1$AP@!MhdB7QYzOWnY$>TEP#UFB0!I!AFQZt@y#HWjSBf&XPlf?TPsT;{9UPvR z9T9loWDX!PXP%2unXbOs<*7=kSGG+}==6)4(BYKQ0K~Rggq4|0*4`hpqc!$7?n~BNX(1qlylK5_2z-2h#Em!>j{{k}hJ5L^+6Gi|4002ovPDHLkV1lOF#CiY# diff --git a/doc/tutorials/imgproc/erosion_dilatation/images/Morphology_1_Tutorial_Theory_Erosion_2.png b/doc/tutorials/imgproc/erosion_dilatation/images/Morphology_1_Tutorial_Theory_Erosion_2.png deleted file mode 100644 index 5e666eef3614ce093e5dd178bd4d07284fcf3d90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1533 zcmVWFU8GbZ8()Nlj2>E@cM*00m)5L_t(|+U?!jZrd;r zMbSv$|NpZ46rfGxM3#A(8Ls_U1gXI}-aM2P`}p|yczhr&k4NqC9miqFi8(C+0D=KP zFaSU>00;&E!2kfk0GLO!1lRfc%!y|-0D|cvlV?9eGJqpece&j8SwMpUkbX0a(yTQY zjRXa=8YRaB(_tv21Q5(nNstUQZGr)|kxK*#5e%TY5Db8P5KJdLa0d_!U?U?K02O3J zFpfBoXM!)FyJ3D+~M3-FysPxC72My@+=I6Kyk5yYB9K`^uAVwi}~v`6Q#O4Dwc7K2={I=|rhTp&+HoA@0%$Nbb_Um9pm8N_FaSU>g?9?npxQ@kp1TbV z0KsT40Kovzw4c)qE%s~GuC!_m2E#PyySur`N$xavVw^+G;%?vxsQ5^+z}~=T!;nL?s7i+KWF5z z8QPrRO)i+7iIrk0BbX6#>HRy&1rgp4D{{ES5$UIe9oc?}1yP#zsw}o$1~&8TODu@c zv?JuO87{e?PKKl9uT@>>C`T}0M$?X(!B%B3q=Fqc%jh|56&IaYP&LQd^4BU4gIGW& z8wcZRyJOB;mf;WyGPjjov)3{V$1o95D$jD}d#@%4X4N8-3r6Pl zPQG@|WLq($y92T_V1-z0T7d*J>f;R}ewiAG1rr71Dm${vrFRB*&vY9#sGdV`G{R`P z^b$daFS1W1m?(doWtdnk7jza(lrI<)5JV7*_VPbxbh$VlL2KEp!MysWzdKBKjzBIO zACVkikV!7HzBX9q-#8+@(q7(KXh$QEiv}~KwPgMLQN%<}k~EkZ*F?w#y<0_vmbA?g z$(tS^mnDLkwd)urR<{>&NhTO_!3gAqV1xx4((Zy8`8AaWhOBb2=}l@dcO^kCaQq^e zA+nhD&>qk`-}1OXFyw-0&7xOBCYQm2xw@#o4fOGNkPA{thFtE`ULD$%VU7A+Ucj-a z_z`K=A{!=FwwSL?TOKDgm=(bQ-p$gdD58A4s|K@h!3`6UG9`}-1T$*k4HHo$a~y{} zu0A4Nz359Wh$NY3nU%p{g6Sa{Lq(<|6DAAh%FbZG0KwQ90CeTF1ONyI0KotN!2lo_ j00aX71OtFz02JU4O40(pVDRtD00000NkvXXu0mjfQaX&Y diff --git a/doc/tutorials/imgproc/erosion_dilatation/images/Morphology_1_Tutorial_Theory_Original_Image.png b/doc/tutorials/imgproc/erosion_dilatation/images/Morphology_1_Tutorial_Theory_Original_Image.png index d7e8a9a429e495272eacfffeeee36078e8e93146..969294c7c66af482e1dce5c0a42be9c747f6b124 100644 GIT binary patch delta 1117 zcmV-j1fu)O1Lg>j7=H)`00006{S4Fq000DYLP=Bz2nYy#2xN!=00bRLL_t(|obBDw za@#NrMA22J|NqPGi#?;HvMrJTfd%$HXHt(&K~b{o8~`3rwEc;G0ctG)k|#j&1W29$ z$rB)X0wnKm^b26>@%VYkd>lv6D>=Oe=tBOo-&pU8M${5|(SKdM(Vz85faD4ASJ4wS zngCDD;zgnh@YyOt6ruph6Cim4Bu{`wMP1MfkURmBC%|XX_cUh{ph1!N0$eP5as_y5 z6eAiB(EEX3dv}X010J9W{Mr>%7Cb-`NS`K?6mS$T^R-}0z)H0Ptg>{zY6Vyg z4`>Ehu{MAerw?cXSQQUw0=QDQy1A5^xMfqrbrAH!G zqnkkC{fuS;XEqhp@c;tA+1=nLyegLvKvKZfEj$yzYU$2_!W%2a1a`XlY+Wdz;MUs; z=y7{$6p!T=+1*S5cOD$CsbiaFGr(PVYzNpolU=Cr;!3d#{glu?mln_iuG$6$NC+4? zag5U*4u8ma&@yGRiJ3t-jzf3`nN47JjEd(!AmPnyHI@LMWnV$w)dH~U@(DBn{1)r< z0Rp5i{5sG(rsZ?y8-q20Nt*q};P!wS&VMVbL}@^V<#Y8lmOlr6DsuX){&SU`z|7NU z`P#|?X3hGu9VM60I|pg^^6B;2j*@_x^7w4Wxqp^R=&tGW#sdlhX4$;#zyq{|y0r7N zjHLjhH!r)U?p!Irs8*Kk)&Eds03)U^67E$Qz@24)d({ST^}t!|ZavPwB>+7y9kPE2 zl^)Oo&-!CVo1NSNgV0JVhAKa@F-_+z$R4d!m<6X^B!OZ4+DSxfbGlN|w8GXeC5%dmsZ+A?6oqjWod zA4^MsS^gMDS3F>07rF~i%jf5&CUDo^FMra`^Ly^^$ag=$-VFop`kQ@PI`8FjD{a?9 zw3_b03EXi`65d#*=Rh6Q{iS-WP}4VF8bIOAl?L!m!u!A5fS!N0RF@3%nN8p_=6Tnw`M`3@afNFm!FC*0b1W29$$rB)X j0whm>D3Y?4c;;`(j zskmoThPXw4rGNVu`-799IY=+I@Ep8mVb3heiPIc}%_Nn$Sdu_mBn`-$84k6{@8A`I zu-F0e#dUOQbwF4w0O?8dS6D%d6^OD3cv+l4*c|XfvEypoY(&jME{ZrQY4IdT$%~UH zY!32?D2ir3WNLaD$7T!Conm}v^M*B8#?6|fXhuOZoHZoPN#1O}Bbyx##R1OJD^3WC mCqzYoq*)Nn<_$$Yo__%B$?YMewV=KL0000tql=cqDmWCqb(v@B)rCTtA37gfMk_mz-3ySQ8 zkv43+Z0+r!t9FpaDlAsgT|uof(n2 ze|}c`?%r|0H!6!n^Q2mS)cm#ogeGB+{{U{VUe7P7t~I8F);*DQarql#ez7T7W*QI zQPRS~smG8>+Q@Y->vV_l_t9*wvqL?+ND8fzT1@PPYlBl&Tz*0=urF=SE|RPC#JU4h z344Q6J%WdzSYW^UmUNXE56ku|z~O+)M%A^Er2_jE3tpLMYV*`7K%-T(3f{Ih7YAI2 zxKYy#oWaOi<2?6(U9Cm>11|5`MNf6?#dhA-e3wJcE&|yad4LiYl0)0aOPj;m%+d{S z$XOk?D1xt3LLsLc12#qmO_VID+KX`f`s(KrM3 z$5m8=0{BpQpR_tDxc%{$sQP(u6_q}c{e&SIPK~BH=v#!Rw3$Mnb=#uKR=ZlsoExd~ z*aGBISTx6rn%;9_)AX3XRJ0m=d7e;(*vO8kX_xcN1YM(P&tq*-MXQ}(NPgefWR(d4?LaUrJ{q*21@AU7p)Pyqx~_CrEY z8ZqawB}B;zV^V+$tHCUWtp*#09D*wCJAE+U2TygBKXrMSjyx8d2XDki{dya16w9o586ZDIT{oTwRTa>b(s`ys%?uLRymlxhq9at>H7_NC5h}aH=fIL}s;tO)6DEcO zWVe1n`hkVP@)%^Kqrng$edxABT?g`5Ie8$D5lsLoD@y~#CV<5ZYx2riNy1W*JL76W z`eS<%ZB%BV`zF#9n>m5DL)~$fC|5FFo*}EKsO5iI@OL<@*B;US=}o`)QG6>@@cm}} I0`}_2UvtFf%m4rY literal 685 zcmV;e0#f~nP)w7>aM=&AlMSs?ZIr6-Y(MliCtWu%FCD>bkLvf^3dZ=}9W;EzfT zZxYbb5=&S{Fthk!WEK|q{7+8%n@F(YMPfDLL{ihT9%U-YMuw7Nq4peG+2Uv@SpbB$L_#G1eoG{(EceRt zQ_`VE@|H{kd>3&ff<_`y+ucA3K^7TCh*-|DLX}v;v*43ND_@ngEgbr;q#40i4!y%I z%OBEispp=IRFPn0!6o^S#4^M2z`EpA)Y9E0H zacWtRuVhVtG*~dv0AeX!Bon$z`~XKyq!0v_K$WGH3GtSG4pf4WE(slIiqv!LmOxzz zfZGZFPJ|-o+AZfR3m%ehDMVA`iUqCvldjSTe2e8nDhnRMX(ZBVJmHdfI?FtJ-I9r_ z2m-_{CyO+A+2U!wDygm~zJYNmfxr^UO_2o!x1^zE0%5)-qZ=Z_Q!BTW>Xq~$a?TXN zNc9%CtmK0)@e?A7w6ffm0jd33I%Ff$-x3a~N@#>F2nDosC1fSCxTU4E#B==Al55^F z!ccrcxMYU77l T+9HUD00000NkvXXu0mjfFYhqH diff --git a/doc/tutorials/imgproc/opening_closing_hats/images/Morphology_2_Tutorial_Theory_Closing.png b/doc/tutorials/imgproc/opening_closing_hats/images/Morphology_2_Tutorial_Theory_Closing.png index f112bfef115e9f5cb1ebaa2df2ae52c2cc8902db..a034ac249695a99b00b8f4c2e708b6c8a7f3f9aa 100644 GIT binary patch literal 2205 zcmYLLeN+=y77tQICBRIwAh3XtV5st8Ccz?Kf)WhKh*kwsO9dw;n$^|KB8M*#S=;zV z6!B2QWJOVIX%!ZCkXCG^VttC39MDFOc%+JB8v$KE7FMx>>>J$E{bT0d`OVCo`+o1< z-yM2oy4r1~?@WO};Fg-AT7_&sI?U72Nx;S5eIO7_-;kMNt?9T=0edsC-wi% z6#Z#FP;c!ZUJYK`7Kd?_@qErQeAu%4yK7TQsLc&4NQqv#A5j7JTbu}*v9`W_{?+{n zoM(bj*>r0!jNUGLE9TeSfGaKC)~MO{CEw~yFp`ofgWov;O34Shr3mrLTT@f?wKYya zrRhmh>X4^~aS>idm&wauz1$_=GVI9vx-o25Z&kEZCVHh*vmn-@+R|Ao7SrEbzG!ZV zlHqrWS%8M^q?$4H?med>gP(4QnNkh@!KA@8+#*N+uaBSIlXL`AQip^%)V3$}URm*k z2fIS6BHj%6gqBu=F8Bw&LjD;dss{O%po5Hxl*!~t_3K{_DatOLvQ=&3k#*WDD(jQW zlAXEnda{+2$i!zY?R+H}sh30ZN-nLnF$)omWcEh)A;m-qUJwas16aVg@}>($+h-jZQ&qf zqEA`lu1mWus<7M$(W7?{z3*jItFv=`DW|;hHng_wl+Eu}hSw%gK}yW>jWAh;7hqa_ zVzy4ie(Hl|SyX+CYl#qU+HGBcfCZ?h7=+mL6kf24FS-Kkj0IIkV8D-&&>wD*;Rn`> zj2=Xd0ql{x@lGn#qBoLlI?)Sn6dRR=sc`=tv6Y!LG}HC`Qr7*l8JwphC5-arjUR0h z=8V0mn2n#7(;67edCG7#b#&Ws$DV{|67B;#mbT+ftjKuS0Hnm~z7MlL!lHPBp3rlC z8249mGCO+Q+>_z85IgIQdX)|F8YTNv`lxhxkhvTQ-SnrMTLfSZnben?u97%Vo<|1p zG{)4{JpxS3rAW9SVdBmY)8M#}1sBE~4`UiHsq6D{G3dBR#qR zZ@f|Nf8#e{Ic_}IRvpbt&cQns$$dm%CKW^VWCu56uLyPip?2a3+R%6^TtCxzsO^9y zvFQpK*eouPZ$umm!7XM6Tu%8aQS;``_cC_U8rq^dzm&}FhLWefjg4W~MUUlnaGSo( z9IrWjp~MxXXM*!=Dr%-}y>1smUs&rK4kv80qO@MO zmYP9qaOaDAfIw=4z<3TuLJ8HucS+)i_s~4oz|0NBssjd)tg4H~OVI~6q^s%-K&Pr3 z1WtA=RN+sc{_?q@jiEYPVKJ!|GG@)v5e7AWpb35bY9y>O(4RpX^{)$cwH59qlY|zt zW?3yC9pH9RsDkz;!r9M}ICv|PmVYzd+~$*kaDwz9#HOoRaZE1 zcAje_l#wSK?_b9@BW7OwJ7MhCaDUb<&!XAyEiXyf@t^UU5t`TLVpvsP_jc4iaYD`O zd8kNgn!R)Q?EGl_V}+JlPT7R~h+!j)-K|iH=sWViLHPSbv~+=C)1LV^HBM?G0?iLAc5w3d+5L5f^aj zBC`34&HO|eX(^D9!0qEWuSTAUg5|A$P_id|W0;$fmRLqILLxmHsUj^HL1ZCc@RvzV zUh2BBv}lAfOW%x)qH6sI@4>Sxp9Owc2_j@$a26WXd>gaLL%Kt z6=}f}f)OYQR+1yrl>^C1FqHJDrDJ1RM%r5?&syl6lBK1(f)D$>9C&hMpgYonCx|RR zjZ7q#uSPmHmTIITw-@O~DzI99c?4R3zyd83NFu>X=GI2GvP6oJ_>jV(b%HGN{Zbtf z2A1l}`h9^b;Q{?3G7ehtgl;8DWvmmIDCJ>&u&< z_VFf`dOhrv2_P*#EG(8G!4`mBqyb4JE)jyvFuc)H(M3KgnTTzdGAEG(nZL@ixr w^l_CS60{7Yb${BSy3NXx(2GpA|9=v{0JsNk0eEGzH2?qr07*qoM6N<$f+UFe8UO$Q diff --git a/doc/tutorials/imgproc/opening_closing_hats/images/Morphology_2_Tutorial_Theory_Closing_2.png b/doc/tutorials/imgproc/opening_closing_hats/images/Morphology_2_Tutorial_Theory_Closing_2.png deleted file mode 100644 index 57b790583f42933202d593d58ebb49521bd529fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1383 zcmYjRX;4#F6nNC|z~7weDCJ@?*o@7caHbIv&tyDi+- z#@z-009!!>Z#w{3xuSdxXpNru&@<)eWt|ii&I8_Cmb$aC3jHBwMeNB2020Nrt$;d} z#fBggMDq#bHbiH)4Gno6s0>(^zGJs6^gu>NYNiZ*0zjxVHBpwDLeEK;eNGP-M8~GE zQV9Tndnn)q?~woYYHTdCf$hXkJo(SN8!FAxQ{QbH_Ijd%4vSxffw{uFj#eFCS(s*5akC6Lv$wPMvUt~D@lJEU;ze`FtFZ5Dj+qy+%&wfnX?sI8U7cMnLM_SS;SQE?YG z5;fim7Kqd^SN}CTCS>7-@2>_-RVgt|5Np6l{j}9&a_>kSg$#T!Ho80(znkcYIVs8u zHYn=EmBmwnLv$C&ffdBYVPt=LTQExq7XNl=ycI4eR|pPvvi}Pn7Nd^h#!Og!K-M#A zH8dFiQAZa(f~xp+262hjLEe$19uo%fa-GN*ftU8nS;i19ak9zSi)EsrJWN$$X_0@A z+&s&qm6No0R=N}c8vFhX6fOO>sKqopYxmm@{-WT$ z_SWJ8a|`L%B`|V<7Zj0){`a&I8dvDsZ}Ya zjnJ!at8$9iJ@y`5ks;iIX!g(dvXG(_6Xy>c7QiLnutgKqdvA)e6ru5gMp4+0e6>~yQZOgfUvQ&H%zOD!tV_^?JpByKcveD43NBXE zoE0;c-!(uiL{{N1mv7~VOezMhm$oh5oy*LS%}hDv^dGDe#h!UY-a1Waxq>&RL&Q(sR+3iFXCMAdchxQ}Nn3V3<#i+R_--}) z&^#K(hFQ;?C3I=9ftb$cHg=EAcJy^?Uo^v?%3tPrYs#Y@D{ekvAZ^Ed23a~NVt8N~ zqDttxOr`ZQLb;tTCqzRfV~EgS%M0`=w=r?fiy7Rx(j97;h^HV2D|I2O&9y?d+qt-? zHQ!!<`*6uRT=U55DJS>ZAnq`U8Ir}rAZwV)&5)<#wB(@n*`YAH%d~_xK%O||SAxBG zGnA>Uzqh!$x@7HDj7GU{gU#fy5yYS+G|HlO1I_E5h1I(bDHY#eg`Xd37qH`~b!Z#- z1vC^(?(owzPZ$~Co3Zg+X<;wo)l@_|i4Vh@I7;!pfX%s%=b9Yi=Z}k^%!+uz{L{)+ zAS1@tyzo1&RbK~c#Hl$Z&fnC&3z%DccE{U6p7qC4X4-WXD5%c;oPxy&cQ+;(5pL4n zSqd44c8YMV8_E9s^WTU}*#+W4f>gT~T6o3SN}Bvj4%(e*fP=FG%JdhH{xq=Vic#b# zZ^xQzb4v|JXqUab5Hb^O6rCyiia1bBNWiP%dZz0ji|^kzJvHh3=roBH$fH7v=X9kH z_4${H4tv&_7u;qa*dNt9Rjh1)1$a+a+0%82!&Kt`hYk*VObnoe8@IdhZm52Li*~(b N-U;~Ic-KS3(7%}ZOS}L8 diff --git a/doc/tutorials/imgproc/opening_closing_hats/images/Morphology_2_Tutorial_Theory_Gradient.png b/doc/tutorials/imgproc/opening_closing_hats/images/Morphology_2_Tutorial_Theory_Gradient.png index 5d8077f0d29267558ce62ff422f456812f0b8a5b..44590016a050eb504f4d0623e7062ffc45861ed0 100644 GIT binary patch literal 1995 zcmY*aZ%h+u8fPyW5UsR8+dJTNTd`;@aAs55JyEYMrFPwx(lRYn{+#{5CbNLo7@&bF zx44#RC#;v_Zr3dc1yQFn7HqKEl(L)4P2(r^gENtEqId6p*reeg^MR$=?a96M?mk?a z>Ad;PZ=Uz}KF{xY#&0njc!gz!d3kv}JaGDN|H#YB|D&-%)8ct= z{V)3mfb(a2e#O2OcU=D0dj~$FqqE;9&v8#uhs7i9S@*leE)v5orA92hsX=fhkVz)Q zZ?MM%o{8rcgT!R!!4UsHi~GUUyo_@uHNCWfRfv@SuRtv)qK-1X(C!<_Md)EzK^Vt5&dsTVit zDwa25*3`qc7x8;A?~ov5!FpOblLL$lC$^=RJ5z@rJsX`PWr56f~mYJ`h=CAS(MHC zGHp``m5B%U>az+niDw=LQx-^^N(721y+sGXFw6!7;qqB7F)$ywmzq^vn-Xv1aZBpi zI`EpSOp(4-$rt1)m;*mv z2D!v$Dxa-fK(SwfP(nOoTZ+qFH`I3z(N7o!L{Ec143*AUaY8~!e!z~To4p@ZYk3-8 z)KFm&hxOib)moF*S!gr2GE}OHVc(_wHyN09s44I=?T?3%3VRoQf5Ama z82+i0W82!pN)J+oD1qN(`6zY^;6q0@b5Nv}H7Noi-|F#0>KRT1TA=DacWVU1f0Ry#p}OVN#aN&u-C2)Jz-Xc|R{Hj{GFX+z zYSIo(%14WrQ_V4KB$V@9W5iW#c*hup#!mz!2T3G5?^EA~N|JWfNm>&N9A*?>P)0)1 zNsj*m=%Q;`dG~fpQfC_dQ7VE!YKzgQ?|7~`Y0Hiawr@k${7-%r+jyW~D2@r5Qnk!M zw{_ibp@LCHA4k`KglaV+4|Hin#0-G(2~U7ukUw;+b@&EJd(Fgr@~67jreS!gMoX ztPmBUCl*lQmX!+iStl$LYQ-ko*uzL)-w|on8%)}#;6dD09)%VCD!8{_pvyTSzDiE6 zl1TFW(@|$?zI)cEhFu}wWaO`5?P^@sB^X9hmqYYPqe%;ul?3(}dS5D1?pNX;fV(0tR0DcpgZYuCaPvRK!?13+XGTg$YM@s{-_xdQVD6xQ zg6)9e!Rx`)hi)4lw^5$kWpJ{PZE&aK3#eca?nL-36E|4}VVn{=VuA5QKt)QJN?8mB ze*wrEKrVn=aHsvy>i9cgZUIEl;-ERNJu^PB<(wRC6ZO?OqgdBKN&%{|%xI4w%Ub*|+g)-D{uIjDskxLq~=cJxWJ=fRnFTeWlRo!Q=u4?SR zr2m8bZ!4lunKN}p9uqSFXX4E9i~j2u$-UrTc~F$RRnMLH>?Q!w%en>6FDe{F{RdOX zYb9ThjsD&AKL~Nu^f@fD!|^ir1>PKp*1(Zph&eM5bNpHs2vj2v1n_}h761qad4!m= z0A4_|lKd5bol=>NRHY~fhl_x<)N7PqNrS_R>CrtZpEKmU!b7qS#%!v$dMw3L+Xqjc z65V@7GqRnuchBz%4l!rJo$?F--}GAWdv%Vyr1f9joieRCXUfU#+6}u>w7?K&A-dt2 zv|<7I{<{_-B0r^`-kqn1MfKm+@k^WSPvIA_XzYk61Ay{mN0*;NBJyk>-WZ$}ZThD9 zAOGKzm7YYXR>931LP9qD1DAWvi$f3Z7d|){0Rp34ok#Xm3JWo}0nfIWVL~2q?5r~Q z6R&{EvzJ@C1-`HlXSFf5g?Hp5V~ca8gbLN`&Jqf~$b1~zqA!}CMLN60wyC%Rjj;kl z_~d7ZV;79P)P$Aqkqu>6K3|F!7J@1K4Ee_L0x`^L2-zrNHgSN$Ld2b4D`8vg;T(C$ zvC-{&ENKABqaIq@6&zv*MWj60;)~A-o;(z|Z>#kp0|?z;>MF|;DfmxzKXz~o-h90O zoqaGzURt+d&oefDuzVSM!F{mm9JJ67r+=z9$Bq9U-M^%c|hOe!us1f1bSafam20gA3$*Q!gsWbU^TQ+S9u6%QsRkVl6ozjvFynE{AW zm89B^ElZbvC&3wc%1D5 zGqZk+BEP1`hbVch;rNJqPF=@w;}HtKh`CJqq4}v8zvkvAVj*8e$>q(sZ8-B@-uq9( zz9{@6=0fzzox~7u=Ezq*>2;ZYe!bNAXtXaE3Jx)+PEK4afRM@KVGqs6M>0HdF^QQ` z_(#ivoW95hKxvl0MWlAg?%eQ%51vl0M&TDRm!w8No^?R2D_p)HqIWjq`H>O`4Nqq2 zhJr&}NPTc!g@ZcYT)rH=&aveKg93Hcp4%D~7-D9bGs+AAp+mhOvw&@;8 z07sF%_azh*;?!*!^o@}Xl|9MNVb?wG4`qM)7J!i2!xd3jh?#Qrx=6P{^gt)%AR&N=G1Ta8wuO0FGe1c(EKPZ8RwO3^{^jsg@iaWcU>Y>+>czVl*xWPlsLHO0;kg!{X@Thed(nnt-E|spZ2lt93MKUP?QzUeyYrm;E>wD;UI_ zY5K}BUcu8n1tdEU!aH(JYmIBgtW!j}ug=Z~6E_~f$Db8$5p#wgb*BV~!ucm}iV&K% zR3YaYFYL>lqqn+nM|<7+I<(lujmJ|ch_m1>yb1-MbQwJb#nDaG$g!wsMoU(l9v6k% zu8hTRgl<;;Dpn|nStc5He*{FK?ex;evXFGnx6I*J+}H1; z1%a5Mp=iZrl7J*TJyENyKA_S52s!07+0a*t- z&uCZX-rOP;LUKs!-ZNtW-*kIDRo-@TBp1&p)(wE!Kh%+Dh+!6jccVJa0>Cr=;5edO z9gxc#UjdGse~FLp={`3d7e5)fo5$?#llc(gYLo9r%bckfrrtFNQ9!~y{o+(&>oG*T zyTntie9(IP-Ez3+?ThD-&g@!p01sU+O)N^o;ja8sET4;*nI+Dzf9}M-a|8vCj=3a6 zm|KX$Rd*5bga&_m_pKxS*LQTDlP1%3c1vbm66wKi-y1%iaqU+`ncBxsh?sdy#!C%Kw|cs>8ORx8&eRzW z6M>KJeEDO<1;7U`Jg3#a9TshR69wuUt_px`N^zUsXVr#zqvmWP6(@&{ZVjWa&Pdp$ zy}gg49!q}kAy-JnOZIGUFP{AB7JN`ZG#oJI2ts5ywRgT3MP+AK6-PsJxZ$wt0HLxO#+#p#;`IineyMOLtz=r@LsyqGp#=41kbC|iA z>VZ~mRH$Tn^zi*~P^$*;!L%3VKq}5~(OIoX#@x8s2OK?p<}H#=t#}KUE5rrAq4(RO z<}84qA&XH?yt@e@GIQX}HsJ7~t4mT;vZE$PWMk<+=Pk|EG@^Nc{G< zwx)hLqN1&fgHXwmRJd{7M*yzwSw}YW@WZ%C^T7ut8;;iYWi;~dQ#N2N<95E?1wvWJXC)&F< zvxqswX3v%I8;;KBA7CGjnUn+=2m=A@S)Zn7oa|-a_L_ES-94RKD+TKKCpdBi*%Ld;n5kEwuqVk{I={M9gh#*QIUbEm)9;_5hZ{R{?yxxGbvYDhiHev_WGC%=- zKZ;V3H>LBrgW=hMq%+#*?tMuvd=Lrb3UR@Y45By&pnf|=YwN;-(dlkXM_pN~V=rJt_H{X^Kg`6QS z$jS`>++8zHfnjDMEPrIqyWj&5B?pgfZy~ZOI7E9kbT0ze%GL`-90Zj5H(Vr8_UO~| zNoN>)9xOb638LfyVj>sBfHv!55-^+x-hW|48Hfh(A?g3mR2)@h4$z`|Q(LBzv}nyU z%Ta*6dUxrzJCsbBwwfr(6yJF&@yL;h4@w>&7G&B2z=yU{UITy)E2k`65EH2?2%*Mx zSNJ4lRdPhhpyoWXwy6B*qRibiqf5;WZTG1I$@0rzgA{R%zIW`!zm8dm1jrd;&Oq)} zQ9{k@Q>iWMw$9d)cmD;5CRv_x`UUNbs0s{mkoa?K^C;r_=WF@-tq+nSfK97jnYNDp@&V}f($lM#eL^;GssIE!-q4#MuF?)c74TRyXArZu}XitR3xZ**(&^^(~(uk=$O^5w+c&hGSkD1G$Wjfj#9#4xp# z@a59yH-7tWvWWx$k0~SoA{LYb@9fY3H4l|z_@ERY*0pETGyud}!~sE-#(x+**bxwitDJ&B>tio&2z>S3 z);Y|a1;BD3tqCLvdv)m8Ywr}vV=uf`TEVC;#2o6K#IMYI>PtXC*%kt-0I7qzcj?{$ zf>ic!hz4r+xb|QNrEfh{^6k%$8bF5K8}HVR?wx7?-_97hk_tw3AqGk0!`c~te-k|6 zXN91kP;_AZ1NKh!+zU_>p>lKhpvA}bZQT@pST=s{#~>~{5DGQxwCPc^-TpfP5U-uF zVD?vdfoZHm_;GdsY2ekR!x!acbp|IZ+1iL3cT<^MKz$hL6V)fV!O#b5uPauD%7i z_Y!K9Wey&2WE)`7(n;z6srB{?KHjf`KJ>O^0LT;M-;TvcZmjsI*JRWYJ451}_g8)| ziVru|48EFd-}&Url*_v+2dFZqy1h`A)S=qHCl zlnlAFIf)3E3(@c|MbT&^R-GqH^qN}|J^rP1COxS)ti5b9Ad);-%)^+!LERO>lY6q= z9nO0_H=;mt-u=ykMb0@~63x9=6xgGmR?pGv7UhJW9MMmX^_O;<>;+tMS|4UjP9?27 zF?N*%^0^45r)~5B;G%mI=P`#l^~qT%h@N2@QT4RW!&)}*Cr7I%+OWFEXGj3T0rwvK<^Hgs<*vJoG?eh$gjf+sAYY<%4;Z(PrO#lglu1F$tRHI#6+x(2s z#WoE=6hOjm&jx=DE4vPAJE1LTwUMafeU6*;nP>AkW^xyMNQG*aC_muWz0{|} zsJ{SO@0CL-J@H>ra@k#~!-0H5ydLtqF96wm&Wl9=nOkonTgzFEs(aEg%Ed0d039^% zz(1F*%zSjv*)3TyWPLhw!d;0Bnu_KfB4LjSePd9W-lbn?)ZmR*)`$Y$Jyl$72g)le zS`FE7W3=V;#i^lWTi9!3D$`)B+JNVMAny?KNw22|ilQuBNHzrsBMypF)pcO9`K-CA z8=ikBTHf>KHqNKNpF8;rP=EVpWQ(aY z;u4J?xNb8P2;wYC4xKgbg-VoCbT&2pcXJ-G87B~ z7KIKSzML@6z*+mg`!qnkIdV+>qMmoOuiLL5+gf(<>pm0^;xMn)_!_nqL~?gPVBujc zuI{-90Obpoyf{B2p`eT4aH8q}Fed_z{IurGI)`}3{skV0QdkH$L?}eEdDix~ZiRpp zFmb}RymMgA6oi~|@}Gqm<*F1QC4>D3A)aHKIV1l$Ylr9m{v|<`GpAahMMTW~*Dms3 a1Nr|{DxRuvHVXFu0000s42CDEv14Z@)2P@Srsd~k^)M*T0KZn5ZybR-Tv4gbMJkhdGEdN zecmtn{lpkA521&Xlap7hir5V2d+@7Y0tY9@y4#~pPKzgFi49wdobPnWkNh0%QaSqS zjxOi@^TQ>-X)lhwvGd>?_lTT(es>3(tFzub(NvAy zIzL_N=%N<~u4pLwB>>1_qlr^ZWhdM<)3v6ru8s!PTca3@j-!I7^6GIpP-Cc@kD( zks#cOtGc|>&2*QNl z-@N~ND`WIcdN{QDW0^FG2q~KzompwR+{E4haX$RR>1DIiIl0YWB(C z_K7Nv)~o{Z13a*r3WW%+5Lo54{A?l}lG1*4jQtiQ8u_K%O}9bf&VeyPaBVBRWQ}Qs zRcaUYQyZ?^ztSFH-i`lH+1sWat0O6k$XzgUB>fM9Ywvt#c=&Nxe;Q zW`6;35cEMMAkh`){i+D%Gf-Lt5(%7#o<5a)H5d=XP>OUcwFe3z| z#s^FUXoj)3*|Mn+_*c{U+VTgCs-?@5=ZDgyW1TXt3HUFSpCtNS%?;aAHk~@2XY(~E zb?Rr~%I3JEtJ`P@dCAD=2_RC*sNSX!^z0zGmYLX2K*BgpbTszJ5|9vZQ2JO3I_5mA9KC5A zgw#;RNyoMLQ;NB zuIpv0R2`-J=4=?w6WDnJ^bvQWhrlk(&5n0-5K6yE)k7$R{kyFWDywzyWnvKDGT;jB zA{Uvnq2IQV|9mw4yu10A$t}u@1SflOIQ&177yja<=p+}nuK}^pB1sJhvjm(4G2q$w zsr3EYEf>OXddj@=v%^R~EF+qha?~~oB&pbDZN+efAm9dEFvC>>JXNI7Qp42(?1rdd zVx84*>I=1@ZT9A?m-CCaS~l(MdrGgS&xF5vazET1ruZ=TN?jkdn?AFDekOeXKVV0F u^w54g2gVt>+wmdSAYM%We=~M;&9AKA^Y#TxX!BmK`NwWdB+f=^4*UmVeU2^w literal 608 zcmV-m0-ybfP)`8`sOBzdOsVt49uvAMTEag4Po-PEP4Fpf=`0-&mCDjkRSHWnBpFCsvQ_CI z8E`6%rNOHROGYe921o`lOH@z+?3VtL`9lWawlpAilE^Yy=9IL=vRIXlpfV9v26kdz zuJY8o98@ZH=E5~3JtD+xiO)d=Zi&PJy9I#XlA5L) z0OFFI1c4=Oc>s~W`MKmZkXRN=35H)H0DcJ&bkH=KmAT3f698V*c;C!UO(Xm*+DjTO zHp{*XufcJHge?NVy<0j<*9PI$E@|2zb5@pWr$kyBb4hWOQn`sI$$;4+ z;bIc2630mr9l!t_Nw+LsWj4nWw&Yn)l8Qfx1eQo!=g5*&0F?~PEd@wh1V*I-lf<$Z ul>(>I?x(C*>F_EIQDx?+GR^=01(NSs_QJ@my6*@80000ippvsVM=45+N8s48@}bW5G}<{nP18XJ_Ag``#Yk?CyJKqxP{0 zmd=&{01(1BtOEdmq9Aq+9*0P5$i?%B!o`QPS-`rfUHR!oHR7>2#)&-+09Ll9jsof~ znbw$RhwTkDpSHBHcOps(%qkI=+mYy)?2rtBASpc?83I5^RuVruDUo{ONOmff9kw?r z5lk`%08C>TD=0c|;?>m1xe2BCY$q8JVqj_S7FiaC59y6%RBsIrgCkRz5P+f8le8ijK%3z!xUTdD^wUKz zlYp9xc2buz4^XPs85vT~ve%E;KlEc=+6lBdW3+htO1C=(vgSB;=z+D9pez8eh>_2-{Uk9P#E&vbHi4zlsdRoOYGAVwyddkw zxFCBGl7EqlP1G^<{r%k0=z8NG!^vo2p#V(09NE4iV}ILg>)5Qm!M)y7Mgzs=Fy5+X zBmHCI%cDGNLTyUI9ix9U!*@SdBH%E+zu(!wzSC<9q~UV>x46}JLW)$OWNw&jzXwB` zoo*SFs`Vn{oV{`kZ|I7F{F`j-IyjLe<@jdm))E2zF{$sx_98xG-q7BJ618neU|OdSqxS?~GhPZf zEkGY%5xFh>{#EDsrK_Iw_k_pTYmaAV2X!Mei?izynKl<&l}9rrZzgU1U&~8MRmj_$ zg))O2e8}7sS~)>~D;Lwz$^G#pTAW4wMci z{=tOdr0)(drLcw+ai-XIgK9orWb9K~Sk&g!spYWnc{vpnhr4?;%vHWs7xe_`Q>E%K zmx$4Em+W_pgTGF&b`8xB!`ey-b9#9<^j%s14bMSW2ZIwux;3!5cML&#l*7ot(jJf~ zwvO6QpS@XDaN1|%*GiIIRAZiN3j38In;lb7ix^%c=zm_$@&wZ>DFHrUZfJVd)sC7& zPvfEcuq)A0RWZ)$D^+o2goV0BnKG|XB!^XZ(H2hs{@zg!P@W3a3n))64D_Fs6ZBIY zu~p0GZ&#GOt^=yoVRubQc?P}e8%aoMznS5A^}AT#A%mUcZ?~5Oler6_=WAuP;_z0( z%`d{U=Doa&t23&S1Ez@%&bZyY!eN+&WAczxQ{;#=-0M|AWJj`ehQFBL!;cGL4E|-0 xUw^-@LY1-v`%<=)o(b;Ym=YhU5dW)9i{@S4J_^mbu3S?U3k%)HY7K^p{sBv$RJH&B diff --git a/doc/tutorials/imgproc/opening_closing_hats/images/Morphology_2_Tutorial_Theory_TopHat.png b/doc/tutorials/imgproc/opening_closing_hats/images/Morphology_2_Tutorial_Theory_TopHat.png index ca22789b03681fdfbfc409c15e83b238229a8c86..18f5084ca5fca00c89d72385511f420e03f6855c 100644 GIT binary patch literal 1531 zcmaJ>YfMvD9Ip?g+=4=BX?XXxy`{EAc{#xsa4FE1haHwjg~6KLfkrZ2<0ixhPVdEm z!fr1qP(x&Qb{laOJA*n*=i=Rm-9|D^m!M=g*Kxm)5F`!J)H&R_e%yzBIKOlLkMlqO z$NB&JEVY$!Pzodv2;xjeLmk-v1Z!9bK=9Yz-$MdH6k{@!TD#Ugy?^oMwL(Gp{ab5q zuD+bl4J8<&#NGp+KKNoNGpo4v%-HL~$j9LY?w3H}I_~6pHagER%05#lapLvXJhX`& zS8TwgkprH#Lu{MkDbqWz4Sw#2|L=fSElZ0^?-IlFI>))=qU`BLZsVdXB|KvM$*1n= zUlr-XcUXa4-E%2cyq5J0tZ`QJ_U+2Ie(;X{!xV>igffdN?h?@vYDIp*c*nw?z|ldn zm8Nb8U1{)-DAJaoEkbt@eW&U<;bLNYxZbJsR5h`U<%48~9qyr4g`&uir>x0YY?>4u z31l9PzSm4PC=Iv$!fjmCgTsC))piy`I}dT!jpzUu(FeuKg%fX{6jPE(}!vSk{~ z?^A4{$*bI#J~h}w%;h~ex_L;6R`pxhCK@T%a5+WtDGx-%N)Of%K(wD3u14VnJloAH zzGQ~=D0~&qw(-!%PBq%ayVUr#86Pyl3I@o%e zd@dx$6paLW4?Nu8BGE=vua&1!WE}7DkQY%T6OUdLYa{YK?D-Z66p@1fB;isGS2`Kv z^2@Y~3EJ-M*0B6Bj{X7VFD5|Ux*4u?8;~U?1z~Hrwh7!5YrBD0~Co;SNO6l#IE&3XH|iVz3N1zaXTGQth0q z0jv2{RiL~m!{Fil;5L?)m}GYvoF zrYuHXCmT1h{__4FGiKOXC*3m$2C_Y(r)=Q*^`_keEow>|;FOd~?pAv7T zV8$@Z^rpeji874zks##CKx#;ktS$h5!O`!R>?3KW*9-chRd|#=7V5J)A7G7Ll@+4h zm|!mPifID#tyK4t>GmqQHLvN3Sm-)VcF@Qcn))8C%0Q8HOgH5bCMIv?aZ#RXuW6?# zCv$lQMfQ564HzQHt7~$)EJoR3TxyGP#YzCr8Z4h>&{-7OKoDNS{E9s|YEoMBEIbA) z8<^@8yJ7)%7chobta-vCRp(iF44RT?s$rBZ;nBDq{PA}f!zPI6#QRpMat*In$78T2 zi6$#XSqqQGVxX78y9*Ck0)jjd0nGM7JZ>Uw6BsgsO;`fvQC^hjCft{R6;Xb2X}eu9 zlrwanF{th8GFDN|!Fue69OnfenTvrQ;;SLQnbb-)<1$QQ6aCF)*vDg)1HQ^-@e8&v z2tDNXh1{{KRD0F3ZZ%%__oaAE@}@~zlAolwDM?DS?~wSQ2_OW2 zRHFO1B(F){HECf=g!Vs0m8wd6uY6O*s$!OW5z?7JNK>V%QtZbi|Ar)|NmKZd#kiLXnZxpdSeFV9S>VN$phQ>GXp$u6;6I<~Ukl?uPa zWhNP6iD%LQ%2ReGfMr7Y<&q9;l*1`TN?78A7+SJZVzLpXONa?!Ut)=p-1hm1%NQp}XLq;6yJ zhumT{LZX|J?Udq);1BUc$#Ln}ha64Yl( "@input" ), IMREAD_COLOR ); if( src.empty() ) { diff --git a/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp b/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp index ce71a3b118..3619753162 100644 --- a/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp +++ b/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp @@ -33,7 +33,7 @@ void Morphology_Operations( int, void* ); int main( int argc, char** argv ) { //![load] - CommandLineParser parser( argc, argv, "{@input | ../data/baboon.jpg | input image}" ); + CommandLineParser parser( argc, argv, "{@input | ../data/LinuxLogo.jpg | input image}" ); src = imread( parser.get( "@input" ), IMREAD_COLOR ); if (src.empty()) { diff --git a/samples/cpp/tutorial_code/ImgProc/Smoothing/Smoothing.cpp b/samples/cpp/tutorial_code/ImgProc/Smoothing/Smoothing.cpp index d96b52a0c1..34d5733f75 100644 --- a/samples/cpp/tutorial_code/ImgProc/Smoothing/Smoothing.cpp +++ b/samples/cpp/tutorial_code/ImgProc/Smoothing/Smoothing.cpp @@ -36,52 +36,90 @@ int main( int argc, char ** argv ) const char* filename = argc >=2 ? argv[1] : "../data/lena.jpg"; src = imread( filename, IMREAD_COLOR ); - if(src.empty()){ + if(src.empty()) + { printf(" Error opening image\n"); printf(" Usage: ./Smoothing [image_name -- default ../data/lena.jpg] \n"); return -1; } - if( display_caption( "Original Image" ) != 0 ) { return 0; } + if( display_caption( "Original Image" ) != 0 ) + { + return 0; + } dst = src.clone(); - if( display_dst( DELAY_CAPTION ) != 0 ) { return 0; } - + if( display_dst( DELAY_CAPTION ) != 0 ) + { + return 0; + } /// Applying Homogeneous blur - if( display_caption( "Homogeneous Blur" ) != 0 ) { return 0; } + if( display_caption( "Homogeneous Blur" ) != 0 ) + { + return 0; + } //![blur] for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ) - { blur( src, dst, Size( i, i ), Point(-1,-1) ); - if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } } + { + blur( src, dst, Size( i, i ), Point(-1,-1) ); + if( display_dst( DELAY_BLUR ) != 0 ) + { + return 0; + } + } //![blur] /// Applying Gaussian blur - if( display_caption( "Gaussian Blur" ) != 0 ) { return 0; } + if( display_caption( "Gaussian Blur" ) != 0 ) + { + return 0; + } //![gaussianblur] for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ) - { GaussianBlur( src, dst, Size( i, i ), 0, 0 ); - if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } } + { + GaussianBlur( src, dst, Size( i, i ), 0, 0 ); + if( display_dst( DELAY_BLUR ) != 0 ) + { + return 0; + } + } //![gaussianblur] /// Applying Median blur - if( display_caption( "Median Blur" ) != 0 ) { return 0; } + if( display_caption( "Median Blur" ) != 0 ) + { + return 0; + } //![medianblur] for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ) - { medianBlur ( src, dst, i ); - if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } } + { + medianBlur ( src, dst, i ); + if( display_dst( DELAY_BLUR ) != 0 ) + { + return 0; + } + } //![medianblur] /// Applying Bilateral Filter - if( display_caption( "Bilateral Blur" ) != 0 ) { return 0; } + if( display_caption( "Bilateral Blur" ) != 0 ) + { + return 0; + } //![bilateralfilter] for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ) - { bilateralFilter ( src, dst, i, i*2, i/2 ); - if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } } + { + bilateralFilter ( src, dst, i, i*2, i/2 ); + if( display_dst( DELAY_BLUR ) != 0 ) + { + return 0; + } + } //![bilateralfilter] /// Done diff --git a/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java b/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java new file mode 100644 index 0000000000..386f94a553 --- /dev/null +++ b/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java @@ -0,0 +1,155 @@ +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferByte; + +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import org.opencv.core.Core; +import org.opencv.core.Mat; +import org.opencv.core.Point; +import org.opencv.core.Size; +import org.opencv.imgcodecs.Imgcodecs; +import org.opencv.imgproc.Imgproc; + +public class MorphologyDemo1 { + private static final String[] ELEMENT_TYPE = { "Rectangle", "Cross", "Ellipse" }; + private static final String[] MORPH_OP = { "Erosion", "Dilatation" }; + private static int maxKernelSize = 21; + private Mat matImgSrc; + private Mat matImgDst = new Mat(); + private int elementType = Imgproc.CV_SHAPE_RECT; + private int kernelSize = 0; + private boolean doErosion = true; + private JFrame frame; + private JLabel imgLabel; + + public MorphologyDemo1(String[] args) { + String imagePath = args.length > 0 ? args[0] : "../data/LinuxLogo.jpg"; + matImgSrc = Imgcodecs.imread(imagePath); + if (matImgSrc.empty()) { + System.out.println("Empty image: " + imagePath); + System.exit(0); + } + + // Create and set up the window. + frame = new JFrame("Erosion and dilatation demo"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + // Set up the content pane. + BufferedImage img = toBufferedImage(matImgSrc); + addComponentsToPane(frame.getContentPane(), img); + // Use the content pane's default BorderLayout. No need for + // setLayout(new BorderLayout()); + // Display the window. + frame.pack(); + frame.setVisible(true); + } + + private void addComponentsToPane(Container pane, BufferedImage img) { + if (!(pane.getLayout() instanceof BorderLayout)) { + pane.add(new JLabel("Container doesn't use BorderLayout!")); + return; + } + + JPanel sliderPanel = new JPanel(); + sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS)); + + JComboBox elementTypeBox = new JComboBox<>(ELEMENT_TYPE); + elementTypeBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + @SuppressWarnings("unchecked") + JComboBox cb = (JComboBox)e.getSource(); + if (cb.getSelectedIndex() == 0) { + elementType = Imgproc.CV_SHAPE_RECT; + } else if (cb.getSelectedIndex() == 1) { + elementType = Imgproc.CV_SHAPE_CROSS; + } else if (cb.getSelectedIndex() == 2) { + elementType = Imgproc.CV_SHAPE_ELLIPSE; + } + update(); + } + }); + sliderPanel.add(elementTypeBox); + + sliderPanel.add(new JLabel("Kernel size: 2n + 1")); + JSlider slider = new JSlider(0, maxKernelSize, 0); + slider.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + JSlider source = (JSlider) e.getSource(); + kernelSize = source.getValue(); + update(); + } + }); + sliderPanel.add(slider); + + JComboBox morphOpBox = new JComboBox<>(MORPH_OP); + morphOpBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + @SuppressWarnings("unchecked") + JComboBox cb = (JComboBox)e.getSource(); + doErosion = cb.getSelectedIndex() == 0; + update(); + } + }); + sliderPanel.add(morphOpBox); + + pane.add(sliderPanel, BorderLayout.PAGE_START); + imgLabel = new JLabel(new ImageIcon(img)); + pane.add(imgLabel, BorderLayout.CENTER); + } + + private BufferedImage toBufferedImage(Mat matrix) { + int type = BufferedImage.TYPE_BYTE_GRAY; + if (matrix.channels() > 1) { + type = BufferedImage.TYPE_3BYTE_BGR; + } + int bufferSize = matrix.channels() * matrix.cols() * matrix.rows(); + byte[] buffer = new byte[bufferSize]; + matrix.get(0, 0, buffer); // get all the pixels + BufferedImage image = new BufferedImage(matrix.cols(), matrix.rows(), type); + final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); + System.arraycopy(buffer, 0, targetPixels, 0, buffer.length); + return image; + } + + private void update() { + Mat element = Imgproc.getStructuringElement(elementType, new Size(2 * kernelSize + 1, 2 * kernelSize + 1), + new Point(kernelSize, kernelSize)); + + if (doErosion) { + Imgproc.erode(matImgSrc, matImgDst, element); + } else { + Imgproc.dilate(matImgSrc, matImgDst, element); + } + BufferedImage img = toBufferedImage(matImgDst); + imgLabel.setIcon(new ImageIcon(img)); + frame.repaint(); + } + + public static void main(String[] args) { + // Load the native OpenCV library + System.loadLibrary(Core.NATIVE_LIBRARY_NAME); + + // Schedule a job for the event dispatch thread: + // creating and showing this application's GUI. + javax.swing.SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + new MorphologyDemo1(args); + } + }); + } +} diff --git a/samples/java/tutorial_code/ImgProc/opening_closing_hats/MorphologyDemo2.java b/samples/java/tutorial_code/ImgProc/opening_closing_hats/MorphologyDemo2.java new file mode 100644 index 0000000000..e5d80280a9 --- /dev/null +++ b/samples/java/tutorial_code/ImgProc/opening_closing_hats/MorphologyDemo2.java @@ -0,0 +1,153 @@ +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferByte; + +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import org.opencv.core.Core; +import org.opencv.core.Mat; +import org.opencv.core.Point; +import org.opencv.core.Size; +import org.opencv.imgcodecs.Imgcodecs; +import org.opencv.imgproc.Imgproc; + +public class MorphologyDemo2 { + private static final String[] MORPH_OP = { "Opening", "Closing", "Gradient", "Top Hat", "Black Hat" }; + private static final int[] MORPH_OP_TYPE = { Imgproc.MORPH_OPEN, Imgproc.MORPH_CLOSE, + Imgproc.MORPH_GRADIENT, Imgproc.MORPH_TOPHAT, Imgproc.MORPH_BLACKHAT }; + private static final String[] ELEMENT_TYPE = { "Rectangle", "Cross", "Ellipse" }; + private static int maxKernelSize = 21; + private Mat matImgSrc; + private Mat matImgDst = new Mat(); + private int morphOpType = Imgproc.MORPH_OPEN; + private int elementType = Imgproc.CV_SHAPE_RECT; + private int kernelSize = 0; + private JFrame frame; + private JLabel imgLabel; + + public MorphologyDemo2(String[] args) { + String imagePath = args.length > 0 ? args[0] : "../data/LinuxLogo.jpg"; + matImgSrc = Imgcodecs.imread(imagePath); + if (matImgSrc.empty()) { + System.out.println("Empty image: " + imagePath); + System.exit(0); + } + + // Create and set up the window. + frame = new JFrame("Morphology Transformations demo"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + // Set up the content pane. + BufferedImage img = toBufferedImage(matImgSrc); + addComponentsToPane(frame.getContentPane(), img); + // Use the content pane's default BorderLayout. No need for + // setLayout(new BorderLayout()); + // Display the window. + frame.pack(); + frame.setVisible(true); + } + + private void addComponentsToPane(Container pane, BufferedImage img) { + if (!(pane.getLayout() instanceof BorderLayout)) { + pane.add(new JLabel("Container doesn't use BorderLayout!")); + return; + } + + JPanel sliderPanel = new JPanel(); + sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS)); + + JComboBox morphOpBox = new JComboBox<>(MORPH_OP); + morphOpBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + @SuppressWarnings("unchecked") + JComboBox cb = (JComboBox)e.getSource(); + morphOpType = MORPH_OP_TYPE[cb.getSelectedIndex()]; + update(); + } + }); + sliderPanel.add(morphOpBox); + + JComboBox elementTypeBox = new JComboBox<>(ELEMENT_TYPE); + elementTypeBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + @SuppressWarnings("unchecked") + JComboBox cb = (JComboBox)e.getSource(); + if (cb.getSelectedIndex() == 0) { + elementType = Imgproc.CV_SHAPE_RECT; + } else if (cb.getSelectedIndex() == 1) { + elementType = Imgproc.CV_SHAPE_CROSS; + } else if (cb.getSelectedIndex() == 2) { + elementType = Imgproc.CV_SHAPE_ELLIPSE; + } + update(); + } + }); + sliderPanel.add(elementTypeBox); + + sliderPanel.add(new JLabel("Kernel size: 2n + 1")); + JSlider slider = new JSlider(0, maxKernelSize, 0); + slider.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + JSlider source = (JSlider) e.getSource(); + kernelSize = source.getValue(); + update(); + } + }); + sliderPanel.add(slider); + + pane.add(sliderPanel, BorderLayout.PAGE_START); + imgLabel = new JLabel(new ImageIcon(img)); + pane.add(imgLabel, BorderLayout.CENTER); + } + + private BufferedImage toBufferedImage(Mat matrix) { + int type = BufferedImage.TYPE_BYTE_GRAY; + if (matrix.channels() > 1) { + type = BufferedImage.TYPE_3BYTE_BGR; + } + int bufferSize = matrix.channels() * matrix.cols() * matrix.rows(); + byte[] buffer = new byte[bufferSize]; + matrix.get(0, 0, buffer); // get all the pixels + BufferedImage image = new BufferedImage(matrix.cols(), matrix.rows(), type); + final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); + System.arraycopy(buffer, 0, targetPixels, 0, buffer.length); + return image; + } + + private void update() { + Mat element = Imgproc.getStructuringElement(elementType, new Size(2 * kernelSize + 1, 2 * kernelSize + 1), + new Point(kernelSize, kernelSize)); + + Imgproc.morphologyEx(matImgSrc, matImgDst, morphOpType, element); + BufferedImage img = toBufferedImage(matImgDst); + imgLabel.setIcon(new ImageIcon(img)); + frame.repaint(); + } + + public static void main(String[] args) { + // Load the native OpenCV library + System.loadLibrary(Core.NATIVE_LIBRARY_NAME); + + // Schedule a job for the event dispatch thread: + // creating and showing this application's GUI. + javax.swing.SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + new MorphologyDemo2(args); + } + }); + } +} diff --git a/samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py b/samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py new file mode 100644 index 0000000000..cb3af732e8 --- /dev/null +++ b/samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py @@ -0,0 +1,63 @@ +from __future__ import print_function +import cv2 as cv +import numpy as np +import argparse + +erosion_size = 0 +max_elem = 2 +max_kernel_size = 21 +title_trackbar_element_type = 'Element:\n 0: Rect \n 1: Cross \n 2: Ellipse' +title_trackbar_kernel_size = 'Kernel size:\n 2n +1' +title_erosion_window = 'Erosion Demo' +title_dilatation_window = 'Dilation Demo' + +def erosion(val): + erosion_size = cv.getTrackbarPos(title_trackbar_kernel_size, title_erosion_window) + erosion_type = 0 + val_type = cv.getTrackbarPos(title_trackbar_element_type, title_erosion_window) + if val_type == 0: + erosion_type = cv.MORPH_RECT + elif val_type == 1: + erosion_type = cv.MORPH_CROSS + elif val_type == 2: + erosion_type = cv.MORPH_ELLIPSE + + element = cv.getStructuringElement(erosion_type, (2*erosion_size + 1, 2*erosion_size+1), (erosion_size, erosion_size)) + erosion_dst = cv.erode(src, element) + cv.imshow(title_erosion_window, erosion_dst) + +def dilatation(val): + dilatation_size = cv.getTrackbarPos(title_trackbar_kernel_size, title_dilatation_window) + dilatation_type = 0 + val_type = cv.getTrackbarPos(title_trackbar_element_type, title_dilatation_window) + if val_type == 0: + dilatation_type = cv.MORPH_RECT + elif val_type == 1: + dilatation_type = cv.MORPH_CROSS + elif val_type == 2: + dilatation_type = cv.MORPH_ELLIPSE + + element = cv.getStructuringElement(dilatation_type, (2*dilatation_size + 1, 2*dilatation_size+1), (dilatation_size, dilatation_size)) + dilatation_dst = cv.dilate(src, element) + cv.imshow(title_dilatation_window, dilatation_dst) + +parser = argparse.ArgumentParser(description='Code for Eroding and Dilating tutorial.') +parser.add_argument('--input', help='Path to input image.', default='../data/LinuxLogo.jpg') +args = parser.parse_args() + +src = cv.imread(args.input) +if src is None: + print('Could not open or find the image: ', args.input) + exit(0) + +cv.namedWindow(title_erosion_window) +cv.createTrackbar(title_trackbar_element_type, title_erosion_window , 0, max_elem, erosion) +cv.createTrackbar(title_trackbar_kernel_size, title_erosion_window , 0, max_kernel_size, erosion) + +cv.namedWindow(title_dilatation_window) +cv.createTrackbar(title_trackbar_element_type, title_dilatation_window , 0, max_elem, dilatation) +cv.createTrackbar(title_trackbar_kernel_size, title_dilatation_window , 0, max_kernel_size, dilatation) + +erosion(0) +dilatation(0) +cv.waitKey() diff --git a/samples/python/tutorial_code/imgProc/opening_closing_hats/morphology_2.py b/samples/python/tutorial_code/imgProc/opening_closing_hats/morphology_2.py new file mode 100644 index 0000000000..5dfdece1b6 --- /dev/null +++ b/samples/python/tutorial_code/imgProc/opening_closing_hats/morphology_2.py @@ -0,0 +1,48 @@ +from __future__ import print_function +import cv2 as cv +import numpy as np +import argparse + +morph_size = 0 +max_operator = 4 +max_elem = 2 +max_kernel_size = 21 +title_trackbar_operator_type = 'Operator:\n 0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat' +title_trackbar_element_type = 'Element:\n 0: Rect - 1: Cross - 2: Ellipse' +title_trackbar_kernel_size = 'Kernel size:\n 2n + 1' +title_window = 'Morphology Transformations Demo' +morph_op_dic = {0: cv.MORPH_OPEN, 1: cv.MORPH_CLOSE, 2: cv.MORPH_GRADIENT, 3: cv.MORPH_TOPHAT, 4: cv.MORPH_BLACKHAT} + +def morphology_operations(val): + morph_operator = cv.getTrackbarPos(title_trackbar_operator_type, title_window) + morph_size = cv.getTrackbarPos(title_trackbar_kernel_size, title_window) + morph_elem = 0 + val_type = cv.getTrackbarPos(title_trackbar_element_type, title_window) + if val_type == 0: + morph_elem = cv.MORPH_RECT + elif val_type == 1: + morph_elem = cv.MORPH_CROSS + elif val_type == 2: + morph_elem = cv.MORPH_ELLIPSE + + element = cv.getStructuringElement(morph_elem, (2*morph_size + 1, 2*morph_size+1), (morph_size, morph_size)) + operation = morph_op_dic[morph_operator] + dst = cv.morphologyEx(src, operation, element) + cv.imshow(title_window, dst) + +parser = argparse.ArgumentParser(description='Code for More Morphology Transformations tutorial.') +parser.add_argument('--input', help='Path to input image.', default='../data/LinuxLogo.jpg') +args = parser.parse_args() + +src = cv.imread(args.input) +if src is None: + print('Could not open or find the image: ', args.input) + exit(0) + +cv.namedWindow(title_window) +cv.createTrackbar(title_trackbar_operator_type, title_window , 0, max_operator, morphology_operations) +cv.createTrackbar(title_trackbar_element_type, title_window , 0, max_elem, morphology_operations) +cv.createTrackbar(title_trackbar_kernel_size, title_window , 0, max_kernel_size, morphology_operations) + +morphology_operations(0) +cv.waitKey()