From 96a501c08be2b4cbfacf79f374cb254a983f1e67 Mon Sep 17 00:00:00 2001 From: kadi soheib Date: Fri, 3 Jul 2020 21:40:01 +0300 Subject: [PATCH 01/21] Adding comment from source code to documentation. --- modules/dnn/include/opencv2/dnn/all_layers.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/dnn/include/opencv2/dnn/all_layers.hpp b/modules/dnn/include/opencv2/dnn/all_layers.hpp index e1df918037..9418a63ce6 100644 --- a/modules/dnn/include/opencv2/dnn/all_layers.hpp +++ b/modules/dnn/include/opencv2/dnn/all_layers.hpp @@ -598,6 +598,15 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN static Ptr create(const LayerParams& params); }; + /** + * @brief \f$ L_p \f$ - detection output layer. + * + * num() and channels() are 1. + * Since the number of bboxes to be kept is unknown before nms, we manually + * set it to maximal number of detections, [keep_top_k] parameter multiplied by batch size. + * Each row is a 7 dimension std::vector, which stores + * [image_id, label, confidence, xmin, ymin, xmax, ymax] + */ class CV_EXPORTS DetectionOutputLayer : public Layer { public: From 17c430da88f798ec6c6118760bed850d643a841c Mon Sep 17 00:00:00 2001 From: kadi soheib Date: Fri, 3 Jul 2020 22:05:50 +0300 Subject: [PATCH 02/21] Updated comment. --- modules/dnn/include/opencv2/dnn/all_layers.hpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/dnn/include/opencv2/dnn/all_layers.hpp b/modules/dnn/include/opencv2/dnn/all_layers.hpp index 9418a63ce6..fb211fe46b 100644 --- a/modules/dnn/include/opencv2/dnn/all_layers.hpp +++ b/modules/dnn/include/opencv2/dnn/all_layers.hpp @@ -599,13 +599,11 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN }; /** - * @brief \f$ L_p \f$ - detection output layer. + * @brief detection output layer. * - * num() and channels() are 1. - * Since the number of bboxes to be kept is unknown before nms, we manually - * set it to maximal number of detections, [keep_top_k] parameter multiplied by batch size. - * Each row is a 7 dimension std::vector, which stores - * [image_id, label, confidence, xmin, ymin, xmax, ymax] + * The layer size is: @f$ (1 \times 1 \times N \times 7) @f$ + * where N is the number of detections after nms, and each row is: + * [image_id, label, confidence, xmin, ymin, xmax, ymax] */ class CV_EXPORTS DetectionOutputLayer : public Layer { From f86c8656a3bfa9219359faba16fd11091fbb7938 Mon Sep 17 00:00:00 2001 From: Anna Petrovicheva Date: Mon, 27 Jul 2020 17:42:15 +0300 Subject: [PATCH 03/21] Updated the OpenCV logo --- doc/js_tutorials/js_assets/opencv_logo.jpg | Bin 4553 -> 5327 bytes doc/opencv-logo-small.png | Bin 1447 -> 2155 bytes doc/opencv-logo-white.png | Bin 8099 -> 9760 bytes doc/opencv-logo.png | Bin 17775 -> 36328 bytes doc/opencv-logo2.png | Bin 24903 -> 42892 bytes doc/opencv.ico | Bin 4798 -> 4286 bytes .../py_setup/images/opencv_logo.jpg | Bin 4553 -> 5327 bytes samples/data/opencv-logo-white.png | Bin 8099 -> 9760 bytes samples/data/opencv-logo.png | Bin 24903 -> 40104 bytes .../ImageManipulations/assets/StoreLogo.png | Bin 1426 -> 2251 bytes .../assets/opencv-logo-150.png | Bin 4609 -> 5230 bytes .../assets/opencv-logo-30.png | Bin 1099 -> 1194 bytes .../assets/windows-sdk.scale-100.png | Bin 1426 -> 2251 bytes .../JavaScript/images/logo.scale-100.png | Bin 4609 -> 5230 bytes .../JavaScript/images/smalllogo.scale-100.png | Bin 1099 -> 1432 bytes .../winrt/JavaScript/images/windows-sdk.png | Bin 1426 -> 2251 bytes .../OcvImageProcessing/Assets/Logo.png | Bin 4609 -> 5230 bytes .../OcvImageProcessing/Assets/SmallLogo.png | Bin 1099 -> 1194 bytes .../OcvImageProcessing/Assets/StoreLogo.png | Bin 1426 -> 2251 bytes 19 files changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/js_tutorials/js_assets/opencv_logo.jpg b/doc/js_tutorials/js_assets/opencv_logo.jpg index a2854e1e9e7f07125100f1c6f58c2fa04e705703..c2bf3a174899b977e8471dbedd0f71519d0788bb 100644 GIT binary patch literal 5327 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 GS@<7@3)vU| literal 4553 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 diff --git a/doc/opencv-logo-small.png b/doc/opencv-logo-small.png index 763ceb2b325b21a83ed10896daa8a9dc9dc5460b..b7e76d27baca0056c4f87f8fb22fd08aa9b21f1a 100644 GIT binary patch delta 2118 zcmV-M2)XyC3+oV&Bsm0UK}|sb0I`n?{9y$E001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}olAsl}eB>(^xB>_oNB=7(L00(qQO+^Rf2OAF^GDzNq z8vpT*b?S`B2Ct}QmfWkK9 zhaqZEh$eta>9&pq{E-L(Doi0pAc*207=r>%L57#wVepiqCBKp9Akx;P%GVc>8FMFnXAUJw^GaoQ4eJK(@~og^yA zWiW-M=SFK8W?A^YXz65O#1Sws;+c{;b7%?n2Y;Gyk}}^`umY?C6?{L*GUi(lW{Jk$ znktDF{p|}d0%ahUrMZK(j+XB&-z zMHavBt`%Tcqrjf_@bC!NF|`h5^I9VkM}1@u9bq{pY`0@lY|-fK6C@2Vot9sLb5m-jH z!_FgJ71j-G&=FM!?vLtWlh3@JU)qGWMjvCwaY>V9rt=8xU{0x#Oht`L%ZiK$Pj$Xh zR8?>j#kI484))Q+sP`T9+Wm*y%%oV=E=3bntBOj?w%qn;wH4wG6j+L@3cBFA%d*Ou zt-s&(?j*W)qZEHWSG%RkvV;+FYO8$wD(?1P!xdL+4*O~g>3aZp5-bLvfh}M&SPk9; zZjiirZJu&y&QlQRwuIvx8v=2I9aA9%H>x*#Fk86UXxqB43xt>P$Q@x9DCNy0Qy@eY3vb3m;? zj2=ILq;N#peX4V@U@BM(dYg%WL$m7!R)7T{k?fL}GyO;bJDmFvG=(YZ0>~|{E;KF5 zK{M`SHaN5hTmm=1Jc@wKHc5-tL~sSP@JZ==%cO8oiEwTexE`h`#`jyS*Pm}%ltYWu zV$cK_rv`tdiK51%oC5ZQ*b(bNQmbt#iK;G$fny6nb2~)UgQ2vH&3;l!Rp+MgNU=72 zM522e>>0kN-r$i6wWFVxfG#Oy%TxAf(9jN1Enq&Cfv}cf2^$3bI--d4AX_hLJYi&j zdIQ_D;1Sgpj>Us=6C!Ad9tXehEO-j+0)4`X7KDFU@#1$391F4&ICO+j!dN4*-2`kT zYz#Op5mf``g2A9CWj`W#+Pqwu|AB&As|IXaSvNVZyGIrFy=Z?4fdmr?h=i?^2|FtgM$Y!|24)DGW}YpN z3&z>_etlky&7&^GO#+9GgTbQCgV#ao4R;I1IZaOOm-K*HYI9tZuPbWd@6&0F*Lkrv z8pp%P*9EFm%LEQl_wbsnRR1`_n_uDygRUh=1v&MBq=r!u9;lZPyxR9za7nD%M2szA`i;QZMpz;oa?iS0R>7!pQZ{kJAss*7L`*g$&*9F!!U zAn&0DT0?|UOXZa~7hIMBupMj#e}I3hChWF=9>HbxICq?NG69}g+SZ{|@RtcE!$oVL zv5awKd5MI@nb>RLLRSXUJV$0I2CY#(XzWB$)U_1ZY1x*sn>vSnCYPic=v?PfCoE84 zbOMeCB|7J-_VN`-z9pNg;sR>+`=*1U8u=wqg6KG7|GysjIv6>M)JAZ(ZvB7rRm})S zt}j>)&bLEU9hk|_c&2Zfz)Vov4p9yK)NB`C0u}jNYgAV-0elV4m^ek#^}tGyQCy=< zP?*o9*$<@5QOELL=3`X32HHA}y#u-pIu03~!qSaf7zbY(hY za%Ew3WdJfTGB7PLH!U(ZR53L=Gc!6eIV&(TIxsL;n&&J4001R)MObuXVRU6WZEs|0 wW_bWIFfuSLFgGnSH&ih-Ix;yrH83kMGdeIZU^ZM+00000NkvXXu0jG}g0|ABv;Y7A delta 1406 zcmV-^1%dkO5T^@}B#~ele=Z{c04^f|c%?sf00007bV*G`2i^(^2p=}zt4eDC00lHj zL_t(&-p!e7h*eb-$A4$MzGfzsY9=k6bQCdSf|y`>*h7M{7nEjHAXHxxg`$v@C@3V5 zq9`(=P_l=mAB-Xp1}!O?9!@oBAc!M1V-u!b$85%$$DMy4?!Nb)f2-%5z0dJFXU=7F z&dlCx@AW@xt-b$i9ghlK0=&|5H82af7q}U?9H<8dfG%JUupRggIO@TOUw%wpg5`p* z1#)P|1@8(P3omD^fk7}quw9UI1m$ldf``W(I6++uD@C<6z896crKSk>Q~*?=txMH% zD&5yr5R?Q%f<Jm4?MOTa>!q!IigI=2)0izp8|wGC*C#kWS!Wm>c=1 z(+0~@^F|dId0>+w`ul)B&%OcmSk^gjw1MS-!HE9Jz~rdFe>b4dx2$t&RDpRg1oTD> znFBP~VhmVeS*kOQ&EsiH;C~*p8~XltnZvF)J`G@3Iw-bHa8UriY!PHFvTdnxM!|kd zDl#IN9{_BLVAulerZln`0@1o-gS3Dff+_TJ|J$nxMxg_uiN(5BOYbmSC4r@VXds zYmLlWL)AtJnBw&p;zRD!PZ7+mG$7BZP?-OF3NX{~w;XU3kM2VE1%E;I!eCLyTI49y z70VN+6^Olv6No;k%@nKD4^P|>yk;<3Tug}fLb*HLoIa+!SzKnbw}k#PrA zRPOl@e@4|0YK}P8XMj$G$Zk2^S}PKQ$|0^w5La_R*$Dppq1jM^WH(!~rG*7hHHbC` z5Pu?GHoN6hh_4W@#CJgfTJ2CX4M`(t%i(PtofD!eQ%lLmMZK;$tUm(->D4e zX|eRb0bbXcB&(>zFz}k?H803uK9h!A$MD#1C31O}92Z%x^NNZrumIa=qp`p)U?gJA znHlmQ!o#la7*<$KzAP71V_fAcj@DS_I^wWiucd!t1~?gIQb%BmfTa=rkNKXnmbsdM ze|F25*%p)jT?HJ77*K<_A#{q8moJN$V*ohi8~ckz=`{{nz%mQ4Lm(co?27Hk)aez- zFCRnGn@c>0GUS%w}8}x_Cw6o?=ZU;RFs<#39AFztj%+)s^u>b%7 M07*qoM6N<$g11(c*#H0l diff --git a/doc/opencv-logo-white.png b/doc/opencv-logo-white.png index 3c7098459e04c5d2a3fed7cb883ce985a55456f0..a683e3569f91731c86ae6598963125ff0b8e1799 100644 GIT binary patch literal 9760 zcmb7qcTf|~6E7kqp(h9^y@Vz$^o|mGSBfAYH6S(gCPhjhbO=QV)gVfdDjlhzYtV=& zMLG!i(nN}Mc>L!5@&0~uv$uD<_u1K*o7ugc+oVUvIF#hIRoI zH*@B+*qa+h_FUaaorI(@gZjde{ASPXtZQmSLh?d@gd`eCLUMK^iYAhf1VKqiHXTSv zl=4YPSbU2*AFJFbD4Yy*G)b=iH(qyFWZy`DzPe8XZmiw^AKh}S5dCu_qzu$E(xP0W zWMjEYdP}QGiG+loUQbiqJal&F8D;35AO99JVG?>oE%VHD(+K7}HYEM&$=4_iSL`zagtjx4RKCB?aEtIA=UTRvN$dUX#(5=*Z@BQ-jby? zpc;xBlJ>-wIdFVPPoN+p9q(kdFMTYSe;3_uz@DUhRHaTdysMs1zAvS2@NgF1hg{UQ z(g-c~Wn0#SF?yq1+e7SIxb?FjQs@d>#^WlAoiIs9amP36TQA}{kS@q@;3eQF_ve!= zr1q}o_nejO!h}&^v5OVtoz)YhYM9Zwpwub}k>9zUSPRT^aTa^lZakC^QhgZcEXwN&;0WXVq(0P>q=o`t zI&1-Nkj2bJ(B^m0tl|6eX;?ceLZ@Xf*GxJOjj`%Xz-o^lU81m$bLsFQ6J{^Wx&doe5}S<&{32}1FducM<9{BwaKgW zIEF~)8b}d*{n?c&4_$tH8W%uE1cv&iI>pZlWKWVY)LQo!g)~1Zrz;KKP0umWT8ZRK zKIVDz2+a?SbCU|uduhBiV*kL1 z^&1UEc`Lm~WB)tpA6oFoB07?-t z4waobib%0o23K+I0Spisfpfrd%e?7G*dwWKmnTO~W&_-l_0)L+QH;E!*GJ!jukH=C zJZG@p3}a-j)F5i#)v(HOdQ)KjxW*DK0!&C)7ZBw-(@c2q_|(7hUJ|)acIX;70i<@| zP8ZH#VF9N~>_DSjML#6<{a1PWsM4l}*lI5o!_6_LxsE7Z-qublE8P)Ej;(=HoXf3&+AmkzdiY=ErnF4@}Hrn1=HM-iqBtQ^!@HbZ;qx0mmj z;LO15A72ry8x8)EhNPakr$B-ZyzViu{Jsl3xXk5CNOt_d(yoz1pua%{V}9&M_E74? z=~le)?425Wf)Yv4o3i@0*N|$tcc5NHeC>A#8)}^z8RK|=SD=)@ZXTvhiskyQ^qbt} zD}kfCv^)6mx^Tj&2C;&lp@0`1=6;JOkRCXK7lxfT3&XQlfk0#lV-AvoowU;^)^g+S z5OgNxm)h({L_)cpZ%{<3&o=(AdZqZ^PJ{m(lO3^{eZ$xBPykWkc=7MTzBi z*T3@G^Hn9ELwXq(|GUCuogGE8koAUJ@E>+$`NvaViXP}>@3)59gsNKBT~*ajTZGB$ zvC^@6Z05a6=s-*KN6}3RwBHAxJ=Cl14L-M6&oC9OE4+AUdgg|$7CFoy1VR3-p5zlW zqhepmtf|6G!=*Q!Px^@2r)ze0(*Vr1N~!g?sKJrZ4w;OAh=Kv} z!wEAuRpu*B9<0jPc4ZRV{H(5@-~FW0nhQ&`%p%>4 zb*9X^ibm8q+pbpB!t&gT&qP*`(UZ?Z@4DC|4@APdyu}X)0n%JMiA?UWhi-Hn4~UNy ze?sp?D$zV1Xj83b+pZmD7dPdK-fJ$@%x61*9p)-#+!8Ns!m(a2N_}_8ZP!W2es;+0 ztGy^GrRNa(3m=FkNZdE$>p~i5P|(f+%?;DSxX#WbGsN8jwzR$Blv?Y)*`0FR|Cy7D zM<|)Iaize&Gsx%PtHB&3lp(8c=Wu^s1x*Rm?8thn>LZ&K?pyn{~Ka6$QL$<;7^g_x2urxITGO zsDCUAHJP}B5mBu=|F66*j%0vYy`Lznj)x6Q+bo^PN=pT-7W2)EFIj-$rXkzThi0XY zrg!&vRQS{v)=DxE=ffAVhIJ*!A$C-HmuGY}R86N7QQX1;obIGX20Y076> zKS&kQbTzAyNaSrQg~(0y$O3C`GPwqD6-due!iN{^(y=1z%IH-^eN7z+d9lhWd(3lO zeLDSHCT;W#;%u(|=m+Y@nn=UdolD8uon?|{nV zGNg>NBAP1s;B@g7@&I50?%~UUsM}Qt^{bZf7MZxoE*DbMTHBy)^!#TPvVHGjGaF(X zerbSH8Yqv&aaK}HjkyqgSAp?HnZurvS8qWur=hlKaC?Ova3U# zqse%!N>cibvLmyjL3AQJJ?AgTzkDPHuOtb0irjSMmL0Z1J(A9(FH;wh7f9v1U~u5w znl@;UVfZAls2Jj@Efpew7qHdQ{agaJHQg8stSs2C8@X<;(OYX|Lu_3X93uE!RB)_t*e+#wVZh%KgI5J`AyY?FO983_?~21>*o@P} z5A~2vH(^~AB0~kPQlEH&d@JYtoDt4|E!bFnF2yo9iWjf{%>$A4A@f;ITUyIyK^aJ! ze48LH_9JQKkPh2Cwx8JsNzfReQp}@Ghl@hs8@Dh2m7taM*H?rv=L}C!nfTPN05M#7 zF)f@EcJkxay}$_iKRS;9k#`-PNmm#3+mTCZRkW_degHuf8vl}Sn^R8ep!eD^6R*VS zdfi;wPo0Um95)e^ysCX{wDay1`*9tB0`~xgG4~|E9;kSN;_q+0S9Iev(iiG?GglvA zX9N~X*4U>n6h7Kv4IXP{o|2R!5_0j|rYiRXXBF4YuH^K1iJ^s=tCUreC;{Y<@Ru0* zWSxrbOA^c$V+pM!#sFCDFlppQVyQ90#;;eDCuf4!WAlja+LC6}Yi zfzQlK+9J#Vmw4@nv@YVK%zIeJFJt-Z1imFQc0DgaGlNy^Ht9}v2Xf>n(dol%*uy@? z)a`~8Xtl#pB_W@c)=5+00ePVrS=2)*xZCF3KD-Je{xya#Iq%_tprLE9Pb9mOl=ON( zoGQD@kHIniv!;U=&)OJaB7cO$OMkwE((?k5z9AVFgsGC0)J)PYJ0x`7m^J&O0!12m6;oYcVOH{Q6FN8V&6hq~|Y+0VRT3)LlR zH&Py$dTDnTjL@}{dN&_bf1uia4l`c2K>l<5_J#Iy6Jb3}mz2Z4Voj{!rO>a=C6B;Z zdSJ&Z>)8g-g~%Y>H3Q#Em2$x62x3@f$1Q>r`%1ET>4Y~rtpJ1u6~Ai)Fn}bpT+zBn_j+7$&_O z76{wytL+u)%XXb`7pC>@S6XVC({krnUT`aHSa}3e%HGR?^SbGN;F=g!h0(X@&K-ko zFHM`A%%QFKymYMoFru%y@d+XPpR0M^yw0^^-Z%0=va0a!l%V;Tvq7q5dW(Dk?~Ay$MLx)1LePoa?L_H&qz1d z>R;I~kddFpx9bQtjU22nTchv;yn;_)ZaMtUGAtMN+wZXDPggLYY@2y zC3ydO<9ZgO>_p0x0pwosOi+gi{TlSnu}K0CW}pVy6|$AA|;#4q^$#{>dyaRw_0P2YhZKTe8>=#qp@*PcA9=`RJ1DhCW;N zU%Vs-z~Cx3G(AZG&HkN&K}Dj9LOGl z6|r&_R-(SDhnT$=F@M~l{Lt7%bT@dT2HI5FF5hIkOws=vOV%&yPO*FEtvTv z;h~IY(IaN2Bb5gQz-|pv?CmDD!A69^WA-JccAsEIYFNM^q610Z!~4+nCj-#&s`~># zRp}v;Q>;q24MU5~)8jtuCDkNS!`I$xLYM~aIFMx))2)^U`4S=S-d>IEGg-lxt8otg zYs33J5_!hv>QheQ#z2NdK*UWfNtI)o>^qNn8Pf=o@8qAz8Uvha#6FCsIK08zlURR#~WRzs- zi!FB*-Js+?jI1tC-pjkWb#XpL_kz+920rg2kX}H`;m3`f~|Kz$az3PzFxdLV)MN2JO6YRZfx03^Rj>-pl zXXF8C@Jv?tdRKA=}6D2t_pn!4cQyqiEp z5x%Hmzp@->gZ?0|#IxU!SQ`;P5@CGb%#gjOg_3Ulvzb+-bjO@RNa zgZ?8DJ-8kBtvkA$P04gdx``U~J@SB-PZU8@)ysyljcV**^W^Mmy3)>0ykVlDO?a3T ztK@N#N z9}8FFYaY~z9L&b(m#fVw50Paa1JyG9kXwn^j~)ZUnaa-HJaPALN*w>}BNjm9(QPqC zvNk4VX2%O}wejT&qN{wANpx_l$@$z~gsg5DsS3{zQT?KcW&dq1TG;aN#Y z-uhKU>8OKO@aUN7|6)s-zyPw3{m3&~K#>KsUiP4=)VXxrnaRD|jGzDFmm^!X{*^&{ zu819A))yXz$P~1Ejsc)Bq9NPJ z69A0FXOs)2&o&$Zs7WILk&oy}Bc*byg9EoBc)5{ujCOSm_wKm;7XWc7w_x@q+s`-e zl1X4JZxzZCxO3TzD7y`t;_s?U+`LQgx7;`BlO-6qBXLLoHD;n9(0*b+8&gVc#*c26VlV0b#5pGwyf0c0QMK>WJMN$ z7fdz958?wT?2RN2I@C9<_g>`Om(ux5gN^!hFP1w_W6&UF;>eiLq| zsnC}jIEBlf(vWaIYoyA?oaZ&?J*5Yl2IP)aSmfjF8DH%CpjCgoz1R`Lrs(|bjRO=` zb7S(#0IBmkRXDlb zqSNTj{&o?fAh|S*VlFp^y9roT_&VnEVs7Fnzfhewe=c6&=1tj3 z_De*MY>%p&RaIyMXD;-sz!aMgJ<$@{LQhtbiP*u9eO5)1zK6kH`T9EholNcmSp%z@EXp zn=%9MckhK#yP6-=?zb|j_S!W=`p5u_KCcbKN7lLUWAYlS=$$pxl8Fhu4BGq5by8#F z;(5gOdB2{PC&BdC?G99P4xz#P&?#hC&#F{^Q>*)HmAQh$AstMf56x!u9e2Ds3{s{> z^soW`=)3vYB>(FU_;&VMjCI06~$>2S=%ab&d+fIs!eGV#M9q}i? z#V#I*f9zcu9glCnj!xNjKb$(@SV%C}FKhQZ-$2eF(ZqM=Z*biy63OQLl3Bv?ub$7} z=@uPchFAM!DwL+?!RcAYBdAS2ixGkI>^_OQm4?(T&8-W!sw4qlpehBy(V7P1~N zwm4ZN5GjnTLXzS_VQR||m=26X zYx^OiVj3ZTj~@3F`57P&Mo=OIQu%FTW&ao`kf~IHbcohSc1Ad(ltK)^c!7NEr=drJM$w*_c{TGO>`gBc)$b~sqIbeqxbDFCf+t5FBWa~m8 z+yq?m((po~tUJT@#e2z1vlkSjjfEFboPB}(zS6ebkW2^CHQOQOvu8)*ILm;l0F~OY zG}er2^+9HXvF}d!>A17(UpnLuI)NrO)*_!~3X>~2%0&_WxlaOVWd$-)2R46gP!KU5 zFL?(_!!O|JnYRgFuS^#AmestWPpDHCv8 zez%utR#}}g4qKKurI7`bC4~4`&!~}$rZazoLcvp;_BAQ5i`a4Cu|`Tt^P!cNn=n$1 zgjyo&H_|K((GFjw2@Q1x?j9)e$S3`6+B%Nxmn{W#l1a8VkySs7`{){7Y(KMi9hSY< zHAH`!&UcN?G9OQKWESt>TB0*hc*4ysvl`KVc_QWuFVm+HUo;|>ck0RQ0I6qcLYjic zi(dbE)C@X}Ck(mEjH+k${SeA!0X?2Mh#QWWToDT^{Dm;@e4^a$KE4}b0j3{^s?Wvg zMKv&CJ#ibNR5?W@gAN`ziwd9|)keO`a%+k!xZg{Ym`YhG?{%(S<-uwDk!SnTE-{BT z+GvJt_Ko74zA@kx{$c`}7YBMxr2o}g`?n|d-0#i~b&5Q~q-|U+^*@(>)zh?M%1(8l%C7sPqjnwGy0#X>^8o2Hg7 z_b&3?7q9}0rxwR2Bu0QdKK#ee{WqTr-3zIc(|vzFKzY8a@E$snith~O7ui+hai6u* zF0g#2K5Wasa2_+}tZ!Kq<3;^g1#}Ot1;kr59Ei@ro_qkU$NtC|IWF1F)C}H_!PtO% zrbEY%SmX>adsX84D~>B#4`$Y)-iY={FNjDmvXiEe9e4BHg4qib4vTuf5q3#8o}Q!& zzHR7mYWw!0KPZn_Z^H(AKz{(qCH{uZ*U8;;rugvrpWE)3L4F1Y)*$nDuu1ZPb5n)! zTo2c--ZtTAl12WFLHq-DZ-n zA7kzvddkUYeMdI%4#h|bB6sOnVdPZ?cdf3tv7Y&Ex$f8aSxRs>Cl1|mppp#Dp)W~qD7e>UWck^Shc47I?NA$nDr_@p1hTTgQY=ZAT)FOexC zBQe*(?R}iQ`Uy%_$NAWh?=SW6^PK-WA4PGPuWOe83x>;-)@!AN_SYix1tQ`(Aq!4(uJ() z0HtVW?kEo4!oG~vTZTuClefCO26!{dHq*qdhCjeW_((_GBz^~fTlB-}?pt_rgX{N3 z?WKC(agHaaGU{}AfmMppSc0d+eZ>|dOC|2+dI1!Vhl1s6_xd}bMTc|VP18f+e@lv> zK2+DaeX31M!&2Fnfoyo~lt`+V)f||ueiMlZA$D+Q?m!1W%_68y``dk{z?FMFkUqpmP2f0N)-_e#LCNla(e(!|DGoF~cDqe|mwVNTv6A(}4E>}jbVZ z1$18CtutydpZ&133isSOw>M*k$IHJWcgrxA;pU+Y{FwzKU9bj||L(ReT8r-`v=|+} zdjh=j`cqWRUm|2bfYWwi3&>3B{(bXr$@>RqxFVAKhbbcc^7S*&N~?zV^y;fzh#JG} z{r=MLPd@5NDNihmGbQxLIFnyR7$1Jp*Dkcqbr>J)19vQ-nZxMV6Lz;j*g|V$)AK>{ zC&N~5M74sHw^nKlodwalof4r%0@!S(T}g8W*`jy3ZAl;1K&36&g(X!+1 zan9pM%|o|8m;lo_u(BIr%_COjPIg?+*J&C?okR#;RJXwwX)cTfelY^ZDbJ|e3PiL% z$d&p?Bwj_5)WLzVP@Bx6+)4Tcn8ViH%i&Aeb2*Cfz55c41iC5Abbc!`IGQG9TXBKA z7#w2qW%B$BZ&q0Tx~Yic403qmc&dht(l2aktbp2^hFz0(TyBXiQ+S5GSEEaGGE0mp zPOiYMDdn10`P+3I?Qqokd7x#iMCS!*_=@;rzc|OQmM&U*9@T=K6gtT`8goKSbwThv$+zbgx#{B}WEIe!o1( z{1kQ{HZkBxI+xIA)=MUHCR-2|GoWkxOH|LxX~IW$uDM%l-=ItVrh1sR-nME}KH+@+ zYTj$zY_jOLMxMjQ6;njF366Y-4dpc686n(B55)v<8O5e7D~9%}~j! z8(j8Esu5+Ii-)F2&cJ}!WuLl(O2O`08LH0P6 z4~1`L(09nKGBi7R8pB2~#eb;R_sCV)oLlY`l>a(o#WpHB_>rlwTRK+Qkkrb7);P#D zdQ^k2k`AMqcn|sg7RWhMqN2b3fC?jqU((|=%ry*ZnXKeg6t|x)4@b|z{xLhS?*{Rx z+}7zMxB8Cr&WraPe$(^aQsgJLXG!S?V^QgXYmH#e&mq5nHL`b}e~1}yG(i!&mmp)4yrK1M%J+FQaQg80l z??+{tAnPQsmK(qR9c-=;OavwZl)ye{@&6_K7%Tvr(o!2@Wu&p}&CF^5b+RT0{mOsc za~7X7J$8M&PNF)2W3dT-(=EjxsAUxhcMNn;D0~ecPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L04^f{04^f|c%?sf00007bV*G`2iyb# z3={#T5(XFm03RbsL_t(|+U=cryj?|=@4vNkGeCeqn352N06_-BC{t8uplwCMASz1h zQ?QX{>PGSTc-^o4V52-6Z9%5jv?HM13WyDe4K@-6naB7TLkJ{{2}2+u6B*X8|2X^H z?3|pv&pyMhea^YH?q}!ToU`|?T2;SVwbrUts~myaBEfiIOTpH_6bJ7UY~x@{V3(TP z7XhybUUM*8@HCa{W#Huq-U%%l$QN)2$zW5#zZjT-Y0V{pY|Sy_?_)!K_+PcIZliUj{P;HyTVz45UDTnkQQW;!%R51TzW%a5L8v1_ucS zLhl4>70f3ZEJ&ygRuY&8%QsjkI5|k`K)Hcz@EO5#Dpw*mx@H@EH1t}aEFF1k!QCZG zhXfv4%X|lv0ClVogK^^ihUamK`0Zj(Z8VHUNFlIy;2j--AM*xtcw0nokId(Qyx3piefmb?D*!S}byAvjY3%xN@A zaB7gyy#r=PWhHQ2P&LwWUcZg{zT!u)y39eEkaqKdo2hK+dcnam!Dv@W zNpLW56tH30Gn%WcAdZP(ahSBa56oY-awFU33jS7!JQ`VKu#4bq!Mu_;1{@R6)1836 z&+|5_YFP^fXSGvzgKrzWRT7{d3Fzq}O2lleC;7&tHrHti* z9cr|ZBI%?6=fRa%po{JfK!a@N8K}K*R&;RZoLwy#VNP$%pTBQP~aU;)M?n zG$H`H+>RdZLFHK91+2ao@Gt}z7()B3T;CKD0G-(Zt2`7lstZ^h=}ADW4uCFKLeKY5 z%q9tMLs@)o?nywr7XV$Zgnq*Vm?BjUr7x4uEjtOB+Knw2i zRL(a`8nEZc4}Z7P2h#mfbMA>I!>{*uk*9XQ&eIq zwsr-3@#2?9g4NF7`q5?%-U<@BVIKL^*=12r+Y!Yqy$iWp@a3GUqU+IVZpo6y~g2JJ%jlzgAvv_K!4Qy>d;>g zsOetmj9{E6FjULfr2szWdaD0BNmpSo3cJrR#8r-W@R94-3GQ<6bO8%2dwUrC4)|GL z0ia){bo~3RA|-XaxUyY=s?*g4OXzt4ExiTouN1t{@()Ez(1KN^;{r;057c)Rxb(fD zim(4k1+8%YDLI=3>J4uPf^7w>3joCNp6WkR@OFo#^NKhhV4xnA(qHeS8_eJdpVCb* zrNeH#zYD17eFO0x>zsuCa0&IlyF+09SwKa9s2>9cvpWEY>q@Hsj@G`KG*7U8SP|?K zNiCSzrao;3ldL=*zSlS#N9%V4;@LpljRFFeYnd87- zs!>q_4LvYde;+JZT9tMNORYN+ou}3N;u;D4(a@WL>Pf#}$DV}mcl#iWLuCKMLP&F< zEU*~7-+E*4jjjcGpg@^Yum?aLC{Un4fdT~z^KT&k;deIn22M$ zwZK|A{CXLVS-^|HL%?H*IXK?Hg$k0VXQ=~!Y~XC{#c#AlzPwV_&v)J z|BfZjLJ15m#dz5WpR%Qy_L2yCZH%fUUCt&I54c zC5+EvY#2HvP_ybp70ibs79du81#p_ouKc?kD?cPOSnt+TfIbj$yJtDv?9Z!+kM|cy zbUfIE?gxu513R(@+LH|s|J>z3PReZ8CqUj1^vgI1@47Cp^G=B<-D|*1Nz3bH>7Jh*q?Wou5A2s4*)p%vj`*VeUFE}m$Gr? z>F(51H7$Mjn_X6ZosCh5`+E$`LY>d+>=_uNz;0`>8>@>FG7hRn&nF~vy=x9=bXi~? zk9ecb!bf*&&K92y-jmWx0cnm&&Q> zpeJ;(uHQ&vZ&~zU+W@hmC*^YG-wk_D)exZdK<~Dg-~7&UjVd$7H<(6(=RE->BK=79sxcGge5W*PhWo`tgFQ)aE#Br|}n=|DE!rC`JS zH-PqSKee?9^hjrC8F79O>&-$O)T4UyC$qg7O-T{>|h#VW83JOcV}3OM3s|90DT1mg7`mdu7~cD(css2?l<5ZC%K5N%{J zr|H>jP}B~f|Jc*gS$wNUjleStIA$?U3S}F4sQ*m`9uxVER*k_!dRT8Z#QcsL$9_En z3z}PqXzH3(Fc0I4tNWn(wSDumOmBNNggCiJ4Z$mmKd#(9Qs7{m@8P)hpEp~#Gke(I zER1`5P|W~ra%T;}R6xH|5D$lYs=q)}n{a*dTo0=n!q}@vb?3_pmTbwzmTwnO|F`_q zUjp5e&%hN^y8_CVp~2TrZ&3Z;ojnTX5gx%{phaNAJE&@0=&}CQYn@P2R|n8bfb~mv z!#b7%w;}GtF%x(j7y(S8a^%A2fh}vETMUdPVr38N&X)qGdoJ`Ya0j;!=!kd`WjHvW z+uD8yZd!&fpFK*9Qx?XXi0>ly&DoaY5nn~z8^7nfy}5`2U@sQv*~nUf+q->0>#h={ zb2WZ?<8)V61x#hYc{$>TZMN$)dX}_(IbhHd(3jh+y951oC0@iks0DU(mar&8OMV)$ zB}1C*mJ-15|3PCrw{obF#jI{Nylzhe^E8jfV6~*n81keIVmFj|l*~65=!d?d1SvhD zUVX0fETMnWdnN3-t@7cI1Nan$YKii+)Y_mXx z?f^+hNRR4=-Bf3hij^K!jZK1N9t6Q{{v?_9^Jo|BT%+a`c|Bb_u=et(IUf~3yjI8i zQZ@digu(hfPrNOznH~5iPjK$Rtx$!6d4flO?IiyVZ^J;omczG(>Y)b-&>CooeQ^c1tOFbu1Q4%9Q;I+4#sPe(L>|BI z$CafIRse0RAGc}IE&J<$-*sq54`nO>H={iNXmmfgcRkE@yHq8#uOk|+4ftJ$##Qvc zLg_iY$g51c%R?EHD}Z+R+6g=-7=!E3sN$p3^kx_Ed0*icTIE_f_>GM{@VT&wj$U58vE;Vy0ztBehce!+02&s1VrsWiJx9Xf@F6K)Z{psf zbxQ|KNEnD^HNKBznKP>@hc7^XqGTy?Y~e;&1vAZf6?}LgcC3VqmL*NJF|f0Tf}W@X zdbuYLM7gK7itl(4QjRB^sMKs9j6oHwhyPd${p$< zeAMDy9mD-b+YRnsdBRgn^yI1z4RD7C=_RT`GCte2A{@TpsSh7-@`1ZONG}&hh8^uU z+Rg#`Ft8iNGr1C&mF$R}J?e`82^z(dSS2{SBdVRaaWG4C&zvEyZ}`t`X9C^Z zIYUuD_qc;Sd7Y63hHsac5BhA3&DT-K@=NAVBNmkaW<$(wZ$K&nttcnip;mxSk5}}X zmB^z(Cnp9-8QD{JuHW#Lbh^8jd{EF5j2~f)LK)k34dU+y5N9CXE;UKJ(Se*7?HnQ8 zvFrLcLCi3)sH(qJ8$8Z58iBR}yRr-F`$m1Q!`i@p2{EzUEof8@Epp7GvPShwD`4ea#29AW$A$%mKIkniB-7e(2iUBBtZK_@wju zt?PNRyQ5J-T-LdDiox@^L*~E6xVW$$gk6e`dJ>Kwg?4L5kK)*;bK^q}+&iF+x@Q9F zN&)>6MBC((fNR=!Ca_azyj1k9L~KaZ>Cjv41$s09I!guBpF?z8y&IxbF9LifOn;eE z-c<#F8E}u)8ajd2YWLY`U~a67ieDvw9cT@`jw|w97#mYjJp$E?_7$MbAxcdx7Bvv= zpQYly2~v7(L-3eli-{Hje-&oPTH&h;v%s7!p$E@Xa3s)*(Q z+lD3wUO4vTtZPHo1M8vkmf_bfm9|rCXDhnAyS)?ojO$4`~Q8Tz4 zV6IB)#}V%zvdt=%0+WcEN>k8@f_H^xHs1E7S7SUx^KvO`x$h8DaJqhp0a7fDk&3bc5L>&gl~w{SfM=z~NN7?DjfdgtD$jK-1QBm-U*!sMP%c#O;X1btI*apVf$G zFiz>|_H3;a-VeG1^loCh_oY@W2Hg*KU|%g_CRQ0oA^r!({6c|k31!E)6tM|56p#J1 zq>ptt=wQ%;aRT(BvM~uXud?CSM)}r{U5P;74LATe1~?G0=~^|?U>rr(J8JJ)g7_nj zKOm+P@fd*;psqHRjRB?t`-A%s@Ilb1HsEn5a6j-M=mCgcDT_T0mY?zgCLp}oBiev6t!YLfZ+)M|I1`ech1lx{O@`H>5#(|c` zaoNKv3EFuc+`Yg|aIersjo!V{%@yxMl#swt+z*C}6^bZqPwJd%5=MWZK!E}U3KS?% zpg@5F1qu`>P@q78$|o}`^!`AB+NGu!RwSJ*X<38YBIn$l&bh}D&*5CiCswvVilV6Y zvoDb2hzaN1bI!T{>~#6wNYa3r{gtFEBt5Mb$jl^ZuB2-veNEEvAi2HwWA*naGy8Ph z7x$}0GP9>8T`B29wS6gR&jyc=?gTF}uIl2gu8JV(Z<6<^Lljr!gaB%PV3ssY(h2G; zS=^uBsUw9`F=J*2w%hM!c0@+K9;nv{zsjmq2LLTI`(c2aH&8#SV(C9?%DXV5|F7x* zKksJL<i5fP%6=xJn9sK{KtGjLKd8hSS1a)`h=c6wwvSxJ*mbu`n&q4u zkaRWhY-|OOk#t((@6S2sDi79oZ%i!R^6hWR5*Pwp?0LGVYOFiw&aM6poSN`{oR;RH za?S}j&CI?QMbYv^**n$qqDeXi_(e-DIp>Z^0jG1$U0nO&k26N-{bsg*3sT|`Nq1+A z?4JkR6{2cv(LfkqVP+HSxz$qMH%!v`4c<8^asLN0Bzj9Ji6uo1W|ysMEB$cB{bO6T zvdwJI^g37w&@V>anA$*f7}4T;mt_EIYVDMsaqmVg4AL)Vyl-apzT{j#CWVPVIOi6$ zI7JXe(Tw!39cDHvK(OO}=Z(^)X5a_TxfLzG`@)RA-lXQ_T0 z)&um8DKA>qfp&g5qoNZ64A%l`i4B*$pc*IXea^Y#fKy1{Y-hmblCE{mJ?5NS*xTM+&Oo7{P)I^ zJ|^iB=iFv>?)?pLlBC7Xxs@5kZJ7qND2i@xrz7)(FT^wN3-P_RyK!CYEZ9lXvyB`A zQ4}HRaA0%>PY>08xKD;b`0;jEcO-o?W4Ur#4WK8b)MHNk{V8Vlj+rUG8o8A2khEDN zi6UteNzX}I-GU2piJ4s~X?U6h%i!y#`1_O1Y-N?N20G}gX0~HSS^tr1X}I}*oMvV} zl5~0PWoA?A-2YGp5C5}?au;MY$9eT0_;$tvM|5B+{bmMZN7US#*6}w>I42P(&~1Xf+anaF?FW#^=nE0&}^82nXNLjJyY7db+6UW2CC zH`%XMdB3Wa3O6%Tb>JO409VKAgG7u*? zCgZ-zwf9Jx9_!~%HW)Ml&X6>&wv!~C3XG%vB0$wM@T8=F1+K}eV?5XnZ?btN*8$8M zz-0~ia=;Wxd#4T5I`vzCe|k7$P@a=x5Pdm=|3?ywIr(&4Ne6TY)a|MqRl3&9wo57F zi1_=ovOZSZ*=9B;rJRQ)?UupM;gaU3JUhM#m7_|JtP@%3N^n3}P zo6|D-{!clcUy)%S9ny-?HmMr`9oO%@EWdR^axX}E$8T%y-yyADd8YDuD`K%xcW#q_ zUTkIqS>;Lk+q6FFWq``qXtn6b)39OY2TCHF{n(WU|ipOKQqW zbA8RNx{R{w8AZ{<_3G=K+r3GCw~3-?Ra$wmE_rd023%1TMbW%8*Kb_UQ!^evCPRgM zq$dE~!1%a0=R3ZiqI-U(=Ds~sUNIwYJ)LvU)zPDmZi3(0jda^)4YG{;SC`bMzsRsT zF3NcB&ocDq8|r;A;7RHZbf{tG=Dc-eP7tJZ@Q5asBuOGE~xqV>Wo)TPc17)gLlFxTt9CEXT;q;*91tePSI`i zzG4KhSbUVTri;d2ylWJbusIca6(kNWS}<%oU$d9 zq#c}dvr96nF9D7y==~P~tLl9IcoaofWXu>>npxWSJJi&FtE?HxIX5@0f2)8VC>j81 z(_pL@=9w<7-SV1HIbH^CYm?=Lo(<-~dm7m+ZSE5Kq@=CtlzRhkMFRtRF0gG%ozHg8 zogW7_9hJhXB)KSxUTS2}`~>(vDff)+Kws>W(HYD0bXsypL=G_T*QV5d#5s3Dw|Rh? z(2ZRN*uUVMyQ;l$RUd3Q>OUPgvCi`XJ_?*47jSIK^UgVUVy3GjDD^u@F+ zKJ(fZO_bMejP-DOo93krh}fghvi>e@XhUum^$NxQaL|C@odx@{Bp@3ag) zAC0{xjRBpul<1suW_Ds5Ol0NXc(j>LlXPxQ-S6-eFUQq2@0*d~<;V*jOT=a?5zjof z(|~Tm2AGpEAU2S+cZ=oToY6lsbH48KjM?L-&bc$Gztsxhj%Fn3^$mh&&X+V%(#SZF zeR$FhV`d~iA1P_Hnfn7*ikvS#h^T4D$ zR+^-vC0(Ckz*WC^HJ+*80p3mssjZxI1M$1Y=a@a;7e&#tIr+$vNGt2vFp?gKqNriy z=Rl%S9+b2g*r0*cJcczp#K+~(>*@xrJLjIQ*GM_u_mQ|keoy5D)0fR`59i!&z=z`u zm$k`l6!-f>b;|n^@Y6bVSRZ&r(v!f;u_RqoTUMRH;No|d=H-a*yTQy>rWm-cjsZO` zt^FGSxf*BPjL-dXNmEkZJ3K{Qy0Tg0El)bsjwNk0v+-%}xs=D|wYp6zp2}{?u-q4R zD4(BIZIN2z)wjwK^L1U(T^awL+T_6eU<>;;w{6N57DW-xxfznqiWT(2Vi28kM@Lcg zT9by)yOO4~Ak_pcs^@-8gqt2mXSRtsNyj#_#EbTFB<}wt@T(@>qs_Ff1ODAPcW>Tp zV6jBM2gnj0d3&4K0vCwNZLKOX8(nlmc)1)^cS=KX>_Kl)wdQpO)*?Pro|Cf^f7cirfGAeGX zOPzC{Yi0l^Rt;y7f4}B6oviq$%gL??}w^mnle zQm^b4@%E^xd41Oj_2XzskHz)R!{g5-ZQrOIN!!Ku*IvJAa?q^vjwYU8KW?|za`KnF zmc`FpQ02ExTuqDnb$NqJdHWEWkKNrQHkKOED(Bq%I?_Lno|xthc)>ZheNBCa#YRmn zw@aLJ?=(|x3cp*D9>BE@k7ZG-Jl2cJNShs#>9ztj*T|E)Wj|b?-lLG1IZyy}pg;l8 xfdU0U2MQDb9Vh@gP@n+lK!F0F0|hFQ{u_Mq*HaEZKl=ax002ovPDHLkV1g9q#mfKy diff --git a/doc/opencv-logo.png b/doc/opencv-logo.png index 76cc29f6dcae7068f6996cddc3e7546948c04e42..3ed6a233bb0bc922052a8967786370fb3a92c184 100644 GIT binary patch literal 36328 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 literal 17775 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 Sun9&0OIH)5QLASA_J07=@!h`w literal 24903 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%0AvpJ zIUyn>m-ihXUb+L#eEf*x@R?0X`ZfWuH^Rq{0vDe-m}Gb#03$aDv38$E?%#=YwXq#Q z$q=~)i@d!9J2tjADd{3@ztKOs59s)6VrGOg%h7Sav1jIB+M!mx($E71p?Pe64YaH=WKwbDEWO= zbX65ajqo_jFdD7x9BKa!)Bu`Riy8I>q6`U~a$nYPf7DZB@EpkjVn;Ofcu$!7+8B6G zzi$0;WEYovo&*T^y33PMZ5e;Ga!Vl7;?=XK&%V(x;s7>kjy}OwV#62tYpmW26s?RQnD-J$0P?fVfR6>+~W0eh+YqpMy?#gZ=amizOT+3lh3JkHGDB=sl(1 zzJzgN?$3NIg#R&_9uFx9;{mQ=KvSYcNwDeq%;l$F7_+~cIyZG0a9L@lZF zCFA;N=|5+QckL(f<=2Dr0fBoraW|b3quHi14JVG9aRSWZh5%C+4gNGHS;n2H_lv-# z^Xos}A_5e|o$;ItUptUIta9qM+;K)yYKj^V%aA)$pA^+V z-RL7T(>+WA~#^i%Q9(ev73v_2`k*u}-m;B3dCgQ&JuFsQPi zKM6Vlp9ud*@vp9DG6#nA-pr6%4q^yZUN{mTEtV-7yUMARDm$c4_VBc(dNnj zy=nC27NH}WdA(S_loYn<+E^+?qdZk(bdyp8C_tZ&yMgQeY#Wi=Atj5U#q&G%l{CnF z%6nCvFKfQ8_nP^-hU>k|IZdBV906r9pRCkJTU+HzeFnw~i?Ofv zk^FuqaaXIEjv)Gze`Bfg?dCh<$KxuN|547O8|)H;$#(o0E_Nyvx^Lb*70krsOjTuL;(iR9XuBmJDR`%m5 zQ{5DgXEEB}67CvWZR0fNvo2#dZoHVgDv{zxhe!cbeYq4Pic|wvy@fZGzKl)fh;>J8 z{MXpJ@u5;b&snk5>Kj5$N7&!A^$?Jup6UY;7u_>j`Il{fFQ4QPJn-PT3#oZZJH&}9o~h50WJE^k@%w!k zOo1R189L}9I`|yqGPOq2E}i=iHE7w$rjJc$ARkC-$AJ=nMH{SjYw3{pFr3&^)AUTi_Dv3xdG^G4@|KR4@Wsu;%q$Ve zx43(_grqwbI4%d1TLZKz@9s>DZ~SYogj8bL=5K~cOlC37PF`#?z>qmKsv|4fHY0P& z$eoz!l{@O708W+zcn{XB?cmVjRwepDPinY&-K-~;=^Zu*ckfA}As3&53e>lif_L3s z<~y)BVSO8PL&B4zGjdC}hCh(xI&wc1E2agwP8s~VQC=P$Hxph}jL~^l-EH`p5b%L5 z9#1iY-r#!1eDS$o#9Jt$t$Tp|zS6WcQ8voJQbap{*QWmL?w8rZ0njU4-aK5cmIqIA z4r+P^xAvZdNjKplu5>kSRAa!Sod42>uK9n0{R%BnZB(@# z8mwP_yvj1ZbD>JYpBir{+i9|NL~^9~aJv2_wA}}2e$@Xf+_SxQHvUes>ra)Ti-SCaGlH&CAivKxJU@oCs0OLKagCkO#d7S_7>F0u z?^NqJ=QKhby`SfrDF$s*leLkz2l-EV?mGGS zclmEI`TGjHp7U$_IQvQJnZM!C0}23{Na+@H=DH~M`ZO<#5XZ^OONM|tj+x6KqI#Si zmx28LF#H@uxi>Vv5T^&auiy!uhPQF^L3R-lAG>!a0Oz+{TW)1++^n*B2;^s9AUO+5 zcW%U(*Nb7<4$QQ!<61z3!^yQ24gi^`y`9jG9P+u6l3F?Xrs;J_=PqLkC7Bgxr^ao{ zLLp77FMm)`Za~iK_sE;jay@?`lMsZH%g0VqkewX#Qg0&d8$#2Z`rG52*T@w|&{^Kq z_jWxKy3x0J)1aGc^p!^~x;5_8g{Yf+1-Ioo?oB@pA%o^U5()3*QbmJr8o$IfNp@2= zGjnVdKkXF#>a1YS!Ux5{^e6tn>62rya>x-Qp^snh2#LyOq6k9s+&QWWUe85r;V8De z>P)u_5aB+9Wa@_;{f8hcIrew+Ow7s~8((7bXFd(pe&_fqb;nhDAoW-V&1?+`2E&ru zm)~2!Nn%yS^S_=0C3nj=#fTEQlyPMTU?3AE<;9nE=$Kpb(XoI z`w5}4uia^uZoyICxN0s#0dYh^Qpx3jgIP%<3eSclrFcs#MoM=Nh2T;2dk-9hY042P z!W8oZ$M8PtgHFIH(lq_eOosvXQgc8oR}eksp| z!T*vsOA|XfR70xuqdodeZ%F=Tg>h; z{nxso3OLG6-u$D{8s~$)Oo()dgkPGF+1kw9z#Q$=d=mZUJ%uivW`gY79We$K!KKy< zRKSZgyR8oyt@Hk>(-In6F8l7#-0w80Tz5y%JZJIAe?WnKM0qSjvnw}QOnXn0)`kBR zI0$auyEDi6pq~JdR+PGD$}sc12y}HunYlKwjMEG2%rF}Z4%S+d0kHx5Y3`+~O=kYw z=*{^N75zq5M!6bT^Bbb_wt&TFzsF_Ycm?kOZS{?==PrQWJQ zP~#Vofoo15_K;csV4T5h8I5+8kvAz%m9cH?dJ{TW=ft^rxJ*eOPn-gizgQw*GI90~ zn8nyrp8GMLmxD{bm`cVIzktpW_`?H*$~el!GIv|3THRuyAHEN&DDJP{@ViO`VbrOE zKi$JOk4;na)XeBhX;CdT#@nbL&<%(LyrY8XLhxf~Uk~XMRB|yu@ha+23`&@e1v0t? z)h$PU7YyEtgPlQSex(J2ZaE4777{1?!Jxg4=pQ&tFuf&1PpmT+ZVD6Bk@oc&FnWrz z>50Q~0deGcAkSZRo1c+@QXlNwo}fLf!aJ&m;||_t-5uKb0@@J3xTp;}#g`s*=*zYMIAu?&^hqUPSLFzbi6I(Hh9AG&}N4 zduVE;T+a664BD%L#ZUG+|9gsFa9)Er!|*gm%0a+o!}kX6_}gswhg$I<4GLB$%3SgLCuV|v@Dza(gsV@|rioL% zlaTfo0~#nYM^?Rm5I$NHXuC0mj?_?hisZhfMinn1<=KrXG;S=Dpk*(%*z(+*Ld$HY z>I=z5x32inza=laEWHvKioY;#={oZSlNo*>V?Wa{JTMJOzvapc z(`cVmYPP}#B0(8PGI<(6W^0J1Sa4{LM*e)N9!gI zU?4M+O04$?n&6sGswE&()X0`?U4hL$e9AmwLlwziLn7 zAY~#&3q6}RepkJIw?#6?+M2fvg5oPoA92sE$s4WteYvrFyNDn4#WzAj)4xf=cNHV0h^j7fpwyj;c6td8WJ3n<+J1n<`y6=5Y(y%}x z)<1g{p^CW90YZLx(*c?UfoZ?2Iy3R39N!YTcl))3X*LiH5B=p=lvNwAQSF2-gxOrL;;;LiC zD~HA`wdIt(WzFHE4z_~O)#MV;q$fk{)XNM0K9eY(v^O28XIYnC6dH?lyvpi)mA`Rf z)c85ey~dR^)#?y?K;HQV?r8o+d{h|}NK|Dn+*a=Oi3+C( zaP_XQ?N!b_&=T0PzgOC=Vc1R))-xh){prmml3ShOw#xUBbs=IJ69=?T{@3Wf3Ri^I z$2z}2dNa@eh=}hatw~8sWA1kRsaR!-3_rY91!CJ}Z3D>2%;vA^b!HZ(| zMJs;Q7PW{WnY3gbEqlUQy~;NLLIg@>J?Cv)i-q2@y>tm*!?b>TQ|by8GvaXP+B@gH z1pE=0A1F8@BX_j!u9kU()THCrU7v}(v#{%Ud~6aAN#4-P>T^#M+4=|;j1KW>xRmj` zGljRDUj|~Fd;~YSmWN9cyA6PwFZ^ScTp}B`I4r{H1etPoQDjRQECy)mSPqi&3T_X$ zTBI!lk?1dUd+vv@s4%VskbKk5TC!U2^DtluBXYwn5z{-I7d{&iXBHzu=N({W%Wv~5#JfD#ZNK)hfF7PSUz5 z2)K+yF7CHjDj+u0Dj;g`dg}m?K^U76o`3VOq;Aww_a*hnK>!*IGOKu>t3z;-mQCTp zn2{7LJEoX#hB}s&6LLo|Jh~Ll(&gO!qxl*WPCPD(=?)D0mki9F4oZM3O+(X42GDo2 z$I~?yJtxF*>C*LQVKQ={$>%AP?1?Zzg74L#TYf2%6JRUtc%C@#%8#>RA1X{gX^lE- zT%Y80hjYDGupAeA!z^Rm8FF3f(9LwWgjr62Yt{``q}Oo7PQxj%yeZ}nALcVvBI2KBsX>B<$z{Q*@?4w9+oSi=#CA^JroVtBdMDARm*feIxIi#=$)brC`Rw-xr zVlAvBTJB-0_ZWZlXO}G)5tyh%SN!|WP}}>@_K(-ctC@^RWY!-Dr(CM~bV@<8R_cP>mb>v3;Ap z-FHK*aPe}k8%lMRW#?qXhu4z!q~xn*&y}~Wbw*9zY^7dM*cJV$wz$6|`5WPgl;!0g zZ`?K@{8P}nS!BEaIR2eW)-qFo9`@2KvaSZig>mRj{-M|N_nsm!g%aic+J*C8c`^OM zZQr8;pya1Ma>(@J4BbNJ7T4uI+zJM$a@AKax5OP!do4h@Kp^5}Ofrx$Ou=THDUirk zU}Z*rdz8HDbd)9fb)QG>@>v|MGKeZ=+}y3}-ns!XA?_mLL;r{PKhXaPdKDO*H4t6wQpp8n!x*U6@Mqp|b?P~03VL%NKmY)! zYiK4?Ia)Y#mqrCmLQYTwOX-DDc9Qa)Y&g~T{mr?g;%xU(2XPFu+$Zew{C zlgrrQ%1vI~_H))eXCWoXfC}3F_i`j9L5%RQ7&(C?WZAvRbMba3kOX_{KeFsA&pKYN zXOlX8uTl$BE^D__ZT|+qY(MJ0bP!qfH2L5e(XmFP#N=s;`{2M8wc*&I(oVZJY0B6laB=bhKu`7LQ%_`^0!=jU&rJkfY<>PT3 zx`!aZ9FRJk#PETr*uvm^Bpq8QAXL>M6O%v%Ft5eDlJ#`#tyNQM0n#!eP<0#+3A{{> z>i~Y7;=$ckM}`mYrGxJ}%|ky-pp|TmXgS;M0f0JdUs~d!X^y+lY3*5RCaL$-VcdW| zbM{kb3(HD^PBIUGI%LTwTFbGqA-$b_`s@)UshdJ|hzK#aOS1Wz>Eq#Jy_J<~@C{*+ zMgw3`FsI^$CYEPUWdugpt(f9i?p*>Zscy_f$8DeX3CIorc zDm%n#8Pv4k3=d%OZ;dL`!G10yKr89O2S&#uTHk0|wv3`PP#LwvZ;`O)Kj;TL*44kw zJTQ1U*=+Iy^-iR_;%Z=`DdtM}yxhq0p4SNaXVueGj?grb5D)388P&iTonK>N>S5Tj zwSp|i;(DJzKUnkeYeb~{%j@5CL&lXW8;wAIjPki&48S&oSOvjdNMNIQnhW;vj1V6x z9J?Rs|2QnIyr$z@qkr3p=r`07ul}{_3cnho+={B#ltkgxvE#K`(X1^wpq+VRW1$7T zvvoqwg|Hd*cL)R&M(5+8AhD*9s(Y5AqN3hKYI>iD7EQDx18i_W<`_p@q32F!QwSMcJj7s(BO zljsFs?y4evV_5{5WdS8mfgW>#f;-Ff9je8yNw$Si0cdMMT`rvOqZXw{W%9Cc6iMW3 z3&S;)CfmUCW`Lt478-XqH?zBc)&oi3T6-5+h?(iBd@+z01j?^goV_6)=|J+9$hjOX z$kzXvXtLm!54I6+xzi=6B04XxJ3?H7-g7bWjrq*hYldLD?I(4yd47IUKb! z9d8$ySr_BreDU^n@P184>ya!yD6Y{~bTy34dg@|1(+GMLt)p1}Iz42ntQT1xv$wIS ztB*;Ya2$WxyQ7Km=_OU#*S0VqRATk8n%K8eZ?d^4bZG9Z*0@m)A7dV-z(DK|BT|Or zV`@4K_THUqtFj6IeE9%MlUjV)8I*$7Ph;)r%U>2v=NBPPP&5wnaP!F39SGJC$0$DW@Qe01XzmO`IZtKM2|7acX~`v9qj#u z93yBYZ+wU|l!Lk#E(M)RKKM=t%08u;mbw~zh!h}aS7A^bwR`rKl{dm|VRw~+!#1n5 zh5*ebq04+kw8&m$`CvZ}^h4o@_nlf5+u4^Tj(183tZ!V?^&LwH|NWuVS1$Ef2we!q z8dVS&IBuNlRV88YYk%vW*)rh1*TwFce`M12aJlOpU;ULKxx~qXp)*aNtX?=43Cd0c z4!*6;5i!5N=01L~)0&arzw(X#))(a6CT-=Tq1i?SJ~-<2F=tX}-A|kCSWWEb9R!k! zGmUuE^TVCo;I&W<5lfRLU!B?VVkmOGnUOVx%=4CjNuu;@9(Wa8IF!vt*z27hchmg( zopdMc9q;;A7uiAVG%3KO*xl;7Q@CS0Tc-0)=4un#alxT-M@Mne?qz0se?#5!i0d!- z9XLwnS}o_6AIqaN?O0E|^+E~P#pyYaHU{rLC-Ov4yI4zn$5e`SK~u5!k{uNH4vH)P zp;i%cu}W)+{A&D}e8K8$Cee14qcVv*fwbQ*)GztN#iGYlomNyt9c}_gJ>Y_ww|Ho^ zg$dvI8|gjEAJ|~R0h%=W(8CgS)O%{0{LK63YiXs+zW20dx?f$)E?N9MG7BAuwCiOH zPUL!LpJx66sDVK7{y5@1Jg9sz30n8$m?qajwuUK6RDP;^TkcAw&<`oW$+J#1MW0lL2t>acaQ zf;aUnQC*;Zlryj+^$IFVZ~7DB<3ydy7gmQ-!S6E~4D3DgB;~@{jfk{|iz+2TsxdZh zzHmcFwKNa@^p_XRsOvh53E$4zRSHo-oh6G(sn^_Z>ip$F{PH6bd^Ceajas@_Pg~xug ztXeYl&95S8sTgwOMYbT{3lqlC?|<18(2C}sL>`yxo&jfLp5BNLyV*TuLaUx2JQq^Y zUf=INXYs-6*=VAC({PV{il_)dKK2FSPC(7tA=@6R${}4YY>_5!!pJ&TCb^L!P{w*&#=bHaM u@!voHt>NGD|FgnBl=b{EMAqQb|Cg$ux{m^y)P8nOS#>lGH0spQG5-a{tnIh} diff --git a/doc/opencv.ico b/doc/opencv.ico index 38f033f3b0fdd143b6e41d8fce42e586ca979938..c4d2cfd4716fed42bf37d104a0ebaa4600462204 100644 GIT binary patch literal 4286 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 GS@<7@3)vU| literal 4553 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 diff --git a/samples/data/opencv-logo-white.png b/samples/data/opencv-logo-white.png index 3c7098459e04c5d2a3fed7cb883ce985a55456f0..a683e3569f91731c86ae6598963125ff0b8e1799 100644 GIT binary patch literal 9760 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 diff --git a/samples/data/opencv-logo.png b/samples/data/opencv-logo.png index bc71a2ae503afd068b568d6e39d05f14474beb4e..995bdc0fa6059aa564e3169d9c3a1dc3d38094ab 100644 GIT binary patch literal 40104 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

AIXnZtP-{@Fk{m<#3+EaX6|&Apn6E2 zZzac&Of9=Kdv3xcLT*L0NAxM<%wt(FMHsEO&G)h~2PLvlg}j!r+o+aQsf*xbc=t21 zxphKWvQIK;AhKF}Y8TAdG;;4qoF)vh_AGHV>K^%Hgp*fYjOFHit?Ad2wALsuu^f?+6*Ru|3aNxP1>KsIDRU6>Us ze2c7`=cd^$Ks#y4pPb{Z8ruoxP17fEJJR5e|MdI#Lyg`R}2rckcr10nper(6}F1yBi z$Jk^W7G%8mu-8A9QtkX}1^3MPx<9GkyG)b<03T#S&gsvurQ(}vj~zeelv>la;oUc1 zcEz&kn~^hzR>z0LfVc@y8@1S|zd;az`cu0OQA${`S6dfrw28D`-X5PoKF^J(LX<#o z(J1vPrh$!kVf$3uLUWzY>-OKXExg&wW(9^%Lr?g%r1I(o_|hl=W&;JOL(@4qMYA}_ zhX>Ijysuf)^Cahryf54gAwHNQ*ApLEHv_ zEQ#wXqZNMnOAjWxp3|^Tc>Z1SN$ED&6eaXnBPoEDC!m3B7AEbwz^x~qlzzWwb18VWv;Z^vf!b`fL_)@uy|X)1ptOr3Xgui zOI&=<=ZrYCN99)O%}82}-l>@R-d0=r$nl@z)anEGkcTl`{IVg1$zVPsB~0Xf)oZ<2 zYJ%ro4%tdx3vH~cNTYk>RrDj2qtSCC#NF496aYk`@Q6dp@WRik+`X(x_Dpd#oXS7S z)MNSf(v%6;Yq9(YZ9pd{$L?`ZTNg_-Ttq6yF$YDFyl%jk`{-PEhCe|+J?y6V5qE`? z;#o2)Hvo(od-o5{_UC&b$_$&t+sdHN6e*L~*bnNO0=*d(r-=n02J1JxE>{T#zcPxy z00>o#A*85PSA!LL&G5DXijN>|sG-$`^D#;V-GO_0jK`PG9o*YAqisRTs&)#UFMmJc zD@oT%fpSh1IBFHtmW9cml-8ycTm+2t_2{bog07uHMzC&XQ|$6Qnpk^|8{jS*T);N{WEbaG77MCFCzqkx>zpL?Az>7vUeEfKdp{FN>piivE<3X7X1{L z_{-o{$+K21JL-w7;rJ&=&h0@r zJbmQVkD%+P>Qt?@18=x_0vF@QIl#P#4I}mG$R?k6<`ej7_|CL-GiyN0LTZ!wLxQ$l zrnmppr+fhD4s4?)75WZK6dh2*5&p}mT{!#f%el&GgA;QaN=G8yWeY56U?GmWz8@Xz zt;dwq^vl$pg(HEzK$<@#s;F?NtRt6F+?em~5NLU?UK0~=E58oIUi#jRXI-Shb)t9? za6W2=eJRM!4&qB6+EmUXQw=QmiAg*+(}i7S5jWBPK97hsP^g^VVY<2`Dr_?6-_*nr zQ4Ra*tdrZXy$`c^epUvEpNnZlLS9s?(Z9wHbHhAia1azZZOtVb55- z^ZdzM*ITA%X(SU#(6+J_a*+)Ty<7#28zCmawqrhb^gW`CzXwHt=_jS++;?f;X2~47 zN9U;K)~*W0HKIW+6SbQSPOWFMiD3LS_yv zy>ct9_;Wx@)!WZ6n5n;R8Kf@4>S@lB)4@GAZU!;;1D#vd-ex9m`l^X_ zslM$-yNHRBxrS9U|x4N(Yn091|+X8Gs z&!CEYLkkkPgfogRXqCnxd;c=T0IAlUDU5YZeZ1b4Elty{s z&$f=sHnJRPSVudQ^c*$A`@%aCMM>oK9fVd}jDqGm2$5O|>WG(2xD#?cMrZ=^JFq1! zt&+whrM3K9Uq0!R^wghRoQ&e_y`dZ-0Dw$-o=9%WYQJNSem_JR!8F0nxTg1d)}vu2 ztJSIK1)r8^Z93;M?Oj^;uM~igA8pIOyX$;!aySp$QRHyZD_{SKzHN{qN};?TP$6f3 z;fk;LH96DK+rjIFWIq*xtc*1)eP9yrb5-{l-@MWItw74x`VK?E0Q=b|1@|opf*6iC zIV-}&2qpmC+YAal)%5D^#Bl!#X?N4a-%JcScD{AheYWCX9@L^#J?(6Kqwng19lrMb zPW`0D5GcILwv}6!%f&>im{R{F%{hrT8Uzh+346qeczuxEL2Lz!AXlo5!ok}|7l61Y z5<{weLMQpe_jY?vvPx_E0lisOKN4+Qz84&uxlS5U>-jUhYTbf5+i5&z_8ET{-Qt5!@ z!OHa1IxlBfKwWd_&-Zm(Z$k*+1fjw8x~|D9+7aqWH3sQOQ$MF%aFo#eUbVUvuf`@zp2z5(aVap}A1iGyzsEDKPmdacWKOBt;R-aW1d{ zObpi46xC zcZ$=*Yir!SMl5TaJ8ZA<&GwBV5O8U*V~jILG~|@P{R}a5`kuQh2-b=7fr4-|R(_FL z|4$3JCd(uL*2-lrkXNDGSWBXx-{c2sTpx@pWsjv#>{MJ_9Irl$pZCFW!BjD3EW1}F z*(2(n_K+-}S?_P5?EeEXRToM&nl*Z&OU;4BPVMz}7l=vCil0Vi*nQD&I+8?MP1sAzIaqgrY_LuYnP)nFuCcOl0f|G)IdV=fI{zB-EA_KnUQ8GL&2Giv z*Z#NHo4R0nWlQ{x&Bk?M1rlgyLP^pJKiZ!ahB}L(&6Q{p*rd+fy@NM@ynl`FX~WXt z?derP`%PgteM^^F#$)Bus4e?|M5EiQcDb;$r+oKIw-%JrC42 z--O(^{tvUoS3cI+f8Qy_KbF{qTbz1jf`FsJi>YNt4ALq1s^QxAi=@Y^&}ay443@gBmymx?Aw18&(ysbjsh7BD5TfG-+3i zbtAHwqpZE`k7_4Zj|z-J6RY2g%Gt=kq*4#%>{}398+OP!>|Jab4Q6Rbu3VfHNqFe< zAXrV6ZK!#{H68g5UdVYEMn{OinHr_eq;CRJkK7D#l!G6p?i+Oz|VPbgh|-% z!+mb*56~|XhLDKTTN84YDLzDFER}6e8COa_s~7ZN&c86xlpos{%Vpj^D)wz| zBD?Fdk!-$=5SI~umC|dk?*dkmxTk9gv5vuD$2!)D4k z^$Jq%O^PNIaY!@h(Ua6eD)2-BoNE5#OUR#4A7h0(!e@4lIw)^ghvCdjOcAEoYnUia z(1xCM7FEfAx_#jw&));dGuh$qg|}&TXS}7T?4Yz4|9m7QL3cIWZBOOvHv+vyRmDMVMsY{*U@mm4E4*Nw^b1$kmVTZ1 z6X!;C6xL3fGQLY3m!`Y>1bXiYDGWi;R$C7Zko26S(P96P<-*LdHA+Qz>J8B*w&R=& zqNH08RNSZOyUS4R5pIe)0O2`SPnv{C{cf} z*QgXX^wC9mXmopydY=V9oxze7h16 zy@oIT`;=RkqoP8#f6}KF#Ga+6x4k=Z+jNMq;`|4;refV+imv$LCNsM;Q zXVv3c5E7|Tcy@sh1c_yj-{XwHwemkLuBRGVA{|aTvDh;6ZV79pCMTfZ2klMWfAV}7 zvbV)>t|pIato2lHa>Vq&+lnDYrYnZRq$`AVr7nHnb-YG<_1^~&1KOsT!(VPXYqO|g%EIs5u>%;h5zlUUTdJI$CZD$)mo4^FZKP_@ zRNt(dJ~(ReykEu2Pvmj9x7g4AD1E(!?9}$zt>h;Eb!*d8w(ayl8{z(FPlB^zQ{Flr zY*c+t{5tJuYMkDU|EP+-%ZF?Tcgu90{V7o+Aw(^2H?>x@KXJvTDNt@g84|;eJr`wL z?A^LX0c1*2AFcb#oSfXd!0OPq$B{t9Bpp8~cwkq`nLspnSBAJnKdow4a3)=gnh6_j z6T0l6os#NzhsL&neP_-xtkdAq#^r@M=`R|~kG6C*=xwTk$c7kih%_V7vqZX=&cUOt z$g}BhJC$Zy(`(0yOW}oNr_Lt4mo%lCvA?eVK`M@h75jnLY{9v32>Z86_k{5$oA2Qj z0oLdj(_`-4Ei6XhUP3()K8>vMWgHWD)SzJzi?{tc?|8)gMc|pb?I)#|Wwy+Szw0KZ zSL>-JK6t>|*?5!jf-su!0kz!ZZ!Xo{l0WfV#*0Rwn(vi(a(`G9Sn9_jkW(ne=Txd3 z39lR@IGx0b^1oJM<#YR0Me4*BNZXU0$7}-0_-3f)i6O#NL?GY2Y24m8Uel5+H6{Qn zmso2U6tL7?OS&krj@OC2iS&|XpMvXJTAf)jJ=?R;wKRD;h{ukRkcC?pZ7sO+_ToO{ zdxut1rMYCw9a$GDH@)uXeEp@s@D>sUqMtc;Z&@fNU14>EC^j3)X>a)wCZ9k$(odXz zjY?FAwW2$#czPehA1|>pjMw0KZ#mU4?0Vd2zrAh6s+DS_YIKB`AxgEBPI_khE^quz z>`Es6c_OAnOv7=YBoWkF^=HQZ68z5}zeY_K&8)fk{h;kHxYh%@15HQOdiQ*B_02MFP1WLHu)k0VSL0S|JNyWfn5Bi_>ZxB zR5~O}Bqx(Xz40(X{yy7M6`INn>psWXm$TwoeTwRkrIunjn71X{kAuk@zIR*+L~#jI zEclk7a5ht9&IEU}?Z)VPt{sW?EyTmWFE!W38k|*)6>du;2%a2zq)Ibvp)%U7S`s?t zPhsJ=-eC$~mUe#-z50yXx)IV^A`3!24Ou`q?YqOGH}?+Xzd$()q_koxZ>%S8EC`&w zU}M;q&m6-~Qsdr*LIjXyThp%}$e;DePCtCnP-?SYaz3ZF+q>XI7KIDIY8PSrzISMf z$xonjQY1qSBl2xVF-4-4cZ%dgW>GXv#_sNFRJZ!bip5cm@6pqgu~ZP88m%Z_49UXH z=HoIz*)6Wp@h9*o$s(2*E3`^Z_R zWOrWq%l;qtQ%S~P1D0(Wf}~Pcf+^bi1cS(TlQkiP@7#%aG?0)M)1U@!0Zlh=CZj3x z#rg3XA`$vV^_Bbn`?sSu55L~TxfuPps&^)kX=Yu3%LPG`TOA#IPyE*3G7cobo1 z6*|!B6xrsiD=k}DU)8g4lf&duUPOQQmSj)yDyZy8Tm{H1QBt=>Y2H-e^FQ(XGIPfY zO@D^D8!nl~V(P?Mv*^ghHbtsx*T03R+fC+?ojbD=?~43vx<#)9|A7BX$-6jM+CBT$ z?!If8@7^()x;^S%9o!$8<@BztRh%A9OXEB}ry zZ8+r32BfjdA6LsEE_FjeImR)QWFYnAmme- z*L?eOS&M7ZUDHV^>$h>miE75~FbI|dwQ(l7fV|swNT#}7@b;IfpHP!$= zf*z08hn6urOwIATpKFqzvOk;uz;B;77^3!1xEp*kf=w-&{l#U<^X5HQgKO77$ts)7zYl~bQk9hgGpl$9)e^kuV$ynGfccU{uQyhs@|E(MD7dBJo`a|u}?~4*5G(QUecgE*>OMuBUV2%nWo)D;kTZ9t-;heYe$0)>x;gV3ghB#s*kN4hais%; zVw&L~J_Z$9B(@MV+tGUC{vhuciBn|!O>Z+s%t(Lu*irM&)jPc2(r+|y_U@yfSby=f z=__8>OF&j{FgRa5&ApfVYRwr9{VxW+X3C3ljuG>1xN9zOd0 zvVGG>v7t<>y8BL2IWHRM@wN%jvj16=BQ*$wKmMsny$-cWV1k40zizFl-K?%{!>UcnN>!y5Z`Ax2@Q+hkFK~u^w$$gZy%I zL<)&%MXW<|u3PK%&T!89FHY;`TlAGQsri|`XUwH9UGs?XTg1m?=SO(3Ow#-QNB^qW z_AAH6)Xl6)uG>?$%mm~NR~kf5Q~ndm8_Vu3o12feI8csBb>w_E^o0JAa*hcJt=AN- z%Y?n0@7Y4;o1{~xQOuE?+tkuiKxrIr@!e$v(HJ1=2bcNg>0nG*+KpRG-g`(-eSxgK zDfLGtsbi*47gkZiMp~6$osOSNUQG4?w0QcUzW_Lgx74(|C0SfsmSxs_vy2O zg;M`Bky8{I2R;b%B>3Uvaayovuwh)|U&5u%D*ZEK%Ye;HFl&`ue0hV2qk#pb_IErm zTeG%sqhebeG_7(q1dq^pMiGUz%4|zs()y1CbEAq9QZO05@2*Zp9*Wsg_1RM4xa5TE zG42R3O>E-y$BKQR^nzLJ#l_H`i8;)*jiiwNnG z3n3hW=~HhQ<0un|HUgEA*$9!3Ot=-tW_ON@y>_`EP7jZY*Qaq^+9s_^=khYMC6g`|6gXxzJ^TO82~|Bi2y`YueE z$m=RB8j)qjAe?9veb95qzl)LVTbUlaMERq4`n&ZmnxMt3TU>5Xlt z2}zNPShp6EsJpPrY<_b_L*^a11ehvkbg~`XQJWYG^Xl2Lbyf|0SU0<`w8DQ+gYUz~ z3va5#V<-vTxaY7i-oLWiDbrV*Wdf{@D5&XnW)+RRrP7upFhj=RU0}ijJb{NZ$TMp? zK}4_Ybk>f#TJTTZ%5;OL_j7%bBr9&Ve$a{-pjo${M7l|ELmL5Oy1M zXt+W>nPE=X8v(!}H)lOk89{=bJtPlzA#8Q*@X~h~>()u%Bo5PM#&xmt_KI_sogY%S z7hQQ|Ets&W3spx!gh;APEKR+_?pnot?J-fThLj-#wsh(@|8lH!e$#Pl=t^AS=lfjKNNaC6Ql0m zg2pUCsNL%{8I=`<{k{2#{?QcV4#HJ;2O1;hZA2#G=t+^TRKjYZ< z!z|u6fL7+~(PH+`?T`($mK2W@wdN;{Ur!F1XcwGUB0Jo^G#|==V9jD<-G?Nv9D|+d z*eGMx`J^vl_qp7v2EwC73|EH~ZkpSl{q`POue?Tc&sz<$!T8qX`UxBHwy^`!wE<`| zcON|bYEnU%djvkO~j|oSneX!k-d}G zbOOThr-sfB)(x)+K3P#O^klhWdUPdat$=UY5gBHkS(sd94-cm@Nopm~6F9Znc@iDe zr(6U+f7n61`3!Bo4*fo4-FZAkr12Qd1g6ZL(ez`QkTewO+Lt@7D*Vh(8A#}Z2f0-y zNrq|t!p`m$VW*xyS%VLJ4Do{+lpbt!n=?}^TrVTIky3yIv0lh+R|h7A+Q@|9ni1#~(><$!^_!m6&t-M0F$9UTKb`)_Hdyzs~ z0$++#HDY}XmrCBiXq;A8@P!dc^No`qR9`VwpJ;`abiGa#AKJSgBv3`Y4ZX``fL8ly zigR8FQm)twF1-qHZt_UO7`V=i<5MObOT6APGiQG)XxMUPi*tMvf%wN8!jU2HK0nbQ zHl&TOD&qr_Teyg#?Z51`SEc?<@qVQM_6+vAeUr&kse-6(xK zq9W8wy;N%b*fT%`FE*$5(G1+94FgN5V7^y|Rfv-zdc{N$OV7+sI)$tM?^`?Q0=WsxPm9$Hqx%{6yd z;S^sF1GEd4Vr1aL)_vEu%-6<4?o1p_F|9a&rNxXFbf)MJb3XznH0R)~XY05!IjstT zg})#1OkPTF*|F3VdU7bLNv6wvwD&3pz6XduzfIg-ea-Dojnf>YthL-de?I+ixD3@e7t@su1o}G6|QL-+7}p zL1r0@9&?e(M#T#hLP`m+f5;cKK0*o5XBBCD%q4<+G!gN>DhJ$Vf;R7}hI=7@Og9HE z!`h+AW`BQMXTGAi6uDVhOcKk{z4`{qw0+m^?Y8bR@`K5v6I?Q8>{j?^)(y8jnxD;Y zXJR>0&+RN6=2~%?x;Q{sf^XgB(X%KNZ#s>)^q36@&78Qk?$+rTKPWkoI~1$FKGJ=Y zqw(FWkj{(n;#G;FFOy0kIS&_|5{lcExO4MU{bR%RO-^n~lC;8QODdP657q{IX3cWQ zWp4p>ZJ!^L;|r}aFLo(jSGm3nYMBLsoB5R=0X@(K`uImMGCn5G&g1y%W)*TkPrt z!Rl=h{XF0EIpO=8kP>rs3>b3=2O!Cu3 zaMf7SMu{YhCl~N@L{K!naGl#=#&EFK7BQ97H*DYH01e&u%4c{lIm3k$70kA*s8O&0 z3NyXt-=cVb( z&#<~o>8Y~VzdcDIrU{smP*13qv)2IZ9VFx=q?n2$GCpSWzthmwG89d78GeAEDPPLG zT?Zw^h?7_hz7q)n&>&wZiS6vj&J%Z#8S$1+=z9pn4C!eNwFXXJzD@CJpVnkiJe}~J za+*zZieFGU$V;2sHiD zt->izm3GXk0X(pf3mfc4OZSr)&cyA}KZ(w*1c#8de2VJy?qJ@L|IFGNRyd!&;klc| zF|S34DuNvffKXAf@uej+!*m2B!DJ510Uv?JOWfoq{!q2MTY+dn@d~H--z&1s1!#S> zuV8?)1HXy)EjO7GCBhTPn%{ksxvcS#_5Kdc76A2YlVJgJY$ak3nX~0Ae5=K%jsxerv$ydK;E3 z3LL8|fnT1g_xPg9?~wn%2pBnmP+rjQk1>*N$>D?MlvHglI&f_so~s}3jZ^d+ZX46M znuZmvelk1coV}Uvrb)4UC)8YwrZ-d;N^NeG=m!y^Liy$O&QePfji0|18MI14`_li@ z^L9Q|`Qu3Qju?(w zIHi0}i_H{NZR=uaSEU12N6S-JTDV&swp-(4oqy1r$xrt*_FDQmM*2Pi}LWS`{(TZbe!mlTJ-$(b&7@ z0QiQu)-<75E&%NXb*ttDpd~w^!Uj_Uz!HQ4UU&8YPd0tM2dhyZ)nm)W$?|3rLKM}1 zn39IE=j(%syniL6k^xwV48Os-_u0R!*9Rye>hjh}$x8^|f1;QO^eoRJN*FXFr>V6J|BayE*>@oS4O+RtFQs!@XbBxU87hfb8{WzTI9OELLp8&Cdi*N2A>WTlsr? z-2p^W*_DD&H2b?90+d*9}m^TO%5}{`S8gRAA4X zOR$~4(09lCO9g<*gdqQF_4F*m50b{6x)PM=Z6Clj@zY9A2*GZ#K<}>@dfZtVP zUWtd8Pypf+Tt2w249vSQ`S{vnxM;|HpCd~Z7^xc=X;mDYiPH(r;ayuzB>UU8#~6^^ z+z5Z6PEY(Fpvn#O7}$`q{!3IHit)^q6)K}U0N#r}J0@iHlN)%(t8Az`lU)ki$pv8t zZ1j$z!F3Vf00^t<{^H3d;=TGUYLHGcqjwf%e@&7+(7JgeNq=>YiH?4^KV?`bfjQ`%eJtT=a^)mIMFPg=%sD2r1lZwRX4j1W-3BHIh!m&2muB~gxiR7~ zaK)JZz_kuVI0OBJDkH0QD;d6>x3?PCerVonQnJsSwj4^ zS<=UnZ#TMK>_0T|=Cn06y(kAfr;U8K4#cf}#mBd>bey)BT;|-0-F*J^2??yNa?_!A zE3IDZKgA_El2ofa?w8+W8Z=hsf%>vQsORci`EI67`lvK_HVe6y@8?P#q9P>0n%u@S zaTLNAlARk7Z6~;#)SSEEa;>5wbaPo=~o^R84 zT%mVJ(xMm2k_*TPiUu1C_M~^Skq03C*lx#ea%O*L--7!!geHc=eb4&K;7}5%zdjvj znfX5z;EUj8I{3@NON@P5b-)^*V{bBh5h1zPxFIRW9+2*DFvt?xeN)!bTjMRov$F

=C1R-D>d!+sOtY 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 literal 24903 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%0AvpJ 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 diff --git a/samples/winrt/ImageManipulations/assets/StoreLogo.png b/samples/winrt/ImageManipulations/assets/StoreLogo.png index af64bf00ad4a8bfec7ee89ab8a7b61d55988dfd6..0fb23ff2cf825632c3b9a2aecae7dfc9e2b31991 100644 GIT binary patch delta 2250 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 JPDHLkV1m3AoeBT| diff --git a/samples/winrt/ImageManipulations/assets/opencv-logo-150.png b/samples/winrt/ImageManipulations/assets/opencv-logo-150.png index ea685d651ace9ce7ed2463b84bbff6ea2d891f9c..8f447ad30cbfb128d3e1dd5e2dfff24849d270ab 100644 GIT binary patch delta 5217 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 bGcqeMGdeIZiR9d>00000NkvXXu0mjf6CmoQ delta 4591 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 diff --git a/samples/winrt/ImageManipulations/assets/opencv-logo-30.png b/samples/winrt/ImageManipulations/assets/opencv-logo-30.png index efaf5468a19d1fd00f0aa95a51b47f849408fbba..449be5858e4d1ef32f9691751bd4d3393cc9104a 100644 GIT binary patch delta 1149 zcmV-@1cLj^2&xH?Bsm0UK}|sb0I`n?{9y$E001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}olE*yWcDgXenDgj}qEbjmS00(qQO+^Rf2OJCmAi{w! z?f?J-nMp)JR7l6I)mcbXQ5XmCt2It)Ws6CsSR%A&q$CstJ+wHblTabif-OW%CDcPN zJw#5?say1oL_M&+<~sF)ROj*8Ii6 zynM1~C3m$RLrrzU7;_2|odkb-;D_-HvvolcJ_CM zLZ*}8(GU;?n_;q;DU7GTeq*U`L$Z_L6z)=4^eSYD@IrWJjM>lI(9w2UZ4|w$w+o{~ z+vnpJ8Jr~ukLO&5a1-^;vpTJAO zwMOV?SPrR>%ztAd%r*@k7{M2L74(>?945!qS^WHDa23RwLFRvpi;jh6Q7`}=W2s}H z!U%4n;GhU?g<=`X&(;kkuml!^ujci%{z;Xp1V!3J!TXS+n@ikaF|>+tK`Q!P1XF{R z%0}Y%Sv?HT z!X`BoMLvjvH2Z%w5GO*Z4^A6PeUl2WGm6stldu4$Lk)a0Ztm#r7qjCLOndgYQItA( zACy8FoHu4mH|N*Oc-?02h9d0kFS-xJb_p2ade4SzKEDD3^m2M_y4wz&Y~|2d1iN^7 zf7*nYUg@sa!L(0{;D$J(?T*bA5N~sA(vq)$*AW6~c`tv#1pVyIUnV-CmcbFY1^3`I zY=FE-`X zGkp=5_W%F@C3HntbYx+4WjbSWWnpw>05UK#FfA}QEiyP%F)}(ZF*-FcD=;%UFfge} ze7FDr03|teMObuXVRU6WZEs|0W_bWIFfuSLFgGnSI8-q*IxsOhGcqeMGdeIZiR9d> P00000NkvXXu0mjfmHqo? delta 1054 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 JPDHLkV1m3AoeBT| diff --git a/samples/winrt/JavaScript/images/logo.scale-100.png b/samples/winrt/JavaScript/images/logo.scale-100.png index ea685d651ace9ce7ed2463b84bbff6ea2d891f9c..8f447ad30cbfb128d3e1dd5e2dfff24849d270ab 100644 GIT binary patch delta 5217 zcmV-n6rSsWB0Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}olE*yWcDgXenDgj}qEbjmS00(qQO+^Rf2OJCmAi{w! z?f?K2T}ebiRCwC$oeP}J)fUJ9gS_(^6!Pk6JSvgWgT$ylie6GGJsEBumC99DTi|Rh0Bl9)skDxT3tpm~+=U=l7r4ra3cb{%5a!{^!izpU;2yqtE?Z zGy7P-v-a9+uf4Y8*kOkqcGzKu9d_7ZhaGmr%Lp{?z?2{=6K4{a6J3cu#2{iAF`Rgk zc!ap0=uEUC>JsGxjZ>5O=h#u4h17(E)HEojO2mc41H^P<1+kSlKx7et0ysweLHtB4 zCB_rC6OD*6L9sSTwg1=&FQ$K{sjg=#3o#8PmJz=b*@cKGQdo@JiFxpL?EOkwPnM9& zT#lf4nY)R2m)NaINCk16_?dW~xRfXznny=#l=xomI=X_YK-_}m>WBeB<;Nc4RpJt& zl=WcoAB?l7c#k+7BSGb57crJNJCB%974Az)F6V*vXUqib+ z34SE548>hmTz(N1$0>ucv;^W9PEB;Op36U;ibZuO&PC<&U*a0;xne4+)Dk#~IglWt za@j;&W<6JIJQZ^T@mqg_iOS_`;+)WVqs`Qt%u}6DtWQu;x$x0bRqM6Pd8=x~2MI1J z_pEU!(kRyWqM{0&{|%0V}Vtz3dmCHY@*U}bS<>Y^?IvMs>*$A9h67LW% z5tE2%5ICRh?Kdo}HAFotEWO7zuNyKR7X*Gx^hd6&O0eRyNqaRh%O%FA5N(JNsIAH} zB=$bmYv~hKGh9%R&KZ4y66Q*g7|*StqCe{pj}n^=h-)#z0xJ#;M>hk7jdhS1lUs1t z!NWXL-P3^i!a0AoKTtPs1)?Fvut?ZY{oNZh8e+j3#8ly>afn?GqZd{a;#VO9ajDG! zo%jAQXO7Ee3NMG{t+1l=0Cxy3EfaKKW>A*z(}@2F&70%R6f3Og3^Y#2IA6i|l5p*-7x0~8RZER-*(08E)e((%WOW&yHQdFuEy_k>&XqqiH`{gYn_{Sv!m!n=_arv zWP{W)We~wH$TqY{vSRUIke&kH^d(rHOn#2W0zD-7fc#u5EN=$sD`?VO=Uv{(B7l+Z}GaA^sUcjo>B-c;0Vuao2x}#e=ZU61qb;&BV?SpMi5`-wS+( zg|^M4ccXCMf>i=W*@|*!6Iu7W1(x#wT726>Xpe?ruQFSxI$*q{*TVd35}ymrzps7y zBD!zJXtKMZN~t)_SYx43sL^t#75fL)2WF?Cxl#dUvfcdES|* z!m59T%b`;B;|twwd$jGa6;ZWAS3apZ&$P8z(Hn}NYMUZ_{cB0+K-c?A5lT#WgTT39 z-UcB(Y~UW1u-dCFA*J8I;qHL#y#&NcO!bgJhCRRjq_#PT#@*E_VS@#5o7trnu!F1{(OE;l*Hi0(QwpA^U%FylOMs@K%?&8VUABI7;-6CT>x@)(k;m z&9xU*bqgzWp!Z1xK}3;&e+kY8$kJhP4UR!8W?Za)Gpf?k~V?8c%-= zp0PVYNnzy{&Rs$5(9mdYpx{{{FI#goi0U(VKq~-4+4x7XoAYY0PtnUta@lSjJz z-D0dV0Q0L9;o}F{Xiro#^!MzsO$^0#LdJV}A%^?X^bSiA|CNQbWa4s|SKJMS^;Z58 z*V*t4*t>7bU_Ow1=a`Bp5CL@RzQhc!%3`KgPmx8=Yjqt9}wXsqv^XQq`PN)zRY3ZNWOibx`y0ZY@o#$DWGt%4tnr+BT( zh`Fo?q8%&_h@>*ngy>8>M2vqWW)TaBe-q2V5@Iefop_q)Nwgyx5M?tm`viZc9mP{f zOi760R^oYL1+kMjN(72PHgSmfnOH;&Bd#Q>xn9kV;vuN2@Jg=`KM}`@D5OX@NUS8D zB3fcObuz5T5=~IO_|H>_-o$6bVF59P<2T|Bq9funXY_{N)-Va+p*Vkbx(^;C%b=k0 zvL6Dg?dRpO`j~)IZFG>bL@EC7SP#sn1aUHv6tg)gF;rV(p@+Chicg5@eiarB$cDR^ zc!RhG|69!Flsq~|=;ssvBJP0b%}pXB*GqBWJe1hw6G1Wii0fQW>MKEIM=Rm{)0H8s>j=h?q(=G$MLMR85HwV!Z6-$22#H_o0_!8W67&M`1uFi|8LK zucgfGT4J9vFJ>iirRdU#9T#uyuOfc*nV^_0#Caj%_x7WxE+jtBV>p-f#5pk(Rx+_P z%-qN`<|=tyiXL{!Wk2+-J)h~ITKJZ53@J4g)HA}%){M1S7l zV^MKNzMG!{c12WeiA@n0&1C^m*@Un#zmmlGBFyg~HXbEC&r!)ybs~QCsi>IQZc@}2 zqRP!tolC4Pg3*5h25h(D;WgLpL|MN^AgBKfG7LRTX7C*k|u*OM>t5<<+YT6y%n)t<2*S#e_Gf%D&A^<507f{mdIS; z7jKnkhqZr4qrsR}L|q-i!W_%t;5(q1AyvbD0br>5K0U5c8HX6qPu_|v0pzU|`5s9r-fB>ck7bU*TZY>-aO&eMzlcilRvnPvkr38)EMK0NMEu=T z3OK9O@&)*d*Mg{OVW(wENJoeth?x-d?L-&iMihSyjz9&)R^m8B*Vl&`c8;xP2pTMa z<*S?*Ve#LA!3Pn?1?RYysGl=O#as0ds!h+YW@-*`JxZDR9MXC0{j~f%D3`#TL-Y?G zGH0e$@!@%3GtI$pxZPKKufihg!0?iDWYMPOcvcv&4Dp_UrEVFHh{^_k@A~+yOIPBS zLBf9qW4WfiM{7nLZZw0(0CW9#6s= zdqU;v6ZsVL>4eW6Td2bNo3N-x;HI;aC?(W$&U1Hk0&}kf0Z7c9iv}C8uu_S=0;1ZDYw*6RLDy)UYRHW1HjL=yimGG8j&@vl znZ1gI^)T{8x`p*JI>tDOHei@0#7+UjtVA-?gvT8(wBdNffdC|ORqcY_Dgm#$!!UnW z;hDwes$2HMW?X1 zeNlUp!cxkqIkiy--DaYtPH;Kj(CdGMqbEgJF9-;0WDM>VrV7N0e>kWz&>gs66a!&# zWyBg{Be6jPn~CA0sPC7014t3pQ~_Z<5rdo19Ki3_eQ53oG)QA%U2IBNN+rZo0@h|?*5v}lfBPkt!Xrq!nike`0>T=bcN3xrYodU##>anPDZEag z>S4DdRMl{As4OPUl(4vNYo5U8_-EeFp$O|~0b#vQoMb{+$tN}h(fv8LIEYJh8)Uqx zbOU}52iofeK1aX&J_8K$kbptBBTa3C>4qfKY3cqPUpqJ`)@_g#=$tJ2kE65#xKAK`SJ@c!fFwh zQsBo|_CFFVsh(8z+1!826!#0ZEXqRivP!7+WFH-#>N4S009^5LT0vh17>WC!|0HOn z%%Hf&MJKL2?ZD>=&X?=xyQ;TzQiyGWhRVWIBxiVyx$yT+Lch^X!gnC2prLPJ#wsaT z_pWx&yWhPDUDPy$lCR=^Tb~KfH50wJPB7T)bopD*-=k6P$&r7))TO+2$Ty-V;w(~f zj)x<8-9qsKw-~qxdI%2>v~pW^7v{kr!X)fohheuVeX;h%oU$J!X6c4IfB^%BTa5k; z?7>Qp%45Vl4`;R}p2hQYCVEPIf#+Nz^#)v@{*3{nxjQbd*}4&eDVvP61XDBjdRGmi z4e<=J`Ns{+Z9jiXaB{sW3|WKt(qL1NEW9Q$pGZevE*4ua;_tj1p?~`yhCAL2h;+GD zyw>A}gyr%lV!IDfzB39UnuJb(tA&!c1+nNa9S9Y#)lcZgPQ0)>TvD_Uah*wQFl&5D_*OO!0jDBGbP#sa|o*f zF}oOvDib%t3s2xGTm2_|-aT0t-?)j}k?Z>C$Zj`_@HMS?=OErOjQmsp;^HHiw-a1c zyU<}!O9g+1BCcBno89__2@$rr}84HfJ`6>AoFZd{Tl z-rAgCqRK)WfU**`VoG0x$pW{GW6f7Yqo}T_DdOtv(m=bE-Njmq4?~p*z1-JU zH^p&GHO}=^BiHp5zhYHAJ)pi4KiNPPgcMwE)7(8}kh*c)8rQqxNmTqq-ea+9va7^g zL*i_=$Zad%%4r8KbtO#^S3}}8LuEG6!WVLHi1oux%5JeMN?H6aD(>_*oTy^ro})8i zb&h|yDxw-_JSn}$`o1nr7 z%uP*nLCNuY%_7UfayJ)Gz@6?Z4^;#&mV{dRRP>r!h)WR%idX`D6bHs!-8v2Zw^D!H zQkQssp01FqWpxllkHGoddhFJYMd*>Z2yYAVDe)X)x<>BdadJi=zW@waH)b1zx&}@+NHQuTft;E=GcD=ZeyCee6nXNnGw3*Sjx>gWh7`zZ#(R;!wx&_ zu)_{J?C>)F58_jp(U34)&j0`bC3HntbYx+4WjbSWWnpw>05UK#FfA}QEiyP%F)}(Z zF*-FcD=;%UFfge}e7FDr03~!qSaf7zbY(hiZ)9m^c>ppnGB7PLH!U(aR52YgIxsOh bGcqeMGdeIZiR9d>00000NkvXXu0mjf6CmoQ delta 4591 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 diff --git a/samples/winrt/JavaScript/images/smalllogo.scale-100.png b/samples/winrt/JavaScript/images/smalllogo.scale-100.png index efaf5468a19d1fd00f0aa95a51b47f849408fbba..f2d18773485dc857bb4d01be63ca29a15f00c75e 100644 GIT binary patch delta 1400 zcmV-;1&8{}2$&0y8AJjA006X7IrRVl00d`2O+f$vv5yP zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9O|@9DlJY006Nn0b!>s?*IS*2XskI zMF->u91JQmFi(?N000DsNklX6!D4TmoZ62vE=nF;d3~mpspx;VRu=s%VpUs?B(01 z_w4!DWq$>VrElIjbLKmHp7%M=dEWP136}ZHx?r|o+6s?nnL8x^vF`IhqsPw`*!4BG zCnF&h`!Y~{9;S)^2kmmBvJNpHATktY#SHi-#lB7gLFDF#QvgeEEWq>E=KxaZ>V#Sf^x zh^jgyejel=8H3|hVM1#S?7W;Zg{+u4gg>T9?D$ILPQ;TAz&R5RG^s%O~*zyrZOyNK`wqwIqar4$hjE;w_wq0iuaY3TrhjAnv=x!xm+{P$VyzmCD zTz?B$%`X$RqQvn#Ff|}dC;?h^YU1gLY?wcpH!yWNw^eQ zs+|SewBZ@uBF-E|R0Te+ha*(yo-sUMg1whu_Lrwb@OhiYYyEIR&@7dd#@31Yg@3q4 zD_*O@eKI_hgEM#LiRs1eKiT^T1r9aAEkM$5SLSK=XZdkyB<>~pL#6tR(?*5WGqn&p zvjwZ=xL<))a=iL0M&<->P~(wYh8rQrj>9x_g5O>&y zjin+qjYQu#r}!UgJW;@K`BLIJNPh~oX#waf<7a&Mw+~1203PPl6nHETjrx!;U3!z4 zl@df2L84G4bBRd`jr~T*jr%-(wyy5!rXCi}Hm|9!4-aIEyk0Ja$q|zHf(8#BWvdi4 zksMWj%Av_~w=E%U$m}*1^&jL{Dpw`z96f=}1pUl$^oLeVl@e?GiRnzFyMN?_K4VT0 zY0Y4c-7AVm&LM|zkJAtGwFf5MMx_Z)7K(xr%8zZ#34v>PvxeO*PrRuNl9q`&&YDN{ zVD?Q*>s{;hi=*W^>OI_%Bjcon8O0pQZAsn7bV?z{j?|r&w8XC5;}F6 z;X8k^a8paUIDEn>=W6x_u780{_UJK@c!b}AYvv{#ca;p$6);%*)u^@KB%cJ(=LdIs z+vIuDM{EfK(}5IUEf3NR1RdzSpWb4C3Hnt zbYx+4WjbwdWNBu304XvsGB7PLH!U(aR53C-G%`9hF)J`LIxsLLjR!FR0000n{fVKa#tnF*r|#)xllK?+ri<0nUsi$ASk(ZTy6- z4b~-JMjIfLUz3BC<$c+{VAFiSV{-}0pxuTIWiULA9e95?nJQd|+X|;PU>6te#D`@8 zXS_Igqwmhf>bJ82X*^Pr7l%CZesaP8>F&&fy|S>p_CoSp@^_^m@$`_Rmf_rm0FOHN z&U||EIAUu);Qh(rp|J22iIuU=Yjeefw?Bvr*zBjn$q-3yQYw}y8czaYdjGpD!Mb8^YgZnGliJ{Cfd~@<< zuwsOFmIhA-_njDM49!ek;UejBVQB@>`FCvgl1W|J+*qT-Ip^pPG_4X|l>U^h_X}x@ z(4E^oaSE}#Et{_8D|>U=>$}no(nJLo&DVc#_#c0lEg_#E_Y$kx*EGac|oif^0I_ti#Jw$cLJ2IZ2G5QoJ@`Vr(ZmgvHYC8JHf>r1XpQv$R*(I0q_p&C-4~v=pnWIp>j! z+Ess4-cNdd$h98|XB-zB%5<09U0E|lK06{Ey-ZA2UioGW7gQD66u#1Nq*b-0)3Fg} zHoNXh@9A{@!ub`zA$;79_zvvCO<3M2J%3Df#YtVIv9`3z%d7FUVs)c&9IG%v{!LlZ zOdiKsv+ti=Nm*14{6%`C38;Qx{U}{uQSE;W=@n_JI*?<+IN2q44&4zS5gV$AzJmC4 z;O0o;og!U|J(bmo9~2)*M{&7gleD-Bz?X23&NSKChF2^9OyO&MLUt(EV0~|s`T@9= z)DfN=vbxXa=@!3x?Syby?+6pQjQFUrB-*rzsv7E7PPvObt?$ki!pw12h jul@g_TCPN$6yQHqi=Pd*%y2UR000R9NkvXXu0mjfZ<7rp diff --git a/samples/winrt/JavaScript/images/windows-sdk.png b/samples/winrt/JavaScript/images/windows-sdk.png index af64bf00ad4a8bfec7ee89ab8a7b61d55988dfd6..0fb23ff2cf825632c3b9a2aecae7dfc9e2b31991 100644 GIT binary patch delta 2250 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 JPDHLkV1m3AoeBT| diff --git a/samples/winrt/OcvImageProcessing/OcvImageProcessing/Assets/Logo.png b/samples/winrt/OcvImageProcessing/OcvImageProcessing/Assets/Logo.png index ea685d651ace9ce7ed2463b84bbff6ea2d891f9c..8f447ad30cbfb128d3e1dd5e2dfff24849d270ab 100644 GIT binary patch delta 5217 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 bGcqeMGdeIZiR9d>00000NkvXXu0mjf6CmoQ delta 4591 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 diff --git a/samples/winrt/OcvImageProcessing/OcvImageProcessing/Assets/SmallLogo.png b/samples/winrt/OcvImageProcessing/OcvImageProcessing/Assets/SmallLogo.png index efaf5468a19d1fd00f0aa95a51b47f849408fbba..449be5858e4d1ef32f9691751bd4d3393cc9104a 100644 GIT binary patch delta 1149 zcmV-@1cLj^2&xH?Bsm0UK}|sb0I`n?{9y$E001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}olE*yWcDgXenDgj}qEbjmS00(qQO+^Rf2OJCmAi{w! z?f?J-nMp)JR7l6I)mcbXQ5XmCt2It)Ws6CsSR%A&q$CstJ+wHblTabif-OW%CDcPN zJw#5?say1oL_M&+<~sF)ROj*8Ii6 zynM1~C3m$RLrrzU7;_2|odkb-;D_-HvvolcJ_CM zLZ*}8(GU;?n_;q;DU7GTeq*U`L$Z_L6z)=4^eSYD@IrWJjM>lI(9w2UZ4|w$w+o{~ z+vnpJ8Jr~ukLO&5a1-^;vpTJAO zwMOV?SPrR>%ztAd%r*@k7{M2L74(>?945!qS^WHDa23RwLFRvpi;jh6Q7`}=W2s}H z!U%4n;GhU?g<=`X&(;kkuml!^ujci%{z;Xp1V!3J!TXS+n@ikaF|>+tK`Q!P1XF{R z%0}Y%Sv?HT z!X`BoMLvjvH2Z%w5GO*Z4^A6PeUl2WGm6stldu4$Lk)a0Ztm#r7qjCLOndgYQItA( zACy8FoHu4mH|N*Oc-?02h9d0kFS-xJb_p2ade4SzKEDD3^m2M_y4wz&Y~|2d1iN^7 zf7*nYUg@sa!L(0{;D$J(?T*bA5N~sA(vq)$*AW6~c`tv#1pVyIUnV-CmcbFY1^3`I zY=FE-`X zGkp=5_W%F@C3HntbYx+4WjbSWWnpw>05UK#FfA}QEiyP%F)}(ZF*-FcD=;%UFfge} ze7FDr03|teMObuXVRU6WZEs|0W_bWIFfuSLFgGnSI8-q*IxsOhGcqeMGdeIZiR9d> P00000NkvXXu0mjfmHqo? delta 1054 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 JPDHLkV1m3AoeBT| From d92af2aa85e55e46c11a9c7732efe7177694fa35 Mon Sep 17 00:00:00 2001 From: Tomoaki Teshima Date: Wed, 29 Jul 2020 17:31:39 +0900 Subject: [PATCH 04/21] * stop showing old generations * keep it possible to build for old CC * make sure old generations don't come up for the choice * remove related version check of old one --- cmake/OpenCVDetectCUDA.cmake | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/cmake/OpenCVDetectCUDA.cmake b/cmake/OpenCVDetectCUDA.cmake index 670bfebd2f..8a62032167 100644 --- a/cmake/OpenCVDetectCUDA.cmake +++ b/cmake/OpenCVDetectCUDA.cmake @@ -78,7 +78,12 @@ if(CUDA_FOUND) message(STATUS "CUDA detected: " ${CUDA_VERSION}) - set(_generations "Fermi" "Kepler" "Maxwell" "Pascal" "Volta" "Turing" "Ampere") + OCV_OPTION(CUDA_ENABLE_DEPRECATED_GENERATION "Enable deprecated generations in the list" OFF) + set(_generations "Maxwell" "Pascal" "Volta" "Turing" "Ampere") + if(CUDA_ENABLE_DEPRECATED_GENERATION) + set(_generations "Fermi" "${_generations}") + set(_generations "Kepler" "${_generations}") + endif() set(_arch_fermi "2.0") set(_arch_kepler "3.0;3.5;3.7") set(_arch_maxwell "5.0;5.2") @@ -199,10 +204,6 @@ if(CUDA_FOUND) endif() endmacro() - macro(ocv_wipeout_deprecated _arch_bin_list) - string(REPLACE "2.1" "2.1(2.0)" ${_arch_bin_list} "${${_arch_bin_list}}") - endmacro() - set(__cuda_arch_ptx "") if(CUDA_GENERATION STREQUAL "Fermi") set(__cuda_arch_bin ${_arch_fermi}) @@ -265,7 +266,6 @@ if(CUDA_FOUND) ) endif() endif() - ocv_wipeout_deprecated(__cuda_arch_bin) set(CUDA_ARCH_BIN ${__cuda_arch_bin} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported") set(CUDA_ARCH_PTX ${__cuda_arch_ptx} CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for") @@ -273,10 +273,14 @@ if(CUDA_FOUND) string(REGEX REPLACE "\\." "" ARCH_BIN_NO_POINTS "${CUDA_ARCH_BIN}") string(REGEX REPLACE "\\." "" ARCH_PTX_NO_POINTS "${CUDA_ARCH_PTX}") - # Check if user specified 1.0 compute capability: we don't support it - if(" ${CUDA_ARCH_BIN} ${CUDA_ARCH_PTX}" MATCHES " 1.0") - message(SEND_ERROR "CUDA: 1.0 compute capability is not supported - exclude it from ARCH/PTX list are re-run CMake") - endif() + # Check if user specified 1.0/2.1 compute capability: we don't support it + macro(ocv_wipeout_deprecated_cc target_cc) + if(" ${CUDA_ARCH_BIN} ${CUDA_ARCH_PTX}" MATCHES " ${target_cc}") + message(SEND_ERROR "CUDA: ${target_cc} compute capability is not supported - exclude it from ARCH/PTX list and re-run CMake") + endif() + endmacro() + ocv_wipeout_deprecated_cc("1.0") + ocv_wipeout_deprecated_cc("2.1") # NVCC flags to be set set(NVCC_FLAGS_EXTRA "") From f66fc199a20882c546fa31142e9c0f5a8b3cf983 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Wed, 29 Jul 2020 18:51:55 +0200 Subject: [PATCH 05/21] Fix build of grfmt_jpeg2000.cpp libjasper has recently changed `jas_matrix_get` from a macro to an inline function (389951d071 in https://github.com/jasper-software/jasper), causing the build to fail. --- modules/imgcodecs/src/grfmt_jpeg2000.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/imgcodecs/src/grfmt_jpeg2000.cpp b/modules/imgcodecs/src/grfmt_jpeg2000.cpp index fe69f80c86..0f4d28d6f4 100644 --- a/modules/imgcodecs/src/grfmt_jpeg2000.cpp +++ b/modules/imgcodecs/src/grfmt_jpeg2000.cpp @@ -377,7 +377,7 @@ bool Jpeg2KDecoder::readComponent8u( uchar *data, void *_buffer, for( y = 0; y < yend - ystart; ) { - jas_seqent_t* pix_row = &jas_matrix_get( buffer, y / ystep, 0 ); + jas_seqent_t* pix_row = jas_matrix_getref( buffer, y / ystep, 0 ); uchar* dst = data + (y - yoffset) * step - xoffset; if( xstep == 1 ) @@ -443,7 +443,7 @@ bool Jpeg2KDecoder::readComponent16u( unsigned short *data, void *_buffer, for( y = 0; y < yend - ystart; ) { - jas_seqent_t* pix_row = &jas_matrix_get( buffer, y / ystep, 0 ); + jas_seqent_t* pix_row = jas_matrix_getref( buffer, y / ystep, 0 ); ushort* dst = data + (y - yoffset) * step - xoffset; if( xstep == 1 ) From 866468cc3e49ce27100df5b70039f3182dac1f9f Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Thu, 30 Jul 2020 01:03:55 +0300 Subject: [PATCH 06/21] Fix Carotene compilation with XCode --- 3rdparty/carotene/CMakeLists.txt | 3 ++- 3rdparty/carotene/hal/CMakeLists.txt | 3 ++- 3rdparty/carotene/hal/dummy.cpp | 2 ++ 3rdparty/carotene/src/dummy.cpp | 2 ++ 4 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 3rdparty/carotene/hal/dummy.cpp create mode 100644 3rdparty/carotene/src/dummy.cpp diff --git a/3rdparty/carotene/CMakeLists.txt b/3rdparty/carotene/CMakeLists.txt index 528fcf62e1..4319815708 100644 --- a/3rdparty/carotene/CMakeLists.txt +++ b/3rdparty/carotene/CMakeLists.txt @@ -40,4 +40,5 @@ if(WITH_NEON) target_compile_definitions(carotene_objs PRIVATE "-DWITH_NEON") endif() -add_library(carotene STATIC EXCLUDE_FROM_ALL "$") +# we add dummy file to fix XCode build +add_library(carotene STATIC EXCLUDE_FROM_ALL "$" "${CAROTENE_SOURCE_DIR}/dummy.cpp") diff --git a/3rdparty/carotene/hal/CMakeLists.txt b/3rdparty/carotene/hal/CMakeLists.txt index a87f7a0949..0162aae101 100644 --- a/3rdparty/carotene/hal/CMakeLists.txt +++ b/3rdparty/carotene/hal/CMakeLists.txt @@ -80,7 +80,8 @@ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS ${carotene_defs}) # set_source_files_properties(impl.cpp $ COMPILE_FLAGS "--param ipcp-unit-growth=100000 --param inline-unit-growth=100000 --param large-stack-frame-growth=5000") endif() -add_library(tegra_hal STATIC $) +# we add dummy file to fix XCode build +add_library(tegra_hal STATIC $ "dummy.cpp") set_target_properties(tegra_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH}) set(OPENCV_SRC_DIR "${CMAKE_SOURCE_DIR}") if(NOT BUILD_SHARED_LIBS) diff --git a/3rdparty/carotene/hal/dummy.cpp b/3rdparty/carotene/hal/dummy.cpp new file mode 100644 index 0000000000..7f10ff3e8c --- /dev/null +++ b/3rdparty/carotene/hal/dummy.cpp @@ -0,0 +1,2 @@ +// This file is needed for compilation on some platforms e.g. with XCode generator +// Related issue: https://gitlab.kitware.com/cmake/cmake/-/issues/17457 diff --git a/3rdparty/carotene/src/dummy.cpp b/3rdparty/carotene/src/dummy.cpp new file mode 100644 index 0000000000..7f10ff3e8c --- /dev/null +++ b/3rdparty/carotene/src/dummy.cpp @@ -0,0 +1,2 @@ +// This file is needed for compilation on some platforms e.g. with XCode generator +// Related issue: https://gitlab.kitware.com/cmake/cmake/-/issues/17457 From 3c3e131c38e7f35b8012e92dd525b42ecacebed2 Mon Sep 17 00:00:00 2001 From: Pavel Rojtberg Date: Thu, 30 Jul 2020 21:59:15 +0200 Subject: [PATCH 07/21] Merge pull request #17977 from paroj:hervec * calib3d: calibrateHandEye - allow using Rodrigues vectors for rotation * calib3d: calibrateHandEye - test rvec representation --- modules/calib3d/src/calibration_handeye.cpp | 10 ++++++++-- modules/calib3d/test/test_calibration_hand_eye.cpp | 5 ++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/calib3d/src/calibration_handeye.cpp b/modules/calib3d/src/calibration_handeye.cpp index 18561c77fe..37d4e89d78 100644 --- a/modules/calib3d/src/calibration_handeye.cpp +++ b/modules/calib3d/src/calibration_handeye.cpp @@ -712,7 +712,10 @@ void calibrateHandEye(InputArrayOfArrays R_gripper2base, InputArrayOfArrays t_gr { Mat m = Mat::eye(4, 4, CV_64FC1); Mat R = m(Rect(0, 0, 3, 3)); - R_gripper2base_[i].convertTo(R, CV_64F); + if(R_gripper2base_[i].size() == Size(3, 3)) + R_gripper2base_[i].convertTo(R, CV_64F); + else + Rodrigues(R_gripper2base_[i], R); Mat t = m(Rect(3, 0, 1, 3)); t_gripper2base_[i].convertTo(t, CV_64F); @@ -727,7 +730,10 @@ void calibrateHandEye(InputArrayOfArrays R_gripper2base, InputArrayOfArrays t_gr { Mat m = Mat::eye(4, 4, CV_64FC1); Mat R = m(Rect(0, 0, 3, 3)); - R_target2cam_[i].convertTo(R, CV_64F); + if(R_target2cam_[i].size() == Size(3, 3)) + R_target2cam_[i].convertTo(R, CV_64F); + else + Rodrigues(R_target2cam_[i], R); Mat t = m(Rect(3, 0, 1, 3)); t_target2cam_[i].convertTo(t, CV_64F); diff --git a/modules/calib3d/test/test_calibration_hand_eye.cpp b/modules/calib3d/test/test_calibration_hand_eye.cpp index d2cef969b3..848dcf07c2 100644 --- a/modules/calib3d/test/test_calibration_hand_eye.cpp +++ b/modules/calib3d/test/test_calibration_hand_eye.cpp @@ -317,7 +317,10 @@ void CV_CalibrateHandEyeTest::simulateData(RNG& rng, int nPoses, t_gripper2base_noise.at(2,0) += rng.gaussian(0.001); } - R_target2cam.push_back(T_target2cam(Rect(0, 0, 3, 3))); + // test rvec represenation + Mat rvec_target2cam; + cv::Rodrigues(T_target2cam(Rect(0, 0, 3, 3)), rvec_target2cam); + R_target2cam.push_back(rvec_target2cam); t_target2cam.push_back(T_target2cam(Rect(3, 0, 1, 3))); } } From 6bed5c181bb9c4b30603306e646b7ba49f6205a0 Mon Sep 17 00:00:00 2001 From: kadi soheib Date: Fri, 31 Jul 2020 23:43:38 +0300 Subject: [PATCH 08/21] Corrected Comment as requested by reviewer. --- modules/dnn/include/opencv2/dnn/all_layers.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/dnn/include/opencv2/dnn/all_layers.hpp b/modules/dnn/include/opencv2/dnn/all_layers.hpp index fb211fe46b..c9455ab528 100644 --- a/modules/dnn/include/opencv2/dnn/all_layers.hpp +++ b/modules/dnn/include/opencv2/dnn/all_layers.hpp @@ -599,11 +599,12 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN }; /** - * @brief detection output layer. + * @brief Detection output layer. * * The layer size is: @f$ (1 \times 1 \times N \times 7) @f$ - * where N is the number of detections after nms, and each row is: + * where N is [keep_top_k] parameter multiplied by batch size. Each row is: * [image_id, label, confidence, xmin, ymin, xmax, ymax] + * where image_id is the index of image input in the batch. */ class CV_EXPORTS DetectionOutputLayer : public Layer { From bc221bdb908052b0f58de388d73885c94654f2ee Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Viel Date: Sun, 2 Aug 2020 18:05:20 +0200 Subject: [PATCH 09/21] Cleaner code for hierarchical_clustering --- .../flann/hierarchical_clustering_index.h | 39 ++++++++----------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/modules/flann/include/opencv2/flann/hierarchical_clustering_index.h b/modules/flann/include/opencv2/flann/hierarchical_clustering_index.h index c068e184bb..78ac401630 100644 --- a/modules/flann/include/opencv2/flann/hierarchical_clustering_index.h +++ b/modules/flann/include/opencv2/flann/hierarchical_clustering_index.h @@ -404,34 +404,16 @@ public: */ virtual ~HierarchicalClusteringIndex() { - free_elements(); - if (root!=NULL) { delete[] root; } if (indices!=NULL) { + free_indices(); delete[] indices; } } - - /** - * Release the inner elements of indices[] - */ - void free_elements() - { - if (indices!=NULL) { - for(int i=0; i Date: Thu, 30 Jul 2020 18:04:22 +0300 Subject: [PATCH 10/21] Do not use size_t for nGraph layers --- .../dnn/src/layers/fully_connected_layer.cpp | 2 +- modules/dnn/src/layers/permute_layer.cpp | 3 +- modules/dnn/test/test_layers.cpp | 29 ++++++++------ modules/dnn/test/test_misc.cpp | 39 ++++++++++++------- 4 files changed, 46 insertions(+), 27 deletions(-) diff --git a/modules/dnn/src/layers/fully_connected_layer.cpp b/modules/dnn/src/layers/fully_connected_layer.cpp index 3f3b62b106..03349253c0 100644 --- a/modules/dnn/src/layers/fully_connected_layer.cpp +++ b/modules/dnn/src/layers/fully_connected_layer.cpp @@ -565,7 +565,7 @@ public: } else { - std::vector data = {(size_t)ieInpNode->get_shape()[0], (size_t)blobs[0].size[1]}; + std::vector data = {(int64_t)ieInpNode->get_shape()[0], (int64_t)blobs[0].size[1]}; auto new_shape = std::make_shared(ngraph::element::i64, ngraph::Shape{2}, data.data()); auto inp = std::make_shared(ieInpNode, new_shape, true); diff --git a/modules/dnn/src/layers/permute_layer.cpp b/modules/dnn/src/layers/permute_layer.cpp index d8e5f66678..e08bfa0c5c 100644 --- a/modules/dnn/src/layers/permute_layer.cpp +++ b/modules/dnn/src/layers/permute_layer.cpp @@ -385,8 +385,9 @@ public: const std::vector >& nodes) CV_OVERRIDE { auto& ieInpNode = nodes[0].dynamicCast()->node; + std::vector order(_order.begin(), _order.end()); auto tr_axes = std::make_shared(ngraph::element::i64, - ngraph::Shape({_order.size()}), _order.data()); + ngraph::Shape({order.size()}), order.data()); auto transpose = std::make_shared(ieInpNode, tr_axes); return Ptr(new InfEngineNgraphNode(transpose)); } diff --git a/modules/dnn/test/test_layers.cpp b/modules/dnn/test/test_layers.cpp index 5713730e54..0c4ce11ca5 100644 --- a/modules/dnn/test/test_layers.cpp +++ b/modules/dnn/test/test_layers.cpp @@ -1108,6 +1108,9 @@ TEST_P(Layer_Test_Convolution_DLDT, Accuracy) const Backend backendId = get<0>(GetParam()); const Target targetId = get<1>(GetParam()); + if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); + if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) throw SkipTestException("No support for async forward"); @@ -1118,9 +1121,8 @@ TEST_P(Layer_Test_Convolution_DLDT, Accuracy) else FAIL() << "Unknown backendId"; - std::string suffix = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? "_fp16" : ""; Net netDefault = readNet(_tf("layer_convolution.caffemodel"), _tf("layer_convolution.prototxt")); - Net net = readNet(_tf("layer_convolution" + suffix + ".xml"), _tf("layer_convolution" + suffix + ".bin")); + Net net = readNet(_tf("layer_convolution.xml"), _tf("layer_convolution.bin")); Mat inp = blobFromNPY(_tf("blob.npy")); @@ -1140,7 +1142,10 @@ TEST_P(Layer_Test_Convolution_DLDT, Accuracy) std::vector outLayers = net.getUnconnectedOutLayers(); ASSERT_EQ(net.getLayer(outLayers[0])->name, "output"); - ASSERT_EQ(net.getLayer(outLayers[0])->type, "Convolution"); + if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019) + ASSERT_EQ(net.getLayer(outLayers[0])->type, "Convolution"); + else + ASSERT_EQ(net.getLayer(outLayers[0])->type, "Add"); } TEST_P(Layer_Test_Convolution_DLDT, setInput_uint8) @@ -1148,6 +1153,9 @@ TEST_P(Layer_Test_Convolution_DLDT, setInput_uint8) const Backend backendId = get<0>(GetParam()); const Target targetId = get<1>(GetParam()); + if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); + if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) throw SkipTestException("No support for async forward"); @@ -1164,12 +1172,10 @@ TEST_P(Layer_Test_Convolution_DLDT, setInput_uint8) randu(inputs[0], 0, 255); inputs[0].convertTo(inputs[1], CV_32F); - std::string suffix = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? "_fp16" : ""; - Mat outs[2]; for (int i = 0; i < 2; ++i) { - Net net = readNet(_tf("layer_convolution" + suffix + ".xml"), _tf("layer_convolution" + suffix + ".bin")); + Net net = readNet(_tf("layer_convolution.xml"), _tf("layer_convolution.bin")); net.setPreferableBackend(backendId); net.setPreferableTarget(targetId); net.setInput(inputs[i]); @@ -1185,6 +1191,9 @@ TEST_P(Layer_Test_Convolution_DLDT, multithreading) const Backend backendId = get<0>(GetParam()); const Target targetId = get<1>(GetParam()); + if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); + if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) throw SkipTestException("No support for async forward"); @@ -1195,9 +1204,8 @@ TEST_P(Layer_Test_Convolution_DLDT, multithreading) else FAIL() << "Unknown backendId"; - std::string suffix = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? "_fp16" : ""; - std::string xmlPath = _tf("layer_convolution" + suffix + ".xml"); - std::string binPath = _tf("layer_convolution" + suffix + ".bin"); + std::string xmlPath = _tf("layer_convolution.xml"); + std::string binPath = _tf("layer_convolution.bin"); Net firstNet = readNet(xmlPath, binPath); Net secondNet = readNet(xmlPath, binPath); Mat inp = blobFromNPY(_tf("blob.npy")); @@ -1256,8 +1264,7 @@ TEST_P(Test_DLDT_two_inputs_3dim, as_IR) int secondInpType = get<1>(GetParam()); Target targetId = get<2>(GetParam()); - std::string suffix = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? "_fp16" : ""; - Net net = readNet(_tf("net_two_inputs" + suffix + ".xml"), _tf("net_two_inputs.bin")); + Net net = readNet(_tf("net_two_inputs.xml"), _tf("net_two_inputs.bin")); std::vector inpSize = get<3>(GetParam()); Mat firstInp(3, inpSize.data(), firstInpType); Mat secondInp(3, inpSize.data(), secondInpType); diff --git a/modules/dnn/test/test_misc.cpp b/modules/dnn/test/test_misc.cpp index 1ca0d39672..6df089e11d 100644 --- a/modules/dnn/test/test_misc.cpp +++ b/modules/dnn/test/test_misc.cpp @@ -440,12 +440,14 @@ TEST_P(Async, model_optimizer_pipeline_set_and_forward_single) const Backend backendId = get<0>(get<1>(GetParam())); const Target targetId = get<1>(get<1>(GetParam())); + if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); + if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) throw SkipTestException("No support for async forward"); - const std::string suffix = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? "_fp16" : ""; - const std::string& model = findDataFile("dnn/layers/layer_convolution" + suffix + ".bin"); - const std::string& proto = findDataFile("dnn/layers/layer_convolution" + suffix + ".xml"); + const std::string& model = findDataFile("dnn/layers/layer_convolution.bin"); + const std::string& proto = findDataFile("dnn/layers/layer_convolution.xml"); if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019) setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API); @@ -499,12 +501,14 @@ TEST_P(Async, model_optimizer_pipeline_set_and_forward_all) const Backend backendId = get<0>(get<1>(GetParam())); const Target targetId = get<1>(get<1>(GetParam())); + if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); + if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) throw SkipTestException("No support for async forward"); - const std::string suffix = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? "_fp16" : ""; - const std::string& model = findDataFile("dnn/layers/layer_convolution" + suffix + ".bin"); - const std::string& proto = findDataFile("dnn/layers/layer_convolution" + suffix + ".xml"); + const std::string& model = findDataFile("dnn/layers/layer_convolution.bin"); + const std::string& proto = findDataFile("dnn/layers/layer_convolution.xml"); if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019) setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API); @@ -673,9 +677,11 @@ TEST_P(Test_Model_Optimizer, forward_two_nets) const Backend backendId = get<0>(GetParam()); const Target targetId = get<1>(GetParam()); - const std::string suffix = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? "_fp16" : ""; - const std::string& model = findDataFile("dnn/layers/layer_convolution" + suffix + ".bin"); - const std::string& proto = findDataFile("dnn/layers/layer_convolution" + suffix + ".xml"); + if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); + + const std::string& model = findDataFile("dnn/layers/layer_convolution.bin"); + const std::string& proto = findDataFile("dnn/layers/layer_convolution.xml"); if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019) setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API); @@ -712,12 +718,14 @@ TEST_P(Test_Model_Optimizer, readFromBuffer) const Backend backendId = get<0>(GetParam()); const Target targetId = get<1>(GetParam()); + if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); + if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) throw SkipTestException("No support for async forward"); - const std::string suffix = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? "_fp16" : ""; - const std::string& weightsFile = findDataFile("dnn/layers/layer_convolution" + suffix + ".bin"); - const std::string& modelFile = findDataFile("dnn/layers/layer_convolution" + suffix + ".xml"); + const std::string& weightsFile = findDataFile("dnn/layers/layer_convolution.bin"); + const std::string& modelFile = findDataFile("dnn/layers/layer_convolution.xml"); if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019) setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API); @@ -765,8 +773,11 @@ TEST_P(Test_Model_Optimizer, flexible_inputs) const Backend backendId = get<0>(GetParam()); const Target targetId = get<1>(GetParam()); - const std::string& model = findDataFile("dnn/layers/layer_convolution_fp16.bin"); - const std::string& proto = findDataFile("dnn/layers/layer_convolution_fp16.xml"); + if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); + + const std::string& model = findDataFile("dnn/layers/layer_convolution.bin"); + const std::string& proto = findDataFile("dnn/layers/layer_convolution.xml"); if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019) setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API); From f2ca7e664abec047171a1d233a322de703034328 Mon Sep 17 00:00:00 2001 From: danielenricocahall Date: Sun, 2 Aug 2020 16:12:13 -0400 Subject: [PATCH 11/21] add python binding and tests for composePanorama fix tests pick 54039c2afd add python binding and tests for composePanorama --- .../stitching/include/opencv2/stitching.hpp | 2 +- .../misc/python/test/test_stitching.py | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/modules/stitching/include/opencv2/stitching.hpp b/modules/stitching/include/opencv2/stitching.hpp index 07e1b5f73a..52789156b8 100644 --- a/modules/stitching/include/opencv2/stitching.hpp +++ b/modules/stitching/include/opencv2/stitching.hpp @@ -264,7 +264,7 @@ public: @param pano Final pano. @return Status code. */ - Status composePanorama(InputArrayOfArrays images, OutputArray pano); + CV_WRAP Status composePanorama(InputArrayOfArrays images, OutputArray pano); /** @overload */ CV_WRAP Status stitch(InputArrayOfArrays images, OutputArray pano); diff --git a/modules/stitching/misc/python/test/test_stitching.py b/modules/stitching/misc/python/test/test_stitching.py index 3a5a99a590..e6fbf9ad0b 100644 --- a/modules/stitching/misc/python/test/test_stitching.py +++ b/modules/stitching/misc/python/test/test_stitching.py @@ -19,5 +19,36 @@ class stitching_test(NewOpenCVTests): self.assertAlmostEqual(pano.shape[0], 685, delta=100, msg="rows: %r" % list(pano.shape)) self.assertAlmostEqual(pano.shape[1], 1025, delta=100, msg="cols: %r" % list(pano.shape)) + +class stitching_compose_panorama_test_no_args(NewOpenCVTests): + + def test_simple(self): + + img1 = self.get_sample('stitching/a1.png') + img2 = self.get_sample('stitching/a2.png') + + stitcher = cv.createStitcher(False) + + stitcher.estimateTransform((img1, img2)) + + result, _ = stitcher.composePanorama() + + assert result == 0 + + +class stitching_compose_panorama_args(NewOpenCVTests): + + def test_simple(self): + + img1 = self.get_sample('stitching/a1.png') + img2 = self.get_sample('stitching/a2.png') + + stitcher = cv.createStitcher(False) + + stitcher.estimateTransform((img1, img2)) + result, _ = stitcher.composePanorama((img1, img2)) + + assert result == 0 + if __name__ == '__main__': NewOpenCVTests.bootstrap() From c262eea84a140cb9590274401cbbdb1e17ec3047 Mon Sep 17 00:00:00 2001 From: Suleyman TURKMEN Date: Sun, 2 Aug 2020 13:33:23 +0300 Subject: [PATCH 12/21] Update warpPerspective_demo.cpp --- modules/imgproc/include/opencv2/imgproc.hpp | 2 +- samples/cpp/warpPerspective_demo.cpp | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/modules/imgproc/include/opencv2/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc.hpp index 962501b62d..bb6284b7b5 100644 --- a/modules/imgproc/include/opencv2/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc.hpp @@ -2263,7 +2263,7 @@ CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst, const Scalar& borderValue = Scalar()); /** @example samples/cpp/warpPerspective_demo.cpp -An example program shows using cv::findHomography and cv::warpPerspective for image warping +An example program shows using cv::getPerspectiveTransform and cv::warpPerspective for image warping */ /** @brief Applies a perspective transformation to an image. diff --git a/samples/cpp/warpPerspective_demo.cpp b/samples/cpp/warpPerspective_demo.cpp index 4a9069f5d2..947abd4359 100644 --- a/samples/cpp/warpPerspective_demo.cpp +++ b/samples/cpp/warpPerspective_demo.cpp @@ -8,7 +8,6 @@ #include "opencv2/imgproc.hpp" #include "opencv2/imgcodecs.hpp" #include "opencv2/highgui.hpp" -#include "opencv2/calib3d.hpp" #include using namespace std; @@ -36,6 +35,7 @@ Mat warping(Mat image, Size warped_image_size, vector< Point2f> srcPoints, vecto String windowTitle = "Perspective Transformation Demo"; String labels[4] = { "TL","TR","BR","BL" }; vector< Point2f> roi_corners; +vector< Point2f> midpoints(4); vector< Point2f> dst_corners(4); int roiIndex = 0; bool dragging; @@ -99,21 +99,26 @@ int main(int argc, char** argv) imshow( windowTitle, image ); + midpoints[0] = (roi_corners[0] + roi_corners[1]) / 2; + midpoints[1] = (roi_corners[1] + roi_corners[2]) / 2; + midpoints[2] = (roi_corners[2] + roi_corners[3]) / 2; + midpoints[3] = (roi_corners[3] + roi_corners[0]) / 2; + dst_corners[0].x = 0; dst_corners[0].y = 0; - dst_corners[1].x = (float)std::max(norm(roi_corners[0] - roi_corners[1]), norm(roi_corners[2] - roi_corners[3])); + dst_corners[1].x = (float)norm(midpoints[1] - midpoints[3]); dst_corners[1].y = 0; - dst_corners[2].x = (float)std::max(norm(roi_corners[0] - roi_corners[1]), norm(roi_corners[2] - roi_corners[3])); - dst_corners[2].y = (float)std::max(norm(roi_corners[1] - roi_corners[2]), norm(roi_corners[3] - roi_corners[0])); + dst_corners[2].x = dst_corners[1].x; + dst_corners[2].y = (float)norm(midpoints[0] - midpoints[2]); dst_corners[3].x = 0; - dst_corners[3].y = (float)std::max(norm(roi_corners[1] - roi_corners[2]), norm(roi_corners[3] - roi_corners[0])); + dst_corners[3].y = dst_corners[2].y; Size warped_image_size = Size(cvRound(dst_corners[2].x), cvRound(dst_corners[2].y)); - Mat H = findHomography(roi_corners, dst_corners); //get homography + Mat M = getPerspectiveTransform(roi_corners, dst_corners); Mat warped_image; - warpPerspective(original_image, warped_image, H, warped_image_size); // do perspective transformation + warpPerspective(original_image, warped_image, M, warped_image_size); // do perspective transformation imshow("Warped Image", warped_image); } From 922108060d48742ff4f2397af9bf8d89c87acab9 Mon Sep 17 00:00:00 2001 From: Yosshi999 Date: Mon, 3 Aug 2020 23:11:55 +0900 Subject: [PATCH 13/21] Merge pull request #17907 from Yosshi999:gsoc_asift-py2cpp * Implement ASIFT in C++ * '>>' should be '> >' within a nested template * add a sample for asift usage * bugfix empty keypoints cause crash * simpler initialization for mask * suppress the number of lines * correct tex document * type casting * add descriptorsize for asift * smaller testdata for asift * more smaller test data * add OpenCV short license header --- doc/opencv.bib | 10 + .../features2d/include/opencv2/features2d.hpp | 25 ++ modules/features2d/src/affine_feature.cpp | 358 ++++++++++++++++++ .../features2d/test/test_affine_feature.cpp | 185 +++++++++ samples/cpp/asift.cpp | 199 ++++++++++ 5 files changed, 777 insertions(+) create mode 100644 modules/features2d/src/affine_feature.cpp create mode 100644 modules/features2d/test/test_affine_feature.cpp create mode 100644 samples/cpp/asift.cpp diff --git a/doc/opencv.bib b/doc/opencv.bib index bdfbc8cf1e..975630a18d 100644 --- a/doc/opencv.bib +++ b/doc/opencv.bib @@ -584,6 +584,16 @@ pages = {1033--1040}, publisher = {IEEE} } +@article{YM11, + author = {Yu, Guoshen and Morel, Jean-Michel}, + title = {ASIFT: An Algorithm for Fully Affine Invariant Comparison}, + year = {2011}, + pages = {11--38}, + journal = {Image Processing On Line}, + volume = {1}, + doi = {10.5201/ipol.2011.my-asift}, + url = {http://www.ipol.im/pub/algo/my_affine_sift/} +} @inproceedings{LCS11, author = {Leutenegger, Stefan and Chli, Margarita and Siegwart, Roland Yves}, title = {BRISK: Binary robust invariant scalable keypoints}, diff --git a/modules/features2d/include/opencv2/features2d.hpp b/modules/features2d/include/opencv2/features2d.hpp index d588d75c14..c4befc9a00 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -245,6 +245,31 @@ typedef Feature2D DescriptorExtractor; //! @{ +/** @brief Class for implementing the wrapper which makes detectors and extractors to be affine invariant, +described as ASIFT in @cite YM11 . +*/ +class CV_EXPORTS_W AffineFeature : public Feature2D +{ +public: + /** + @param backend The detector/extractor you want to use as backend. + @param maxTilt The highest power index of tilt factor. 5 is used in the paper as tilt sampling range n. + @param minTilt The lowest power index of tilt factor. 0 is used in the paper. + @param tiltStep Tilt sampling step \f$\delta_t\f$ in Algorithm 1 in the paper. + @param rotateStepBase Rotation sampling step factor b in Algorithm 1 in the paper. + */ + CV_WRAP static Ptr create(const Ptr& backend, + int maxTilt = 5, int minTilt = 0, float tiltStep = 1.4142135623730951f, float rotateStepBase = 72); + + CV_WRAP virtual void setViewParams(const std::vector& tilts, const std::vector& rolls) = 0; + CV_WRAP virtual void getViewParams(std::vector& tilts, std::vector& rolls) const = 0; + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; +}; + +typedef AffineFeature AffineFeatureDetector; +typedef AffineFeature AffineDescriptorExtractor; + + /** @brief Class for extracting keypoints and computing descriptors using the Scale Invariant Feature Transform (SIFT) algorithm by D. Lowe @cite Lowe04 . */ diff --git a/modules/features2d/src/affine_feature.cpp b/modules/features2d/src/affine_feature.cpp new file mode 100644 index 0000000000..41518d945d --- /dev/null +++ b/modules/features2d/src/affine_feature.cpp @@ -0,0 +1,358 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// This file is based on code issued with the following license. +/********************************************************************* +* Software License Agreement (BSD License) +* +* Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +* Copyright (C) 2008-2013, Willow Garage Inc., all rights reserved. +* Copyright (C) 2013, Evgeny Toropov, all rights reserved. +* Third party copyrights are property of their respective owners. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided +* with the distribution. +* * The name of the copyright holders may not be used to endorse +* or promote products derived from this software without specific +* prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*********************************************************************/ + +/* + Guoshen Yu, Jean-Michel Morel, ASIFT: An Algorithm for Fully Affine + Invariant Comparison, Image Processing On Line, 1 (2011), pp. 11–38. + https://doi.org/10.5201/ipol.2011.my-asift + */ + +#include "precomp.hpp" +#include +namespace cv { + +class AffineFeature_Impl CV_FINAL : public AffineFeature +{ +public: + explicit AffineFeature_Impl(const Ptr& backend, + int maxTilt, int minTilt, float tiltStep, float rotateStepBase); + + int descriptorSize() const CV_OVERRIDE + { + return backend_->descriptorSize(); + } + + int descriptorType() const CV_OVERRIDE + { + return backend_->descriptorType(); + } + + int defaultNorm() const CV_OVERRIDE + { + return backend_->defaultNorm(); + } + + void detectAndCompute(InputArray image, InputArray mask, std::vector& keypoints, + OutputArray descriptors, bool useProvidedKeypoints=false) CV_OVERRIDE; + + void setViewParams(const std::vector& tilts, const std::vector& rolls) CV_OVERRIDE; + void getViewParams(std::vector& tilts, std::vector& rolls) const CV_OVERRIDE; + +protected: + void splitKeypointsByView(const std::vector& keypoints_, + std::vector< std::vector >& keypointsByView) const; + + const Ptr backend_; + int maxTilt_; + int minTilt_; + float tiltStep_; + float rotateStepBase_; + + // Tilt factors. + std::vector tilts_; + // Roll factors. + std::vector rolls_; + +private: + AffineFeature_Impl(const AffineFeature_Impl &); // copy disabled + AffineFeature_Impl& operator=(const AffineFeature_Impl &); // assign disabled +}; + +AffineFeature_Impl::AffineFeature_Impl(const Ptr& backend, + int maxTilt, int minTilt, float tiltStep, float rotateStepBase) + : backend_(backend), maxTilt_(maxTilt), minTilt_(minTilt), tiltStep_(tiltStep), rotateStepBase_(rotateStepBase) +{ + int i = minTilt_; + if( i == 0 ) + { + tilts_.push_back(1); + rolls_.push_back(0); + i++; + } + float tilt = 1; + for( ; i <= maxTilt_; i++ ) + { + tilt *= tiltStep_; + float rotateStep = rotateStepBase_ / tilt; + int rollN = cvFloor(180.0f / rotateStep); + if( rollN * rotateStep == 180.0f ) + rollN--; + for( int j = 0; j <= rollN; j++ ) + { + tilts_.push_back(tilt); + rolls_.push_back(rotateStep * j); + } + } +} + +void AffineFeature_Impl::setViewParams(const std::vector& tilts, + const std::vector& rolls) +{ + CV_Assert(tilts.size() == rolls.size()); + tilts_ = tilts; + rolls_ = rolls; +} + +void AffineFeature_Impl::getViewParams(std::vector& tilts, + std::vector& rolls) const +{ + tilts = tilts_; + rolls = rolls_; +} + +void AffineFeature_Impl::splitKeypointsByView(const std::vector& keypoints_, + std::vector< std::vector >& keypointsByView) const +{ + for( size_t i = 0; i < keypoints_.size(); i++ ) + { + const KeyPoint& kp = keypoints_[i]; + CV_Assert( kp.class_id >= 0 && kp.class_id < (int)tilts_.size() ); + keypointsByView[kp.class_id].push_back(kp); + } +} + +class skewedDetectAndCompute : public ParallelLoopBody +{ +public: + skewedDetectAndCompute( + const std::vector& _tilts, + const std::vector& _rolls, + std::vector< std::vector >& _keypointsCollection, + std::vector& _descriptorCollection, + const Mat& _image, + const Mat& _mask, + const bool _do_keypoints, + const bool _do_descriptors, + const Ptr& _backend) + : tilts(_tilts), + rolls(_rolls), + keypointsCollection(_keypointsCollection), + descriptorCollection(_descriptorCollection), + image(_image), + mask(_mask), + do_keypoints(_do_keypoints), + do_descriptors(_do_descriptors), + backend(_backend) {} + + void operator()( const cv::Range& range ) const CV_OVERRIDE + { + CV_TRACE_FUNCTION(); + + const int begin = range.start; + const int end = range.end; + + for( int a = begin; a < end; a++ ) + { + Mat warpedImage, warpedMask; + Matx23f pose, invPose; + affineSkew(tilts[a], rolls[a], warpedImage, warpedMask, pose); + invertAffineTransform(pose, invPose); + + std::vector wKeypoints; + Mat wDescriptors; + if( !do_keypoints ) + { + const std::vector& keypointsInView = keypointsCollection[a]; + if( keypointsInView.size() == 0 ) // when there are no keypoints in this affine view + continue; + + std::vector pts_, pts; + KeyPoint::convert(keypointsInView, pts_); + transform(pts_, pts, pose); + wKeypoints.resize(keypointsInView.size()); + for( size_t wi = 0; wi < wKeypoints.size(); wi++ ) + { + wKeypoints[wi] = keypointsInView[wi]; + wKeypoints[wi].pt = pts[wi]; + } + } + backend->detectAndCompute(warpedImage, warpedMask, wKeypoints, wDescriptors, !do_keypoints); + if( do_keypoints ) + { + // KeyPointsFilter::runByPixelsMask( wKeypoints, warpedMask ); + if( wKeypoints.size() == 0 ) + { + keypointsCollection[a].clear(); + continue; + } + std::vector pts_, pts; + KeyPoint::convert(wKeypoints, pts_); + transform(pts_, pts, invPose); + + keypointsCollection[a].resize(wKeypoints.size()); + for( size_t wi = 0; wi < wKeypoints.size(); wi++ ) + { + keypointsCollection[a][wi] = wKeypoints[wi]; + keypointsCollection[a][wi].pt = pts[wi]; + keypointsCollection[a][wi].class_id = a; + } + } + if( do_descriptors ) + wDescriptors.copyTo(descriptorCollection[a]); + } + } +private: + void affineSkew(float tilt, float phi, + Mat& warpedImage, Mat& warpedMask, Matx23f& pose) const + { + int h = image.size().height; + int w = image.size().width; + Mat rotImage; + + Mat mask0; + if( mask.empty() ) + mask0 = Mat(h, w, CV_8UC1, 255); + else + mask0 = mask; + pose = Matx23f(1,0,0, + 0,1,0); + + if( phi == 0 ) + image.copyTo(rotImage); + else + { + phi = phi * (float)CV_PI / 180; + float s = std::sin(phi); + float c = std::cos(phi); + Matx22f A(c, -s, s, c); + Matx corners(0, 0, (float)w, 0, (float)w,(float)h, 0, (float)h); + Mat tf(corners * A.t()); + Mat tcorners; + tf.convertTo(tcorners, CV_32S); + Rect rect = boundingRect(tcorners); + h = rect.height; w = rect.width; + pose = Matx23f(c, -s, -(float)rect.x, + s, c, -(float)rect.y); + warpAffine(image, rotImage, pose, Size(w, h), INTER_LINEAR, BORDER_REPLICATE); + } + if( tilt == 1 ) + warpedImage = rotImage; + else + { + float s = 0.8f * sqrt(tilt * tilt - 1); + GaussianBlur(rotImage, rotImage, Size(0, 0), s, 0.01); + resize(rotImage, warpedImage, Size(0, 0), 1.0/tilt, 1.0, INTER_NEAREST); + pose(0, 0) /= tilt; + pose(0, 1) /= tilt; + pose(0, 2) /= tilt; + } + if( phi != 0 || tilt != 1 ) + warpAffine(mask0, warpedMask, pose, warpedImage.size(), INTER_NEAREST); + } + + + const std::vector& tilts; + const std::vector& rolls; + std::vector< std::vector >& keypointsCollection; + std::vector& descriptorCollection; + const Mat& image; + const Mat& mask; + const bool do_keypoints; + const bool do_descriptors; + const Ptr& backend; +}; + +void AffineFeature_Impl::detectAndCompute(InputArray _image, InputArray _mask, + std::vector& keypoints, + OutputArray _descriptors, + bool useProvidedKeypoints) +{ + CV_TRACE_FUNCTION(); + + bool do_keypoints = !useProvidedKeypoints; + bool do_descriptors = _descriptors.needed(); + Mat image = _image.getMat(), mask = _mask.getMat(); + Mat descriptors; + + if( (!do_keypoints && !do_descriptors) || _image.empty() ) + return; + + std::vector< std::vector > keypointsCollection(tilts_.size()); + std::vector< Mat > descriptorCollection(tilts_.size()); + + if( do_keypoints ) + keypoints.clear(); + else + splitKeypointsByView(keypoints, keypointsCollection); + + parallel_for_(Range(0, (int)tilts_.size()), skewedDetectAndCompute(tilts_, rolls_, keypointsCollection, descriptorCollection, + image, mask, do_keypoints, do_descriptors, backend_)); + + if( do_keypoints ) + for( size_t i = 0; i < keypointsCollection.size(); i++ ) + { + const std::vector& keys = keypointsCollection[i]; + keypoints.insert(keypoints.end(), keys.begin(), keys.end()); + } + + if( do_descriptors ) + { + _descriptors.create((int)keypoints.size(), backend_->descriptorSize(), backend_->descriptorType()); + descriptors = _descriptors.getMat(); + int iter = 0; + for( size_t i = 0; i < descriptorCollection.size(); i++ ) + { + const Mat& descs = descriptorCollection[i]; + if( descs.empty() ) + continue; + Mat roi(descriptors, Rect(0, iter, descriptors.cols, descs.rows)); + descs.copyTo(roi); + iter += descs.rows; + } + } +} + + +Ptr AffineFeature::create(const Ptr& backend, + int maxTilt, int minTilt, float tiltStep, float rotateStepBase) +{ + CV_Assert(minTilt < maxTilt); + CV_Assert(tiltStep > 0); + CV_Assert(rotateStepBase > 0); + return makePtr(backend, maxTilt, minTilt, tiltStep, rotateStepBase); +} + +String AffineFeature::getDefaultName() const +{ + return (Feature2D::getDefaultName() + ".AffineFeature"); +} + +} // namespace diff --git a/modules/features2d/test/test_affine_feature.cpp b/modules/features2d/test/test_affine_feature.cpp new file mode 100644 index 0000000000..f40f21ed8d --- /dev/null +++ b/modules/features2d/test/test_affine_feature.cpp @@ -0,0 +1,185 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + +#include "test_precomp.hpp" + +// #define GENERATE_DATA // generate data in debug mode + +namespace opencv_test { namespace { + +#ifndef GENERATE_DATA +static bool isSimilarKeypoints( const KeyPoint& p1, const KeyPoint& p2 ) +{ + const float maxPtDif = 1.f; + const float maxSizeDif = 1.f; + const float maxAngleDif = 2.f; + const float maxResponseDif = 0.1f; + + float dist = (float)cv::norm( p1.pt - p2.pt ); + return (dist < maxPtDif && + fabs(p1.size - p2.size) < maxSizeDif && + abs(p1.angle - p2.angle) < maxAngleDif && + abs(p1.response - p2.response) < maxResponseDif && + (p1.octave & 0xffff) == (p2.octave & 0xffff) // do not care about sublayers and class_id + ); +} +#endif + +TEST(Features2d_AFFINE_FEATURE, regression) +{ + Mat image = imread(cvtest::findDataFile("features2d/tsukuba.png")); + string xml = cvtest::TS::ptr()->get_data_path() + "asift/regression_cpp.xml.gz"; + ASSERT_FALSE(image.empty()); + + Mat gray; + cvtColor(image, gray, COLOR_BGR2GRAY); + + // Default ASIFT generates too large descriptors. This test uses small maxTilt to suppress the size of testdata. + Ptr ext = AffineFeature::create(SIFT::create(), 2, 0, 1.4142135623730951f, 144.0f); + Mat mpt, msize, mangle, mresponse, moctave, mclass_id; +#ifdef GENERATE_DATA + // calculate + vector calcKeypoints; + Mat calcDescriptors; + ext->detectAndCompute(gray, Mat(), calcKeypoints, calcDescriptors, false); + + // create keypoints XML + FileStorage fs(xml, FileStorage::WRITE); + ASSERT_TRUE(fs.isOpened()) << xml; + std::cout << "Creating keypoints XML..." << std::endl; + + mpt = Mat(calcKeypoints.size(), 2, CV_32F); + msize = Mat(calcKeypoints.size(), 1, CV_32F); + mangle = Mat(calcKeypoints.size(), 1, CV_32F); + mresponse = Mat(calcKeypoints.size(), 1, CV_32F); + moctave = Mat(calcKeypoints.size(), 1, CV_32S); + mclass_id = Mat(calcKeypoints.size(), 1, CV_32S); + + for( size_t i = 0; i < calcKeypoints.size(); i++ ) + { + const KeyPoint& key = calcKeypoints[i]; + mpt.at(i, 0) = key.pt.x; + mpt.at(i, 1) = key.pt.y; + msize.at(i, 0) = key.size; + mangle.at(i, 0) = key.angle; + mresponse.at(i, 0) = key.response; + moctave.at(i, 0) = key.octave; + mclass_id.at(i, 0) = key.class_id; + } + + fs << "keypoints_pt" << mpt; + fs << "keypoints_size" << msize; + fs << "keypoints_angle" << mangle; + fs << "keypoints_response" << mresponse; + fs << "keypoints_octave" << moctave; + fs << "keypoints_class_id" << mclass_id; + + // create descriptor XML + fs << "descriptors" << calcDescriptors; + fs.release(); +#else + const float badCountsRatio = 0.01f; + const float badDescriptorDist = 1.0f; + const float maxBadKeypointsRatio = 0.15f; + const float maxBadDescriptorRatio = 0.15f; + + // read keypoints + vector validKeypoints; + Mat validDescriptors; + FileStorage fs(xml, FileStorage::READ); + ASSERT_TRUE(fs.isOpened()) << xml; + + fs["keypoints_pt"] >> mpt; + ASSERT_EQ(mpt.type(), CV_32F); + fs["keypoints_size"] >> msize; + ASSERT_EQ(msize.type(), CV_32F); + fs["keypoints_angle"] >> mangle; + ASSERT_EQ(mangle.type(), CV_32F); + fs["keypoints_response"] >> mresponse; + ASSERT_EQ(mresponse.type(), CV_32F); + fs["keypoints_octave"] >> moctave; + ASSERT_EQ(moctave.type(), CV_32S); + fs["keypoints_class_id"] >> mclass_id; + ASSERT_EQ(mclass_id.type(), CV_32S); + + validKeypoints.resize(mpt.rows); + for( int i = 0; i < (int)validKeypoints.size(); i++ ) + { + validKeypoints[i].pt.x = mpt.at(i, 0); + validKeypoints[i].pt.y = mpt.at(i, 1); + validKeypoints[i].size = msize.at(i, 0); + validKeypoints[i].angle = mangle.at(i, 0); + validKeypoints[i].response = mresponse.at(i, 0); + validKeypoints[i].octave = moctave.at(i, 0); + validKeypoints[i].class_id = mclass_id.at(i, 0); + } + + // read descriptors + fs["descriptors"] >> validDescriptors; + fs.release(); + + // calc and compare keypoints + vector calcKeypoints; + ext->detectAndCompute(gray, Mat(), calcKeypoints, noArray(), false); + + float countRatio = (float)validKeypoints.size() / (float)calcKeypoints.size(); + ASSERT_LT(countRatio, 1 + badCountsRatio) << "Bad keypoints count ratio."; + ASSERT_GT(countRatio, 1 - badCountsRatio) << "Bad keypoints count ratio."; + + int badPointCount = 0, commonPointCount = max((int)validKeypoints.size(), (int)calcKeypoints.size()); + for( size_t v = 0; v < validKeypoints.size(); v++ ) + { + int nearestIdx = -1; + float minDist = std::numeric_limits::max(); + float angleDistOfNearest = std::numeric_limits::max(); + + for( size_t c = 0; c < calcKeypoints.size(); c++ ) + { + if( validKeypoints[v].class_id != calcKeypoints[c].class_id ) + continue; + float curDist = (float)cv::norm( calcKeypoints[c].pt - validKeypoints[v].pt ); + if( curDist < minDist ) + { + minDist = curDist; + nearestIdx = (int)c; + angleDistOfNearest = abs( calcKeypoints[c].angle - validKeypoints[v].angle ); + } + else if( curDist == minDist ) // the keypoints whose positions are same but angles are different + { + float angleDist = abs( calcKeypoints[c].angle - validKeypoints[v].angle ); + if( angleDist < angleDistOfNearest ) + { + nearestIdx = (int)c; + angleDistOfNearest = angleDist; + } + } + } + if( nearestIdx == -1 || !isSimilarKeypoints( validKeypoints[v], calcKeypoints[nearestIdx] ) ) + badPointCount++; + } + float badKeypointsRatio = (float)badPointCount / (float)commonPointCount; + std::cout << "badKeypointsRatio: " << badKeypointsRatio << std::endl; + ASSERT_LT( badKeypointsRatio , maxBadKeypointsRatio ) << "Bad accuracy!"; + + // Calc and compare descriptors. This uses validKeypoints for extraction. + Mat calcDescriptors; + ext->detectAndCompute(gray, Mat(), validKeypoints, calcDescriptors, true); + + int dim = validDescriptors.cols; + int badDescriptorCount = 0; + L1 distance; + + for( int i = 0; i < (int)validKeypoints.size(); i++ ) + { + float dist = distance( validDescriptors.ptr(i), calcDescriptors.ptr(i), dim ); + if( dist > badDescriptorDist ) + badDescriptorCount++; + } + float badDescriptorRatio = (float)badDescriptorCount / (float)validKeypoints.size(); + std::cout << "badDescriptorRatio: " << badDescriptorRatio << std::endl; + ASSERT_LT( badDescriptorRatio, maxBadDescriptorRatio ) << "Too many descriptors mismatched."; +#endif +} + +}} // namespace diff --git a/samples/cpp/asift.cpp b/samples/cpp/asift.cpp new file mode 100644 index 0000000000..568954058d --- /dev/null +++ b/samples/cpp/asift.cpp @@ -0,0 +1,199 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace cv; + +static void help(char** argv) +{ + cout + << "This is a sample usage of AffineFeature detector/extractor.\n" + << "And this is a C++ version of samples/python/asift.py\n" + << "Usage: " << argv[0] << "\n" + << " [ --feature= ] # Feature to use.\n" + << " [ --flann ] # use Flann-based matcher instead of bruteforce.\n" + << " [ --maxlines= ] # The maximum number of lines in visualizing the matching result.\n" + << " [ --image1= ]\n" + << " [ --image2= ] # Path to images to compare." + << endl; +} + +static double timer() +{ + return getTickCount() / getTickFrequency(); +} + +int main(int argc, char** argv) +{ + vector fileName; + cv::CommandLineParser parser(argc, argv, + "{help h ||}" + "{feature|brisk|}" + "{flann||}" + "{maxlines|50|}" + "{image1|aero1.jpg|}{image2|aero3.jpg|}"); + if (parser.has("help")) + { + help(argv); + return 0; + } + string feature = parser.get("feature"); + bool useFlann = parser.has("flann"); + int maxlines = parser.get("maxlines"); + fileName.push_back(samples::findFile(parser.get("image1"))); + fileName.push_back(samples::findFile(parser.get("image2"))); + if (!parser.check()) + { + parser.printErrors(); + cout << "See --help (or missing '=' between argument name and value?)" << endl; + return 1; + } + + Mat img1 = imread(fileName[0], IMREAD_GRAYSCALE); + Mat img2 = imread(fileName[1], IMREAD_GRAYSCALE); + if (img1.empty()) + { + cerr << "Image " << fileName[0] << " is empty or cannot be found" << endl; + return 1; + } + if (img2.empty()) + { + cerr << "Image " << fileName[1] << " is empty or cannot be found" << endl; + return 1; + } + + Ptr backend; + Ptr matcher; + + if (feature == "sift") + { + backend = SIFT::create(); + if (useFlann) + matcher = DescriptorMatcher::create("FlannBased"); + else + matcher = DescriptorMatcher::create("BruteForce"); + } + else if (feature == "orb") + { + backend = ORB::create(); + if (useFlann) + matcher = makePtr(makePtr(6, 12, 1)); + else + matcher = DescriptorMatcher::create("BruteForce-Hamming"); + } + else if (feature == "brisk") + { + backend = BRISK::create(); + if (useFlann) + matcher = makePtr(makePtr(6, 12, 1)); + else + matcher = DescriptorMatcher::create("BruteForce-Hamming"); + } + else + { + cerr << feature << " is not supported. See --help" << endl; + return 1; + } + + cout << "extracting with " << feature << "..." << endl; + Ptr ext = AffineFeature::create(backend); + vector kp1, kp2; + Mat desc1, desc2; + + ext->detectAndCompute(img1, Mat(), kp1, desc1); + ext->detectAndCompute(img2, Mat(), kp2, desc2); + cout << "img1 - " << kp1.size() << " features, " + << "img2 - " << kp2.size() << " features" + << endl; + + cout << "matching with " << (useFlann ? "flann" : "bruteforce") << "..." << endl; + double start = timer(); + // match and draw + vector< vector > rawMatches; + vector p1, p2; + vector distances; + matcher->knnMatch(desc1, desc2, rawMatches, 2); + // filter_matches + for (size_t i = 0; i < rawMatches.size(); i++) + { + const vector& m = rawMatches[i]; + if (m.size() == 2 && m[0].distance < m[1].distance * 0.75) + { + p1.push_back(kp1[m[0].queryIdx].pt); + p2.push_back(kp2[m[0].trainIdx].pt); + distances.push_back(m[0].distance); + } + } + vector status; + vector< pair > pointPairs; + Mat H = findHomography(p1, p2, status, RANSAC); + int inliers = 0; + for (size_t i = 0; i < status.size(); i++) + { + if (status[i]) + { + pointPairs.push_back(make_pair(p1[i], p2[i])); + distances[inliers] = distances[i]; + // CV_Assert(inliers <= (int)i); + inliers++; + } + } + distances.resize(inliers); + + cout << "execution time: " << fixed << setprecision(2) << (timer()-start)*1000 << " ms" << endl; + cout << inliers << " / " << status.size() << " inliers/matched" << endl; + + cout << "visualizing..." << endl; + vector indices(inliers); + cv::sortIdx(distances, indices, SORT_EVERY_ROW+SORT_ASCENDING); + + // explore_match + int h1 = img1.size().height; + int w1 = img1.size().width; + int h2 = img2.size().height; + int w2 = img2.size().width; + Mat vis = Mat::zeros(max(h1, h2), w1+w2, CV_8U); + img1.copyTo(Mat(vis, Rect(0, 0, w1, h1))); + img2.copyTo(Mat(vis, Rect(w1, 0, w2, h2))); + cvtColor(vis, vis, COLOR_GRAY2BGR); + + vector corners(4); + corners[0] = Point2f(0, 0); + corners[1] = Point2f((float)w1, 0); + corners[2] = Point2f((float)w1, (float)h1); + corners[3] = Point2f(0, (float)h1); + vector icorners; + perspectiveTransform(corners, corners, H); + transform(corners, corners, Matx23f(1,0,(float)w1,0,1,0)); + Mat(corners).convertTo(icorners, CV_32S); + polylines(vis, icorners, true, Scalar(255,255,255)); + + for (int i = 0; i < min(inliers, maxlines); i++) + { + int idx = indices[i]; + const Point2f& pi1 = pointPairs[idx].first; + const Point2f& pi2 = pointPairs[idx].second; + circle(vis, pi1, 2, Scalar(0,255,0), -1); + circle(vis, pi2 + Point2f((float)w1,0), 2, Scalar(0,255,0), -1); + line(vis, pi1, pi2 + Point2f((float)w1,0), Scalar(0,255,0)); + } + if (inliers > maxlines) + cout << "only " << maxlines << " inliers are visualized" << endl; + imshow("affine find_obj", vis); + + // Mat vis2 = Mat::zeros(max(h1, h2), w1+w2, CV_8U); + // Mat warp1; + // warpPerspective(img1, warp1, H, Size(w1, h1)); + // warp1.copyTo(Mat(vis2, Rect(0, 0, w1, h1))); + // img2.copyTo(Mat(vis2, Rect(w1, 0, w2, h2))); + // imshow("warped", vis2); + + waitKey(); + cout << "done" << endl; + return 0; +} From 1c8ee3f957f1d8bcb9ac051f0068b9d3aca00856 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Mon, 3 Aug 2020 17:13:34 +0300 Subject: [PATCH 14/21] Merge pull request #17885 from alalek:dnn_ocl_slice_update DNN: OpenCL/slice update * dnn(ocl/slice): make slice kernel VTune friendly - more unique names - inline code of copy functions * dnn(ocl/slice): prefer to spawn more work groups - even in case with 1D copy - perf improvement up to 2x of kernel time (due to changed configuration 128x1x1 => 128x32x1) * dnn(ocl/slice): cache kernel exec info --- modules/dnn/src/layers/slice_layer.cpp | 129 ++++++++++++++--- modules/dnn/src/opencl/slice.cl | 191 +++++++++++-------------- 2 files changed, 196 insertions(+), 124 deletions(-) diff --git a/modules/dnn/src/layers/slice_layer.cpp b/modules/dnn/src/layers/slice_layer.cpp index d7d541474e..9994677cb5 100644 --- a/modules/dnn/src/layers/slice_layer.cpp +++ b/modules/dnn/src/layers/slice_layer.cpp @@ -160,6 +160,10 @@ public: void finalize(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr) CV_OVERRIDE { +#ifdef HAVE_OPENCL + ocl_exec_cache.clear(); +#endif + std::vector inputs, outputs; inputs_arr.getMatVector(inputs); outputs_arr.getMatVector(outputs); @@ -214,26 +218,33 @@ public: } #ifdef HAVE_OPENCL - bool forward_ocl(InputArrayOfArrays inputs_, OutputArrayOfArrays outputs_, OutputArrayOfArrays internals_) + struct OpenCLExecInfo { - std::vector inputs; - std::vector outputs; + std::string kernel_name; + std::string build_opts; + size_t local_size[2]; + size_t global_size[2]; - inputs_.getUMatVector(inputs); - outputs_.getUMatVector(outputs); + OpenCLExecInfo() + { + local_size[0] = local_size[1] = 0; + global_size[0] = global_size[1] = 0; + } + }; + std::vector ocl_exec_cache; + + void ocl_prepare(const std::vector& inputs, const std::vector& outputs) + { + CV_TRACE_FUNCTION(); CV_Assert(outputs.size() == finalSliceRanges.size()); + ocl_exec_cache.resize(outputs.size()); const UMat& input = inputs[0]; - if (input.dims > 5) - { - CV_LOG_INFO(NULL, "DNN/OpenCL/Slice: implementation doesn't support dims=" << input.dims << ". Fallback to CPU"); - return false; - } + const int dims = input.dims; size_t WSZ = 128; - const int dims = input.dims; const int elemSize = (int)input.elemSize(); String opts0 = cv::format( "-DDIMS=%d -DELEMSIZE=%d", @@ -243,10 +254,11 @@ public: { opts0 += cv::format(" -DSRC_STEP_%d=%d", d, (int)input.step[dims - 1 - d]); } - String kname = cv::format("slice_%d", dims); for (size_t i = 0; i < outputs.size(); i++) { - UMat& output = outputs[i]; + OpenCLExecInfo& ocl = ocl_exec_cache[i]; + + const UMat& output = outputs[i]; const std::vector& range = finalSliceRanges[i]; String opts = opts0; @@ -262,6 +274,8 @@ public: CV_CheckEQ(range[d].size(), (int)output.size[d], ""); } + const size_t param_LIMIT_BLOCK_SIZE_PER_WG = WSZ * 64; + int block_dims = 0; size_t block_size = elemSize; for (int i = dims - 1; i >= 0; --i) @@ -270,12 +284,14 @@ public: break; block_size *= output.size[i]; block_dims++; + if (block_size >= param_LIMIT_BLOCK_SIZE_PER_WG) + break; } const size_t total = output.total() * elemSize; size_t num_blocks = total / block_size; - if ((num_blocks <= 8 && block_size >= WSZ * 4) || (block_size >= WSZ * 64)) + if ((num_blocks <= 8 && block_size >= WSZ * 4) || (block_size >= param_LIMIT_BLOCK_SIZE_PER_WG)) { // use 1D copy mode opts += cv::format(" -DUSE_COPY_1D=1"); @@ -345,23 +361,98 @@ public: opts += cv::format(" -DWSZ=%d", (int)WSZ); - size_t local[] = { WSZ, 1 }; - size_t global[] = { WSZ, num_blocks }; + std::ostringstream kernel_suffix; + kernel_suffix << dims << 'x' << elemSize << "_bsz" << block_size; + kernel_suffix << "__src_"; + for (int d = 0; d < dims; d++) + { + kernel_suffix << input.size[dims - 1 - d] << '_'; + } + kernel_suffix << '_'; + /*for (int d = 0; d < dims; d++) + { + kernel_suffix << input.step[dims - 1 - d] << '_'; + } + kernel_suffix << '_';*/ - ocl::Kernel kernel(kname.c_str(), ocl::dnn::slice_oclsrc, opts); + kernel_suffix << "dst_"; + for (int d = 0; d < dims; d++) + { + kernel_suffix << output.size[dims - 1 - d] << '_'; + } + /*kernel_suffix << '_'; + for (int d = 0; d < dims; d++) + { + kernel_suffix << output.step[dims - 1 - d] << '_'; + }*/ + kernel_suffix << "_slice_"; + for (int d = 0; d < dims; d++) + { + kernel_suffix << range[dims - 1 - d].start << '_'; + } + for (int d = 0; d < dims; d++) + { + kernel_suffix << '_' << range[dims - 1 - d].end; + } + + std::string kernel_suffix_str = kernel_suffix.str(); + opts += cv::format(" -DSLICE_KERNEL_SUFFIX=%s", kernel_suffix_str.c_str()); + + ocl.kernel_name = cv::format("slice_%s", kernel_suffix_str.c_str()); + ocl.build_opts = opts; + ocl.local_size[0] = WSZ; + ocl.local_size[1] = 1; + ocl.global_size[0] = WSZ; + ocl.global_size[1] = num_blocks; + } // for outputs.size() + } // ocl_prepare + + bool forward_ocl(InputArrayOfArrays inputs_, OutputArrayOfArrays outputs_, OutputArrayOfArrays internals_) + { + CV_TRACE_FUNCTION(); + + std::vector inputs; + std::vector outputs; + + inputs_.getUMatVector(inputs); + outputs_.getUMatVector(outputs); + + CV_Assert(outputs.size() == finalSliceRanges.size()); + + const UMat& input = inputs[0]; + const int dims = input.dims; + if (dims > 5) + { + CV_LOG_INFO(NULL, "DNN/OpenCL/Slice: implementation doesn't support dims=" << dims << ". Fallback to CPU"); + return false; + } + + if (ocl_exec_cache.empty()) + { + ocl_prepare(inputs, outputs); + } + CV_CheckEQ(ocl_exec_cache.size(), outputs.size(), ""); + + for (size_t i = 0; i < outputs.size(); i++) + { + const OpenCLExecInfo& ocl = ocl_exec_cache[i]; + + UMat& output = outputs[i]; + + ocl::Kernel kernel(ocl.kernel_name.c_str(), ocl::dnn::slice_oclsrc, ocl.build_opts); if (kernel.empty()) return false; bool ret = kernel.args( ocl::KernelArg::PtrReadOnly(input), ocl::KernelArg::PtrWriteOnly(output) ) - .run(2, global, local, false); + .run(2, (size_t*)ocl.global_size, (size_t*)ocl.local_size, false); if (!ret) return false; } // for outputs.size() return true; - } + } // forward_ocl #endif void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE diff --git a/modules/dnn/src/opencl/slice.cl b/modules/dnn/src/opencl/slice.cl index d468dbc16a..f32d66a9ca 100644 --- a/modules/dnn/src/opencl/slice.cl +++ b/modules/dnn/src/opencl/slice.cl @@ -48,19 +48,85 @@ global: #define BLOCK_COLS_X4 (BLOCK_COLS / 4) #define BLOCK_COLS_X16 (BLOCK_COLS / 16) -#ifdef USE_COPY_1D - -static inline -__attribute__((always_inline)) -void copy_block_1d( +__attribute__((reqd_work_group_size(WSZ, 1, 1))) +__kernel void +CONCAT(slice_, SLICE_KERNEL_SUFFIX)( __global const uchar* src0, - const uint src_offset, - __global uchar* dst0, - const uint dst_offset + __global uchar* dst0 ) { - __global const uchar* src = src0 + src_offset; - __global uchar* dst = dst0 + dst_offset; + uint block_id = get_global_id(1); + uint dst_offset0 = block_id * BLOCK_SIZE; + uint src_offset0 = 0; + + { // calculate src_offset0 + +#define CALC_SRC_INDEX(dim) \ + { \ + uint plane_sz = CONCAT(DST_STEP_, dim) / BLOCK_SIZE; \ + CONCAT(idx_, dim) = block_id / plane_sz; \ + block_id = block_id - CONCAT(idx_, dim) * plane_sz; \ + } +#define UPDATE_SRC_OFFSET(dim) \ + src_offset0 = mad24((uint)(CONCAT(idx_, dim) + CONCAT(SRC_START_, dim)), (uint)CONCAT(SRC_STEP_, dim), (uint)src_offset0); +/* + if (get_global_id(0) == 0 && get_global_id(1) == 0) \ + printf("(%d, %d): @%d src_offset0=%d idx_dim=%d block_id=%d\n", \ + get_global_id(0), get_global_id(1), \ + dim, src_offset0, CONCAT(idx_, dim), block_id \ + ); +*/ + +#if DIMS > 5 +#error "invalid configuration" +#endif +#if DIMS > 4 + uint idx_4 = 0; +#if BLOCK_DIMS <= 4 + CALC_SRC_INDEX(4) +#endif + UPDATE_SRC_OFFSET(4) +#endif +#if DIMS > 3 + uint idx_3 = 0; +#if BLOCK_DIMS <= 3 + CALC_SRC_INDEX(3) +#endif + UPDATE_SRC_OFFSET(3) +#endif +#if DIMS > 2 + uint idx_2 = 0; +#if BLOCK_DIMS <= 2 + CALC_SRC_INDEX(2) +#endif + UPDATE_SRC_OFFSET(2) +#endif +#if DIMS > 1 + uint idx_1 = 0; +#if BLOCK_DIMS <= 1 + CALC_SRC_INDEX(1) +#endif + UPDATE_SRC_OFFSET(1) +#endif +#if DIMS > 0 + uint idx_0 = 0; + UPDATE_SRC_OFFSET(0) +#endif + +/* + if (get_global_id(0) == 0) + printf("(%d, %d): src_offset0=%d dst_offset0=%d\n", + get_global_id(0), get_global_id(1), + src_offset0, dst_offset0 + ); +*/ + + } // calculate src_offset0 + +#ifdef USE_COPY_1D + { // copy_block_1d + __global const uchar* src = src0 + src_offset0; + __global uchar* dst = dst0 + dst_offset0; uint processed = 0; @@ -70,8 +136,9 @@ void copy_block_1d( uint i = get_local_id(0) * 16; // uchar16 while (i < BLOCK_COLS_X16 * 16) { - uint4 idx = (uint4)(i, i + 16 * WSZ, i + 32 * WSZ, i + 48 * WSZ); - idx = select((uint4)i, idx, idx < (BLOCK_COLS_X16 * 16)); + uint4 idx0 = (uint4)i; + uint4 idx = idx0 + (uint4)(0, 16 * WSZ, 32 * WSZ, 48 * WSZ); + idx = select(idx0, idx, idx < (BLOCK_COLS_X16 * 16)); uchar16 a0 = vload16(0, src + idx.s0); uchar16 a1 = vload16(0, src + idx.s1); @@ -97,8 +164,9 @@ void copy_block_1d( uint i = get_local_id(0) * 4 + processed; // uchar4 while (i < BLOCK_COLS_X4 * 4) { - uint4 idx = (uint4)(i, i + 4 * WSZ, i + 8 * WSZ, i + 12 * WSZ); - idx = select((uint4)i, idx, idx < (BLOCK_COLS_X4 * 4)); + uint4 idx0 = (uint4)i; + uint4 idx = idx0 + (uint4)(0, 4 * WSZ, 8 * WSZ, 12 * WSZ); + idx = select(idx0, idx, idx < (BLOCK_COLS_X4 * 4)); uchar4 a0 = vload4(0, src + idx.s0); uchar4 a1 = vload4(0, src + idx.s1); @@ -130,19 +198,11 @@ void copy_block_1d( } } #endif -} + } // copy_block_1d -#else // USE_COPY_1D +#else -static inline -__attribute__((always_inline)) -void copy_block_2d( - __global const uchar* src0, - const uint src_offset0, - __global uchar* dst0, - const uint dst_offset0 -) -{ + { // copy_block_2d __global const uchar* src = src0 + src_offset0; __global uchar* dst = dst0 + dst_offset0; @@ -199,85 +259,6 @@ void copy_block_2d( #endif // BLOCK_COLS_FILL_X4 != BLOCK_COLS i += WSZ * 4; } -} - -#endif // USE_COPY_1D - -__kernel void -CONCAT(slice_, DIMS)( - __global const uchar* src, - __global uchar* dst -) -{ - uint block_id = get_global_id(1); - - uint dst_offset = block_id * BLOCK_SIZE; - - uint src_offset = 0; - -#define CALC_SRC_INDEX(dim) \ - { \ - uint plane_sz = CONCAT(DST_STEP_, dim) / BLOCK_SIZE; \ - CONCAT(idx_, dim) = block_id / plane_sz; \ - block_id = block_id - CONCAT(idx_, dim) * plane_sz; \ - } -#define UPDATE_SRC_OFFSET(dim) \ - src_offset = mad24((uint)(CONCAT(idx_, dim) + CONCAT(SRC_START_, dim)), (uint)CONCAT(SRC_STEP_, dim), (uint)src_offset); -/* - if (get_global_id(0) == 0 && get_global_id(1) == 0) \ - printf("(%d, %d): @%d src_offset=%d idx_dim=%d block_id=%d\n", \ - get_global_id(0), get_global_id(1), \ - dim, src_offset, CONCAT(idx_, dim), block_id \ - ); -*/ - -#if DIMS > 5 -#error "invalid configuration" -#endif -#if DIMS > 4 - uint idx_4 = 0; -#if BLOCK_DIMS <= 4 - CALC_SRC_INDEX(4) -#endif - UPDATE_SRC_OFFSET(4) -#endif -#if DIMS > 3 - uint idx_3 = 0; -#if BLOCK_DIMS <= 3 - CALC_SRC_INDEX(3) -#endif - UPDATE_SRC_OFFSET(3) -#endif -#if DIMS > 2 - uint idx_2 = 0; -#if BLOCK_DIMS <= 2 - CALC_SRC_INDEX(2) -#endif - UPDATE_SRC_OFFSET(2) -#endif -#if DIMS > 1 - uint idx_1 = 0; -#if BLOCK_DIMS <= 1 - CALC_SRC_INDEX(1) -#endif - UPDATE_SRC_OFFSET(1) -#endif -#if DIMS > 0 - uint idx_0 = 0; - UPDATE_SRC_OFFSET(0) -#endif - -/* - if (get_global_id(0) == 0) - printf("(%d, %d): src_offset=%d dst_offset=%d\n", - get_global_id(0), get_global_id(1), - src_offset, dst_offset - ); -*/ - -#ifdef USE_COPY_1D - copy_block_1d(src, src_offset, dst, dst_offset); -#else - copy_block_2d(src, src_offset, dst, dst_offset); + } // copy_block_2d #endif } From d695208727c8bfcf3e1524a30ebe7a4d4ca24845 Mon Sep 17 00:00:00 2001 From: Liubov Batanina Date: Mon, 3 Aug 2020 21:02:49 +0300 Subject: [PATCH 15/21] Merge pull request #17967 from l-bat:non_const_weights_for_conv * Supported convolution with non-const weights * Fix opencl blobs * Update tests --- modules/dnn/src/layers/convolution_layer.cpp | 166 +++++++++++++------ modules/dnn/src/onnx/onnx_importer.cpp | 9 +- modules/dnn/test/test_onnx_importer.cpp | 56 +++++++ 3 files changed, 178 insertions(+), 53 deletions(-) diff --git a/modules/dnn/src/layers/convolution_layer.cpp b/modules/dnn/src/layers/convolution_layer.cpp index 17fadd93ec..b6532f23d3 100644 --- a/modules/dnn/src/layers/convolution_layer.cpp +++ b/modules/dnn/src/layers/convolution_layer.cpp @@ -106,18 +106,19 @@ public: inputs_arr.getMatVector(inputs); outputs_arr.getMatVector(outputs); - CV_Assert(inputs.size() > 0); + CV_Assert((inputs.size() > outputs.size() && blobs.empty()) || + (!inputs.empty() && (blobs.size() == 1 || blobs.size() == 2))); + MatSize weightShape = blobs.empty() ? inputs[1].size : blobs[0].size; - CV_Assert(blobs.size() == 1 || blobs.size() == 2); CV_Assert(inputs[0].dims == outputs[0].dims); - CV_Assert(blobs[0].dims == kernel_size.size() + 2); + CV_Assert(weightShape.dims() == kernel_size.size() + 2); for (int i = 0; i < kernel_size.size(); i++) { - CV_Assert(blobs[0].size[i + 2] == kernel_size[i]); + CV_Assert(weightShape[i + 2] == kernel_size[i]); } const Mat &input = inputs[0]; CV_Assert((input.dims == 4 || input.dims == 5) && (input.type() == CV_32F || input.type() == CV_16S)); - for (size_t i = 0; i < inputs.size(); i++) + for (size_t i = 0; i < outputs.size(); i++) { CV_Assert(inputs[i].type() == input.type()); CV_Assert((inputs[i].dims == 4 || inputs[i].dims == 5) && inputs[i].size[1] == input.size[1]); @@ -245,6 +246,7 @@ public: MatShape computeColRowShape(const MatShape &inpShape, const MatShape &outShape) const CV_OVERRIDE { + CV_Assert(!blobs.empty()); int dims = inpShape.size(); int inpD = dims == 5 ? inpShape[2] : 1; int inpH = inpShape[dims - 2]; @@ -262,12 +264,14 @@ public: { if (kernel_size.size() == 3) return preferableTarget == DNN_TARGET_CPU; + if ((backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || preferableTarget != DNN_TARGET_MYRIAD) && blobs.empty()) + return false; return (preferableTarget != DNN_TARGET_MYRIAD || dilation.width == dilation.height); } else #endif return (kernel_size.size() == 3 && preferableTarget == DNN_TARGET_CPU && backendId == DNN_BACKEND_OPENCV) || - (kernel_size.size() == 2 && (backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE)); + (kernel_size.size() == 2 && (backendId == DNN_BACKEND_OPENCV || (backendId == DNN_BACKEND_HALIDE && !blobs.empty()))); } bool getMemoryShapes(const std::vector &inputs, @@ -275,16 +279,16 @@ public: std::vector &outputs, std::vector &internals) const CV_OVERRIDE { - CV_Assert(blobs.size() != 0); - CV_Assert(!hasBias() || blobs[1].total() == (size_t)blobs[0].size[0]); - CV_Assert(inputs.size() == (size_t)1); + CV_Assert(!blobs.empty() || inputs.size() > 1); + const int* weightShape = blobs.empty() ? &inputs[1][0] : blobs[0].size.p; + CV_Assert(!hasBias() || blobs[1].total() == (size_t)weightShape[0]); internals.clear(); CV_Assert(inputs.size() != 0); std::vector inpShape(inputs[0].begin() + 2, inputs[0].end()); - int outCn = blobs[0].size[0]; + int outCn = weightShape[0]; std::vector outShape; outShape.push_back(inputs[0][0]); outShape.push_back(outCn); @@ -300,10 +304,10 @@ public: getConvPoolOutParams(inpShape, kernel_size, strides, padMode, dilations, outShape); } - int ngroups = inpCn / blobs[0].size[1]; - if (ngroups == 0 || ngroups * blobs[0].size[1] != inpCn) + int ngroups = inpCn / weightShape[1]; + if (ngroups == 0 || ngroups * weightShape[1] != inpCn) CV_Error(Error::StsError, format("Number of input channels should " - "be multiple of %d but got %d", blobs[0].size[1], inpCn)); + "be multiple of %d but got %d", weightShape[1], inpCn)); CV_Assert(ngroups > 0 && inpCn % ngroups == 0 && outCn % ngroups == 0); outputs.resize(1, outShape); @@ -315,15 +319,15 @@ public: { BaseConvolutionLayerImpl::finalize(inputs_arr, outputs_arr); - CV_Assert(!blobs.empty()); - const int outCn = blobs[0].size[0]; + std::vector inputs; + inputs_arr.getMatVector(inputs); // prepare weightsMat where each row is aligned and has enough zero padding on the right to // use vectorized (i.e. with intrinsics) loops without tail processing - Mat wm = blobs[0].reshape(1, outCn); + Mat wm = blobs.empty() ? inputs[1].reshape(1, numOutput) : blobs[0].reshape(1, numOutput); if( wm.step1() % VEC_ALIGN != 0 ) { int newcols = (int)alignSize(wm.step1(), VEC_ALIGN); - Mat wm_buffer = Mat(outCn, newcols, wm.type()); + Mat wm_buffer = Mat(numOutput, newcols, wm.type()); Mat wm_padding = wm_buffer.colRange(wm.cols, newcols); wm_padding.setTo(Scalar::all(0.)); Mat wm_aligned = wm_buffer.colRange(0, wm.cols); @@ -331,18 +335,18 @@ public: wm = wm_aligned; } weightsMat = wm; - weightsMultipliers.assign(outCn, 1.0); + weightsMultipliers.assign(numOutput, 1.0); - Mat biasMat = hasBias() ? blobs[1].reshape(1, outCn) : Mat(); - biasvec.resize(outCn+2); + Mat biasMat = hasBias() ? blobs[1].reshape(1, numOutput) : Mat(); + biasvec.resize(numOutput+2); if( biasMat.empty() ) { - for(int i = 0; i < outCn; i++ ) + for(int i = 0; i < numOutput; i++ ) biasvec[i] = 0.f; } else { - for(int i = 0; i < outCn; i++ ) + for(int i = 0; i < numOutput; i++ ) biasvec[i] = biasMat.at(i); } #ifdef HAVE_OPENCL @@ -352,7 +356,7 @@ public: bool setActivation(const Ptr& layer) CV_OVERRIDE { - if (!activ.empty() && !layer.empty()) + if ((!activ.empty() && !layer.empty()) || blobs.empty()) return false; activ = layer; @@ -537,37 +541,48 @@ public: virtual Ptr initNgraph(const std::vector > &inputs, const std::vector >& nodes) CV_OVERRIDE { - CV_Assert_N(inputs.size() == 1, nodes.size() == 1); + CV_Assert_N(inputs.size() >= 1, nodes.size() >= 1); auto& ieInpNode = nodes[0].dynamicCast()->node; std::vector dims = ieInpNode->get_shape(); CV_Assert(dims.size() == 4 || dims.size() == 5); + std::shared_ptr ieWeights = nodes.size() > 1 ? nodes[1].dynamicCast()->node : nullptr; const int inpCn = dims[1]; - const int outCn = blobs[0].size[0]; - const int inpGroupCn = blobs[0].size[1]; + const int inpGroupCn = nodes.size() > 1 ? ieWeights->get_shape()[1] : blobs[0].size[1]; const int group = inpCn / inpGroupCn; - std::vector kernel_shape = getShape(blobs[0]); + std::vector kernel_shape; if (group != 1) { - kernel_shape[0] /= group; - kernel_shape.insert(kernel_shape.begin(), group); + kernel_shape.push_back(group); } + kernel_shape.push_back(numOutput / group); + kernel_shape.push_back(inpCn / group); + std::copy(kernel_size.begin(), kernel_size.end(), back_inserter(kernel_shape)); - auto ieWeights = std::make_shared(ngraph::element::f32, kernel_shape, blobs[0].data); - if (fusedWeights) + if (nodes.size() == 1) { - if (weightsMat.isContinuous()) - { - ieWeights = std::make_shared(ngraph::element::f32, kernel_shape, weightsMat.data); - } - else + ieWeights = std::make_shared(ngraph::element::f32, kernel_shape, blobs[0].data); + if (fusedWeights) { - Mat newWeights; - Mat cvWeights = weightsMat.colRange(0, blobs[0].total() / outCn); - cvWeights.copyTo(newWeights); - ieWeights = std::make_shared(ngraph::element::f32, kernel_shape, newWeights.data); + if (weightsMat.isContinuous()) + { + ieWeights = std::make_shared(ngraph::element::f32, kernel_shape, weightsMat.data); + } + else + { + Mat newWeights; + Mat cvWeights = weightsMat.colRange(0, blobs[0].total() / numOutput); + cvWeights.copyTo(newWeights); + ieWeights = std::make_shared(ngraph::element::f32, kernel_shape, newWeights.data); + } } } + else + { + auto shape = std::make_shared(ngraph::element::i64, + ngraph::Shape{kernel_shape.size()}, kernel_shape.data()); + ieWeights = std::make_shared(ieWeights, shape, true); + } ngraph::op::PadType pad_type = ngraph::op::PadType::EXPLICIT; if (!padMode.empty()) @@ -592,11 +607,21 @@ public: pad_type); } - if (hasBias() || fusedBias) + if (hasBias() || fusedBias || nodes.size() == 3) { std::vector shape(conv_node->get_shape().size(), 1); - shape[1] = outCn; - auto bias = std::make_shared(ngraph::element::f32, ngraph::Shape(shape), biasvec.data()); + shape[1] = conv_node->get_shape()[1]; + std::shared_ptr bias; + if (nodes.size() == 3) + { + auto bias_shape = std::make_shared(ngraph::element::i64, + ngraph::Shape{shape.size()}, shape.data()); + bias = std::make_shared(nodes[2].dynamicCast()->node, bias_shape, true); + } + else + { + bias = std::make_shared(ngraph::element::f32, ngraph::Shape(shape), biasvec.data()); + } auto conv_bias = std::make_shared(conv_node, bias, ngraph::op::AutoBroadcastType::NUMPY); return Ptr(new InfEngineNgraphNode(conv_bias)); } @@ -1103,6 +1128,26 @@ public: for (int i = 0; i < inputs.size(); ++i) CV_Assert(inputs[i].u != outputs[0].u); + if (blobs.empty()) + { + size_t n = inputs.size() - 1; + umat_blobs.resize(n); + for (size_t i = 0; i < n; i++) + { + if (use_half) + { + Mat matFP32; + convertFp16(inputs[i + 1], matFP32); + matFP32.copyTo(umat_blobs[i]); + } + else + { + inputs[i + 1].copyTo(umat_blobs[i]); + } + } + inputs.resize(1); + } + if (umat_blobs.empty()) { size_t n = blobs.size(); @@ -1113,7 +1158,7 @@ public: } } - if (convolutionOp.empty()) + if (convolutionOp.empty() || blobs.empty()) { OCL4DNNConvConfig config; config.in_shape = shape(inputs[0]); @@ -1123,7 +1168,7 @@ public: config.stride = stride; config.dilation = dilation; config.group = inputs[0].size[1] / umat_blobs[0].size[1]; - config.bias_term = (hasBias()) ? true : false; + config.bias_term = umat_blobs.size() == 2; config.use_half = use_half; convolutionOp = Ptr >(new OCL4DNNConvSpatial(config)); @@ -1250,16 +1295,37 @@ public: inputs_arr.getMatVector(inputs); outputs_arr.getMatVector(outputs); + int outCn = blobs.empty() ? inputs[1].size[0] : blobs[0].size[0]; + // Need to align non-const blobs + if (blobs.empty()) + { + Mat wm = inputs[1].reshape(1, outCn); + if( wm.step1() % VEC_ALIGN != 0 ) + { + wm.copyTo(weightsMat); + if (inputs.size() > 2) + { + Mat biasMat = inputs[2].reshape(1, outCn); + biasMat.col(0).copyTo(biasvec); + biasvec.resize(outCn + 2); + } + else + { + biasvec.resize(outCn + 2, 0); + } + } + } + /*printf("conv %s: input (%d x %d x %d x %d), kernel (%d x %d), pad (%d x %d), stride (%d x %d), dilation (%d x %d)\n", name.c_str(), inputs[0].size[0], inputs[0].size[1], inputs[0].size[2], inputs[0].size[3], kernel.width, kernel.height, pad.width, pad.height, stride.width, stride.height, dilation.width, dilation.height);*/ - CV_Assert_N(inputs.size() == (size_t)1, inputs[0].size[1] % blobs[0].size[1] == 0, + int inpGroupCn = blobs.empty() ? inputs[1].size[1] : blobs[0].size[1]; + CV_Assert_N(inputs.size() >= (size_t)1, inputs[0].size[1] % inpGroupCn == 0, outputs.size() == 1, inputs[0].data != outputs[0].data); - int ngroups = inputs[0].size[1]/blobs[0].size[1]; + int ngroups = inputs[0].size[1] / inpGroupCn; CV_Assert(outputs[0].size[1] % ngroups == 0); - int outCn = blobs[0].size[0]; reluslope.clear(); if( activ ) @@ -1328,11 +1394,11 @@ public: virtual int64 getFLOPS(const std::vector &inputs, const std::vector &outputs) const CV_OVERRIDE { - CV_Assert(inputs.size() == outputs.size()); + CV_Assert(inputs.size() == outputs.size() || inputs.size() == outputs.size() + blobs.size()); int64 flops = 0; int karea = std::accumulate(kernel_size.begin(), kernel_size.end(), 1, std::multiplies()); - for (int i = 0; i < inputs.size(); i++) + for (int i = 0; i < outputs.size(); i++) { flops += total(outputs[i])*(CV_BIG_INT(2)*karea*inputs[i][1] + 1); } diff --git a/modules/dnn/src/onnx/onnx_importer.cpp b/modules/dnn/src/onnx/onnx_importer.cpp index 220cae813e..407dcdc570 100644 --- a/modules/dnn/src/onnx/onnx_importer.cpp +++ b/modules/dnn/src/onnx/onnx_importer.cpp @@ -1003,10 +1003,13 @@ void ONNXImporter::populateNet(Net dstNet) CV_Assert(node_proto.input_size() >= 2); layerParams.type = "Convolution"; for (int j = 1; j < node_proto.input_size(); j++) { - layerParams.blobs.push_back(getBlob(node_proto, constBlobs, j)); + if (constBlobs.find(node_proto.input(j)) != constBlobs.end()) + { + layerParams.blobs.push_back(getBlob(node_proto, constBlobs, j)); + } } - layerParams.set("num_output", layerParams.blobs[0].size[0]); - layerParams.set("bias_term", node_proto.input_size() == 3); + int outCn = layerParams.blobs.empty() ? outShapes[node_proto.input(1)][0] : layerParams.blobs[0].size[0]; + layerParams.set("num_output", outCn); } else if (layer_type == "ConvTranspose") { diff --git a/modules/dnn/test/test_onnx_importer.cpp b/modules/dnn/test/test_onnx_importer.cpp index e932bc6919..6a9e68dbc5 100644 --- a/modules/dnn/test/test_onnx_importer.cpp +++ b/modules/dnn/test/test_onnx_importer.cpp @@ -111,6 +111,62 @@ TEST_P(Test_ONNX_layers, Convolution) testONNXModels("convolution"); } +TEST_P(Test_ONNX_layers, Convolution_variable_weight) +{ + if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH || + backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019) && target == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); + + String basename = "conv_variable_w"; + Net net = readNetFromONNX(_tf("models/" + basename + ".onnx")); + ASSERT_FALSE(net.empty()); + + net.setPreferableBackend(backend); + net.setPreferableTarget(target); + + for (int i = 0; i < 2; i++) + { + Mat input = blobFromNPY(_tf("data/input_" + basename + format("_%d", i) + "_0.npy")); + Mat weights = blobFromNPY(_tf("data/input_" + basename + format("_%d", i) + "_1.npy")); + Mat ref = blobFromNPY(_tf("data/output_" + basename + format("_%d", i) + ".npy")); + + net.setInput(input, "0"); + net.setInput(weights, "1"); + + Mat out = net.forward(); + normAssert(ref, out, "", default_l1, default_lInf); + } +} + +TEST_P(Test_ONNX_layers, Convolution_variable_weight_bias) +{ + if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH || + backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019) && target == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); + + String basename = "conv_variable_wb"; + Net net = readNetFromONNX(_tf("models/" + basename + ".onnx")); + ASSERT_FALSE(net.empty()); + + net.setPreferableBackend(backend); + net.setPreferableTarget(target); + + for (int i = 0; i < 2; i++) + { + Mat input = blobFromNPY(_tf("data/input_" + basename + format("_%d", i) + "_0.npy")); + Mat weights = blobFromNPY(_tf("data/input_" + basename + format("_%d", i) + "_1.npy")); + Mat bias = blobFromNPY(_tf("data/input_" + basename + format("_%d", i) + "_2.npy")); + Mat ref = blobFromNPY(_tf("data/output_" + basename + format("_%d", i) + ".npy")); + + net.setInput(input, "0"); + net.setInput(weights, "1"); + net.setInput(bias, "bias"); + + Mat out = net.forward(); + normAssert(ref, out, "", default_l1, default_lInf); + } +} + TEST_P(Test_ONNX_layers, Gather) { if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD) From 793e7c0d9fdb70d7b9f758322d1a59ee585bdc93 Mon Sep 17 00:00:00 2001 From: pemmanuelviel Date: Mon, 3 Aug 2020 20:29:57 +0200 Subject: [PATCH 16/21] Merge pull request #18019 from pemmanuelviel:pev--multiple-kmeans-trees * Possibility to set more than one tree for the hierarchical KMeans (default is still 1 tree). This particularly improves NN retrieval results with binary vectors, allowing better quality compared to LSH for similar processing time when speed is the criterium. * Add explanations on the FLANN's hierarchical KMeans for binary data. --- modules/flann/include/opencv2/flann.hpp | 32 ++- .../include/opencv2/flann/kmeans_index.h | 195 +++++++++++++----- 2 files changed, 179 insertions(+), 48 deletions(-) diff --git a/modules/flann/include/opencv2/flann.hpp b/modules/flann/include/opencv2/flann.hpp index 674e6583c5..e8ee91a3ec 100644 --- a/modules/flann/include/opencv2/flann.hpp +++ b/modules/flann/include/opencv2/flann.hpp @@ -191,8 +191,28 @@ public: KDTreeIndexParams( int trees = 4 ); }; @endcode + - **HierarchicalClusteringIndexParams** When passing an object of this type the index constructed + will be a hierarchical tree of clusters, dividing each set of points into n clusters whose centers + are picked among the points without further refinement of their position. + This algorithm fits both floating, integer and binary vectors. : + @code + struct HierarchicalClusteringIndexParams : public IndexParams + { + HierarchicalClusteringIndexParams( + int branching = 32, + flann_centers_init_t centers_init = CENTERS_RANDOM, + int trees = 4, + int leaf_size = 100); + + }; + @endcode - **KMeansIndexParams** When passing an object of this type the index constructed will be a - hierarchical k-means tree. : + hierarchical k-means tree (one tree by default), dividing each set of points into n clusters + whose barycenters are refined iteratively. + Note that this algorithm has been extended to the support of binary vectors as an alternative + to LSH when knn search speed is the criterium. It will also outperform LSH when processing + directly (i.e. without the use of MCA/PCA) datasets whose points share mostly the same values + for most of the dimensions. It is recommended to set more than one tree with binary data. : @code struct KMeansIndexParams : public IndexParams { @@ -201,6 +221,13 @@ public: int iterations = 11, flann_centers_init_t centers_init = CENTERS_RANDOM, float cb_index = 0.2 ); + + KMeansIndexParams( + int branching, + int iterations, + flann_centers_init_t centers_init, + float cb_index, + int trees ); }; @endcode - **CompositeIndexParams** When using a parameters object of this type the index created @@ -219,7 +246,8 @@ public: - **LshIndexParams** When using a parameters object of this type the index created uses multi-probe LSH (by Multi-Probe LSH: Efficient Indexing for High-Dimensional Similarity Search by Qin Lv, William Josephson, Zhe Wang, Moses Charikar, Kai Li., Proceedings of the 33rd - International Conference on Very Large Data Bases (VLDB). Vienna, Austria. September 2007) : + International Conference on Very Large Data Bases (VLDB). Vienna, Austria. September 2007). + This algorithm is designed for binary vectors. : @code struct LshIndexParams : public IndexParams { diff --git a/modules/flann/include/opencv2/flann/kmeans_index.h b/modules/flann/include/opencv2/flann/kmeans_index.h index a50e0cdf8d..a823986e09 100644 --- a/modules/flann/include/opencv2/flann/kmeans_index.h +++ b/modules/flann/include/opencv2/flann/kmeans_index.h @@ -57,8 +57,8 @@ namespace cvflann struct KMeansIndexParams : public IndexParams { - KMeansIndexParams(int branching = 32, int iterations = 11, - flann_centers_init_t centers_init = FLANN_CENTERS_RANDOM, float cb_index = 0.2 ) + void indexParams(int branching, int iterations, + flann_centers_init_t centers_init, float cb_index, int trees) { (*this)["algorithm"] = FLANN_INDEX_KMEANS; // branching factor @@ -69,6 +69,20 @@ struct KMeansIndexParams : public IndexParams (*this)["centers_init"] = centers_init; // cluster boundary index. Used when searching the kmeans tree (*this)["cb_index"] = cb_index; + // number of kmeans trees to search in + (*this)["trees"] = trees; + } + + KMeansIndexParams(int branching = 32, int iterations = 11, + flann_centers_init_t centers_init = FLANN_CENTERS_RANDOM, float cb_index = 0.2 ) + { + indexParams(branching, iterations, centers_init, cb_index, 1); + } + + KMeansIndexParams(int branching, int iterations, + flann_centers_init_t centers_init, float cb_index, int trees) + { + indexParams(branching, iterations, centers_init, cb_index, trees); } }; @@ -347,6 +361,7 @@ public: veclen_ = dataset_.cols; branching_ = get_param(params,"branching",32); + trees_ = get_param(params,"trees",1); iterations_ = get_param(params,"iterations",11); if (iterations_<0) { iterations_ = (std::numeric_limits::max)(); @@ -367,6 +382,13 @@ public: } cb_index_ = 0.4f; + root_ = new KMeansNodePtr[trees_]; + indices_ = new int*[trees_]; + + for (int i=0; i(); - std::memset(root_, 0, sizeof(KMeansNode)); + for (int i=0; i(); + std::memset(root_[i], 0, sizeof(KMeansNode)); - if(is_kdtree_distance::val || is_vector_space_distance::val) - { - computeNodeStatistics(root_, indices_, (unsigned int)size_); - computeClustering(root_, indices_, (int)size_, branching_,0); - } - else - { - computeBitfieldNodeStatistics(root_, indices_, (unsigned int)size_); - computeBitfieldClustering(root_, indices_, (int)size_, branching_,0); + if(is_kdtree_distance::val || is_vector_space_distance::val) { + computeNodeStatistics(root_[i], indices_[i], (unsigned int)size_); + computeClustering(root_[i], indices_[i], (int)size_, branching_,0); + } + else { + computeBitfieldNodeStatistics(root_[i], indices_[i], (unsigned int)size_); + computeBitfieldClustering(root_[i], indices_[i], (int)size_, branching_,0); + } } } @@ -456,35 +481,43 @@ public: save_value(stream, iterations_); save_value(stream, memoryCounter_); save_value(stream, cb_index_); - save_value(stream, *indices_, (int)size_); - - save_tree(stream, root_); + save_value(stream, trees_); + for (int i=0; i& result, const ElementType* vec, const SearchParams& searchParams) CV_OVERRIDE { - int maxChecks = get_param(searchParams,"checks",32); + const int maxChecks = get_param(searchParams,"checks",32); if (maxChecks==FLANN_CHECKS_UNLIMITED) { - findExactNN(root_, result, vec); + findExactNN(root_[0], result, vec); } else { // Priority queue storing intermediate branches in the best-bin-first search Heap* heap = new Heap((int)size_); int checks = 0; - findNN(root_, result, vec, checks, maxChecks, heap); + for (int i=0; i= maxChecks) && result.full()) + break; + } BranchSt branch; while (heap->popMin(branch) && (checkspivot), (int)veclen_); if (node->childs==NULL) { - int indices_offset = (int)(node->indices - indices_); + int indices_offset = (int)(node->indices - indices_[num]); save_value(stream, indices_offset); } else { for(int i=0; ichilds[i]); + save_tree(stream, node->childs[i], num); } } } - void load_tree(FILE* stream, KMeansNodePtr& node) + void load_tree(FILE* stream, KMeansNodePtr& node, int num) { node = pool_.allocate(); load_value(stream, *node); @@ -636,12 +672,12 @@ private: if (node->childs==NULL) { int indices_offset; load_value(stream, indices_offset); - node->indices = indices_ + indices_offset; + node->indices = indices_[num] + indices_offset; } else { node->childs = pool_.allocate(branching_); for(int i=0; ichilds[i]); + load_tree(stream, node->childs[i], num); } } } @@ -660,6 +696,32 @@ private: } } + void free_centers() + { + if (root_ != NULL) { + for(int i=0; ichilds==NULL) { - if (checks>=maxChecks) { - if (result.full()) return; + if ((checks>=maxChecks) && result.full()) { + return; } checks += node->size; for (int i=0; isize; ++i) { @@ -1397,6 +1497,9 @@ private: /** The branching factor used in the hierarchical k-means clustering */ int branching_; + /** Number of kmeans trees (default is one) */ + int trees_; + /** Maximum number of iterations to use when performing k-means clustering */ int iterations_; @@ -1432,12 +1535,12 @@ private: /** * The root node in the tree. */ - KMeansNodePtr root_; + KMeansNodePtr* root_; /** * Array of indices to vectors in the dataset. */ - int* indices_; + int** indices_; /** * The distance From e8c26963e9799b4eb27b41b42cfab11441004195 Mon Sep 17 00:00:00 2001 From: Ilya Churaev Date: Fri, 17 Jul 2020 14:34:06 +0300 Subject: [PATCH 17/21] Fixed removing is_parameter, is_constant, is_output --- modules/dnn/src/ie_ngraph.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/dnn/src/ie_ngraph.cpp b/modules/dnn/src/ie_ngraph.cpp index f02ef45ef1..aea2955d59 100644 --- a/modules/dnn/src/ie_ngraph.cpp +++ b/modules/dnn/src/ie_ngraph.cpp @@ -380,7 +380,11 @@ void InfEngineNgraphNet::setNodePtr(std::shared_ptr* ptr) { void InfEngineNgraphNet::release() { for (auto& node : components.back()) { +#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) + if (!(ngraph::op::is_parameter(node) || ngraph::op::is_output(node) || ngraph::op::is_constant(node)) ) { +#else if (!(node->is_parameter() || node->is_output() || node->is_constant()) ) { +#endif auto it = all_nodes.find(node->get_friendly_name()); if (it != all_nodes.end()) { unconnectedNodes.erase(*(it->second)); @@ -447,11 +451,19 @@ void InfEngineNgraphNet::createNet(Target targetId) { ngraph::ResultVector outputs; ngraph::ParameterVector inps; for (auto& node : components.back()) { +#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) + if (ngraph::op::is_parameter(node)) { +#else if (node->is_parameter()) { +#endif auto parameter = std::dynamic_pointer_cast(node); inps.push_back(parameter); } +#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) + else if (ngraph::op::is_output(node)) { +#else else if (node->is_output()) { +#endif auto result = std::dynamic_pointer_cast(node); outputs.push_back(result); } From 246de2b7f50452b8f335154af946d4d647bdc6ab Mon Sep 17 00:00:00 2001 From: Ilya Churaev Date: Mon, 20 Jul 2020 15:43:00 +0300 Subject: [PATCH 18/21] Replaced copy_with_new_args to clone_with_new_inputs --- modules/dnn/src/ie_ngraph.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/dnn/src/ie_ngraph.cpp b/modules/dnn/src/ie_ngraph.cpp index aea2955d59..82d8b9ca73 100644 --- a/modules/dnn/src/ie_ngraph.cpp +++ b/modules/dnn/src/ie_ngraph.cpp @@ -109,6 +109,12 @@ public: } } +#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_4) + std::shared_ptr clone_with_new_inputs(const ngraph::OutputVector& new_args) const override + { + return std::make_shared(new_args, params); + } +#else std::shared_ptr copy_with_new_args(const ngraph::NodeVector& new_args) const override { #if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_3) @@ -117,6 +123,7 @@ public: return std::make_shared(new_args, params); #endif } +#endif bool visit_attributes(ngraph::AttributeVisitor& visitor) override { From 8457e471fd09201938d3dc049009a04f75b27f2a Mon Sep 17 00:00:00 2001 From: danielenricocahall Date: Sun, 2 Aug 2020 12:46:05 -0400 Subject: [PATCH 19/21] add relu as activation option in darknet add relu option add relu as activation option in darknet simplify the setParams if-else ladder add relu as activation option in darknet correct activation_param type format format add relu as activation option in darknet spacing spacing add relu as activation option in darknet --- modules/dnn/src/darknet/darknet_io.cpp | 24 ++++++---------------- modules/dnn/test/test_darknet_importer.cpp | 5 +++++ 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/modules/dnn/src/darknet/darknet_io.cpp b/modules/dnn/src/darknet/darknet_io.cpp index f6504b96c7..bc0b413588 100644 --- a/modules/dnn/src/darknet/darknet_io.cpp +++ b/modules/dnn/src/darknet/darknet_io.cpp @@ -221,6 +221,10 @@ namespace cv { { cv::dnn::LayerParams activation_param; if (type == "relu") + { + activation_param.type = "ReLU"; + } + else if (type == "leaky") { activation_param.set("negative_slope", 0.1f); activation_param.type = "ReLU"; @@ -862,24 +866,8 @@ namespace cv { } std::string activation = getParam(layer_params, "activation", "linear"); - if (activation == "leaky") - { - setParams.setActivation("relu"); - } - else if (activation == "swish") - { - setParams.setActivation("swish"); - } - else if (activation == "mish") - { - setParams.setActivation("mish"); - } - else if (activation == "logistic") - { - setParams.setActivation("logistic"); - } - else if (activation != "linear") - CV_Error(cv::Error::StsParseError, "Unsupported activation: " + activation); + if (activation != "linear") + setParams.setActivation(activation); net->out_channels_vec[layers_counter] = tensor_shape[0]; } diff --git a/modules/dnn/test/test_darknet_importer.cpp b/modules/dnn/test/test_darknet_importer.cpp index 552c1fa111..45edf405ac 100644 --- a/modules/dnn/test/test_darknet_importer.cpp +++ b/modules/dnn/test/test_darknet_importer.cpp @@ -753,6 +753,11 @@ TEST_P(Test_Darknet_layers, connected) testDarknetLayer("connected", true); } +TEST_P(Test_Darknet_layers, relu) +{ + testDarknetLayer("relu"); +} + INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_layers, dnnBackendsAndTargets()); }} // namespace From 96ce65f021ee2d7d5a225c45ac635734f5fef464 Mon Sep 17 00:00:00 2001 From: Gabriel Date: Sat, 1 Aug 2020 20:00:49 -0300 Subject: [PATCH 20/21] Document PatchNANs input type --- modules/core/include/opencv2/core.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/core/include/opencv2/core.hpp b/modules/core/include/opencv2/core.hpp index c9ae4b9a81..6eb519e8a2 100644 --- a/modules/core/include/opencv2/core.hpp +++ b/modules/core/include/opencv2/core.hpp @@ -1615,7 +1615,9 @@ elements. CV_EXPORTS_W bool checkRange(InputArray a, bool quiet = true, CV_OUT Point* pos = 0, double minVal = -DBL_MAX, double maxVal = DBL_MAX); -/** @brief converts NaN's to the given number +/** @brief converts NaNs to the given number +@param a input/output matrix (CV_32F type). +@param val value to convert the NaNs */ CV_EXPORTS_W void patchNaNs(InputOutputArray a, double val = 0); From 1537ecd931a682b32d72c10fc46010182569a646 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Sat, 1 Aug 2020 15:05:05 +0300 Subject: [PATCH 21/21] * added depth-wise convolution; gives ~20-30% performance improvement in MobileSSD networks * hopefully, eliminated compile warnings, errors, as well as failure in one test * * fixed a few typos * decreased buffer size in some cases * added more optimal im2row branch in the case of 1x1 convolutions * tuned fastConv to reduce the number of passes over arrays backport of commit 77b01deb805b7166e938bbd17d393f051aad88c1 --- modules/dnn/src/layers/convolution_layer.cpp | 261 +++++++++++++++-- modules/dnn/src/layers/layers_common.simd.hpp | 274 +++++++++++++++++- 2 files changed, 499 insertions(+), 36 deletions(-) diff --git a/modules/dnn/src/layers/convolution_layer.cpp b/modules/dnn/src/layers/convolution_layer.cpp index b6532f23d3..f8ce75a824 100644 --- a/modules/dnn/src/layers/convolution_layer.cpp +++ b/modules/dnn/src/layers/convolution_layer.cpp @@ -648,6 +648,7 @@ public: bool useAVX; bool useAVX2; bool useAVX512; + int blk_size_cn; ParallelConv() : input_(0), weights_(0), output_(0), ngroups_(0), nstripes_(0), @@ -704,12 +705,17 @@ public: p.useAVX2 = checkHardwareSupport(CPU_AVX2) && isConv2D; p.useAVX512 = CV_CPU_HAS_SUPPORT_AVX512_SKX && isConv2D; - int ncn = std::min(inpCn, (int)BLK_SIZE_CN); - int kernel_d = !isConv2D? kernel_size[0] : 1; int kernel_h = kernel_size[kernel_size.size() - 2]; int kernel_w = kernel_size.back(); + int blk_size_cn0 = cvCeil(800./(kernel_w*kernel_h)); + int ncn = 16; + while (ncn*2 < blk_size_cn0 && ncn < inpCn) + ncn *= 2; + ncn = std::min(ncn, inpCn); + p.blk_size_cn = ncn; + int dil_d = !isConv2D? dilations[0] : 1; int dil_h = dilations[dilations.size() - 2]; int dil_w = dilations.back(); @@ -777,18 +783,26 @@ public: int dilation_w = dilations.back(); int i, j, k, d; - size_t inpPlaneSize = input_->total(2); - size_t outPlaneSize = output_->total(2); + int inpPlaneSize = (int)input_->total(2); + int outPlaneSize = (int)output_->total(2); bool is1x1 = is1x1_; int stripesPerSample; - size_t stripeSize; + int stripeSize; Range r = r0; - - if( nstripes >= batchSize*2 ) + bool depthWiseConvolution = !is1x1 && isConv2D && ngroups > 1 && inpCn == 1 && + outCn == 1 && kernel_d == 1 && dilation_d == 1 && stride_d == 0 && pad_d == 0 && + width >= 16 + dilation_w*(kernel_w - 1); + // for now only 3x3 depth-wise convolutions are supported + depthWiseConvolution = depthWiseConvolution && kernel_w == 3 && kernel_h == 3 && + // computing at most 1 pixel from each side can involve padding + max(stride_w, dilation_w) >= pad_l && max(stride_h, dilation_h) >= pad_t && + pad_l <= 1 && pad_t <= 1; + + if( !depthWiseConvolution && nstripes >= batchSize*2 ) { stripesPerSample = nstripes/batchSize; - stripeSize = alignSize((outPlaneSize + stripesPerSample - 1)/stripesPerSample, valign); + stripeSize = (int)alignSize((outPlaneSize + stripesPerSample - 1)/stripesPerSample, valign); stripeSize = std::min(stripeSize, outPlaneSize); } else @@ -807,20 +821,29 @@ public: const float* biasptr_ = &biasvec_->at(0); const float* reluptr_ = reluslope_->empty() ? 0 : &reluslope_->at(0); float* data_out0_ = output_->ptr(); - size_t rowbufsz = (size_t)karea*BLK_SIZE_CN*BLK_SIZE; - AutoBuffer rowbuf0_(rowbufsz + valign); - float* rowbuf0 = alignPtr(rowbuf0_.data(), (int)(valign*sizeof(float))); - - // we clear the buffer once; ultimately, it lets us to avoid - // tail processing after running the unrolled/vectorized loop. - // the main idea is to make sure that the tail (a.k.a. padding) of each row - // (i.e. the elements with indices between vsz=karea*ncn and vsz_a) - // does not contain NaNs or Infs. Because the padding in the weights - // matrix is explicitly initialized with 0's, we handle all other - // cases nicely, i.e. we can skip expliciting re-initialization - // of the padding - we just retain elements from the previous iteration - // of the loop over channels (cn0). - memset(rowbuf0, 0, rowbufsz*sizeof(rowbuf0[0]) ); + AutoBuffer rowbuf0_; + float* rowbuf0 = 0; + bool use_rowbuf = !depthWiseConvolution; + int blk_size = depthWiseConvolution ? outPlaneSize : min((int)BLK_SIZE, stripeSize); + + // im2row buffer is not used for depth-wise convolution + if(use_rowbuf) + { + size_t rowbufsz = alignSize(karea*blk_size_cn, valign)*min((int)BLK_SIZE, blk_size); + //printf("karea=%d, blk_size_cn=%d, rowbufsz=%d, stripeSize=%d\n", karea, blk_size_cn, (int)rowbufsz, stripeSize); + rowbuf0_.allocate(rowbufsz + valign); + rowbuf0 = alignPtr(rowbuf0_.data(), (int)(valign*sizeof(float))); + // we clear the buffer once; ultimately, it lets us to avoid + // tail processing after running the unrolled/vectorized loop. + // the main idea is to make sure that the tail (a.k.a. padding) of each row + // (i.e. the elements with indices between vsz=karea*ncn and vsz_a) + // does not contain NaNs or Infs. Because the padding in the weights + // matrix is explicitly initialized with 0's, we handle all other + // cases nicely, i.e. we can skip expliciting re-initialization + // of the padding - we just retain elements from the previous iteration + // of the loop over channels (cn0). + memset(rowbuf0, 0, rowbufsz*sizeof(rowbuf0[0]) ); + } for( int stripe = r.start; stripe < r.end; stripe++ ) { @@ -835,28 +858,213 @@ public: const float* wptr_orig = wptr_orig_ + wstep*startOutCn; const float* biasptr = biasptr_ + startOutCn; - for( int cn0 = 0; cn0 < inpCn; cn0 += BLK_SIZE_CN ) + for( int cn0 = 0; cn0 < inpCn; cn0 += blk_size_cn ) { - int cn1 = std::min(cn0 + BLK_SIZE_CN, inpCn); + int cn1 = std::min(cn0 + blk_size_cn, inpCn); int ncn = cn1 - cn0, vsz = karea*ncn; int vsz_a = (int)alignSize(vsz, valign); const float* wptr = wptr_orig + cn0*karea; // we apply [Channels][P]ReLU (if any) during the final pass only. const float* relu = cn1 == inpCn && reluptr_ ? reluptr_ + startOutCn : 0; - for( int ofs0 = stripeStart; ofs0 < stripeEnd; ofs0 += BLK_SIZE ) + for( int ofs0 = stripeStart; ofs0 < stripeEnd; ofs0 += blk_size ) { - int ofs, ofs1 = std::min(ofs0 + BLK_SIZE, stripeEnd); + int ofs, ofs1 = std::min(ofs0 + blk_size, stripeEnd); + int bsz = ofs1 - ofs0; int out_d = ofs0 / (outH * outW); int out_i = (ofs0 - out_d * outH * outW) / outW; int out_j = ofs0 % outW; + if (depthWiseConvolution) + { + CV_Assert(out_i == 0 && out_j == 0); + int in_d = out_d * stride_d - pad_d; + const float* inptr_ = data_inp0 + (cn0*depth*height + in_d*height)*width; + float* outptr_ = data_out0 + ofs0; + + #if CV_TRY_AVX2 + if(useAVX2) + opt_AVX2::fastDepthwiseConv(wptr, kernel_h, kernel_w, + stride_h, stride_w, dilation_h, dilation_w, pad_t, pad_l, + biasptr, relu, inptr_, height, width, outptr_, out_d, outH, outW); + else + #endif + #if CV_TRY_AVX + if(useAVX) + opt_AVX::fastDepthwiseConv(wptr, kernel_h, kernel_w, + stride_h, stride_w, dilation_h, dilation_w, pad_t, pad_l, + biasptr, relu, inptr_, height, width, outptr_, out_d, outH, outW); + else + #endif + { + const float w00_ = wptr[0], w01_ = wptr[1], w02_ = wptr[2], + w10 = wptr[3], w11 = wptr[4], w12 = wptr[5], + w20_ = wptr[6], w21_ = wptr[7], w22_ = wptr[8]; + int outW1 = min(outW, (width - dilation_w*(kernel_w - 1) + pad_l)/stride_w); + float relu_coeff = relu ? relu[out_d] : 1.f, bias = biasptr[out_d]; + + for (int out_i = 0; out_i < outH; out_i++) + { + int in_i = out_i * stride_h - pad_t, out_j = 0; + const float* imgptr0 = inptr_ + in_i*width; + const float* imgptr1 = imgptr0 + dilation_h*width; + const float* imgptr2 = imgptr0 + (dilation_h*2)*width; + float out, w00 = w00_, w01 = w01_, w02 = w02_; + float w20 = w20_, w21 = w21_, w22 = w22_; + if (in_i < 0) + { + w00 = w01 = w02 = 0.f; + imgptr0 = imgptr1; + } + else if (in_i + dilation_h*(kernel_h-1) >= height) + { + w20 = w21 = w22 = 0.f; + imgptr2 = imgptr1; + } + float* outptr = outptr_ + out_i*outW; + if (pad_l > 0) + { + out = imgptr0[0]*w01 + imgptr0[dilation_w]*w02 + + imgptr1[0]*w11 + imgptr1[dilation_w]*w12 + + imgptr2[0]*w21 + imgptr2[dilation_w]*w22 + bias; + if (relu) + out = out > 0.f ? out : out*relu_coeff; + outptr[0] = out; + out_j = 1; + } + + #if CV_SIMD + // maybe with AVX or AVX512 strided depthwise convolution + // can be accelerated with vector code, but with 4xfloat vectors + // it's hardly the case + if( stride_w == 1 ) + { + const int VECSZ = v_float32::nlanes; + const int out_delta = VECSZ/stride_w; + v_float32 vw00 = vx_setall_f32(w00), vw01 = vx_setall_f32(w01), vw02 = vx_setall_f32(w02), + vw10 = vx_setall_f32(w10), vw11 = vx_setall_f32(w11), vw12 = vx_setall_f32(w12), + vw20 = vx_setall_f32(w20), vw21 = vx_setall_f32(w21), vw22 = vx_setall_f32(w22); + v_float32 z = vx_setzero_f32(), vbias = vx_setall_f32(bias), vrc = vx_setall_f32(relu_coeff); + for( ; out_j < outW1; out_j += out_delta ) + { + if (out_j + out_delta > outW1) + { + if (out_j <= pad_l) + break; + out_j = outW1 - out_delta; + } + int in_j = out_j * stride_w - pad_l; + v_float32 v00 = vx_load(imgptr0 + in_j), + v01 = vx_load(imgptr0 + in_j + dilation_w), + v02 = vx_load(imgptr0 + in_j + dilation_w*2), + v10 = vx_load(imgptr1 + in_j), + v11 = vx_load(imgptr1 + in_j + dilation_w), + v12 = vx_load(imgptr1 + in_j + dilation_w*2), + v20 = vx_load(imgptr2 + in_j), + v21 = vx_load(imgptr2 + in_j + dilation_w), + v22 = vx_load(imgptr2 + in_j + dilation_w*2); + + v_float32 vout = v00*vw00 + v01*vw01 + v02*vw02 + + v10*vw10 + v11*vw11 + v12*vw12 + + v20*vw20 + v21*vw21 + v22*vw22 + vbias; + if (relu) + vout = v_select(vout > z, vout, vout*vrc); + vx_store(outptr + out_j, vout); + } + } + #endif + for (; out_j < outW1; out_j++) + { + int in_j = out_j * stride_w - pad_l; + out = imgptr0[in_j]*w00 + imgptr0[in_j + dilation_w]*w01 + imgptr0[in_j + dilation_w*2]*w02 + + imgptr1[in_j]*w10 + imgptr1[in_j + dilation_w]*w11 + imgptr1[in_j + dilation_w*2]*w12 + + imgptr2[in_j]*w20 + imgptr2[in_j + dilation_w]*w21 + imgptr2[in_j + dilation_w*2]*w22 + bias; + if (relu) + out = out > 0.f ? out : out*relu_coeff; + outptr[out_j] = out; + } + + for (; out_j < outW; out_j++ ) + { + int in_j0 = out_j * stride_w - pad_l, in_j1 = in_j0 + dilation_w, in_j2 = in_j0 + dilation_w*2; + float s0 = 1.f, s1 = 1.f, s2 = 1.f; + if (in_j0 >= width) + { + in_j0 = 0; + s0 = 0.f; + } + if (in_j1 >= width) + { + in_j1 = 0; + s1 = 0.f; + } + if (in_j2 >= width) + { + in_j2 = 0; + s2 = 0.f; + } + out = imgptr0[in_j0]*w00*s0 + imgptr0[in_j1]*w01*s1 + imgptr0[in_j2]*w02*s2 + + imgptr1[in_j0]*w10*s0 + imgptr1[in_j1]*w11*s1 + imgptr1[in_j2]*w12*s2 + + imgptr2[in_j0]*w20*s0 + imgptr2[in_j1]*w21*s1 + imgptr2[in_j2]*w22*s2 + bias; + if (relu) + out = out > 0.f ? out : out*relu_coeff; + outptr[out_j] = out; + } + } + } + continue; + } + // do im2row for a part of input tensor float* rowbuf = rowbuf0; if (isConv2D) { + if( is1x1 && stride_w == 1 && stride_h == 1 ) + { + const float* imgptr = data_inp0 + (cn0*height + out_i)*width + out_j; + for( int j = 0; j < bsz; j++, rowbuf += vsz_a ) + { + if( j + 4 <= bsz ) + { + k = 0; + #if CV_SIMD128 + for( ; k <= vsz - 4; k += 4 ) + { + const float* inp = imgptr + j + k*inpPlaneSize; + v_float32x4 p0 = v_load(inp), p1 = v_load(inp + inpPlaneSize); + v_float32x4 p2 = v_load(inp + inpPlaneSize*2), p3 = v_load(inp + inpPlaneSize*3); + v_float32x4 r0, r1, r2, r3; + v_transpose4x4(p0, p1, p2, p3, r0, r1, r2, r3); + v_store(rowbuf + k, r0); + v_store(rowbuf + k + vsz_a, r1); + v_store(rowbuf + k + vsz_a*2, r2); + v_store(rowbuf + k + vsz_a*3, r3); + } + #endif + for( ; k < vsz; k++ ) + { + const float* inp = imgptr + j + k*inpPlaneSize; + float v0 = inp[0], v1 = inp[1], v2 = inp[2], v3 = inp[3]; + rowbuf[k] = v0; + rowbuf[k + vsz_a] = v1; + rowbuf[k + vsz_a*2] = v2; + rowbuf[k + vsz_a*3] = v3; + } + j += 3; + rowbuf += vsz_a*3; + } + else + { + for( k = 0; k < vsz; k++ ) + { + rowbuf[k] = imgptr[j + k*inpPlaneSize]; + } + } + } + } + else for( ofs = ofs0; ofs < ofs1; out_j = 0, ++out_i ) { int delta = std::min(ofs1 - ofs, outW - out_j); @@ -976,7 +1184,6 @@ public: // now compute dot product of the weights // and im2row-transformed part of the tensor - int bsz = ofs1 - ofs0; #if CV_TRY_AVX512_SKX /* AVX512 convolution requires an alignment of 16, and ROI is only there for larger vector sizes */ if(useAVX512) diff --git a/modules/dnn/src/layers/layers_common.simd.hpp b/modules/dnn/src/layers/layers_common.simd.hpp index b2c0aa6a29..706695a7b2 100644 --- a/modules/dnn/src/layers/layers_common.simd.hpp +++ b/modules/dnn/src/layers/layers_common.simd.hpp @@ -50,6 +50,16 @@ void fastConv( const float* weights, size_t wstep, const float* bias, const float* rowbuf, float* output, const int* outShape, int blockSize, int vecsize, int vecsize_aligned, const float* relu, bool initOutput ); +void fastDepthwiseConv( const float* weights, + int kernel_h, int kernel_w, + int stride_h, int stride_w, + int dilation_h, int dilation_w, + int pad_t, int pad_l, + const float* bias, const float* relu, + const float* inptr, + int height, int width, + float* outptr, + int out_d, int outH, int outW ); void fastGEMM1T( const float* vec, const float* weights, size_t wstep, const float* bias, float* dst, int nvecs, int vecsize ); @@ -64,6 +74,8 @@ void fastGEMM( const float* aptr, size_t astep, const float* bptr, #define _mm256_fmadd_ps(a, b, c) _mm256_add_ps(c, _mm256_mul_ps(a, b)) #endif +enum { FASCONV_BASE_VECSZ = 4 }; + void fastConv( const float* weights, size_t wstep, const float* bias, const float* rowbuf, float* output, const int* outShape, int blockSize, int vecsize, int vecsize_aligned, @@ -73,6 +85,11 @@ void fastConv( const float* weights, size_t wstep, const float* bias, size_t outPlaneSize = outShape[2]*outShape[3]; float r0 = 1.f, r1 = 1.f, r2 = 1.f; __m128 vr0 = _mm_set1_ps(1.f), vr1 = vr0, vr2 = vr0, z = _mm_setzero_ps(); + int CV_DECL_ALIGNED(16) maskbuf[FASCONV_BASE_VECSZ] = {0}; + int rsz = blockSize % FASCONV_BASE_VECSZ; + for( int i = 0; i < rsz; i++ ) + maskbuf[FASCONV_BASE_VECSZ - i - 1] = -1; + __m128 mask = _mm_loadu_ps((const float*)maskbuf); // now compute dot product of the weights // and im2row-transformed part of the tensor @@ -114,8 +131,16 @@ void fastConv( const float* weights, size_t wstep, const float* bias, } int j = 0; - for( ; j <= blockSize - 4; j += 4 ) + for( ; j < blockSize; j += FASCONV_BASE_VECSZ ) { + bool tail = false; + if (j + FASCONV_BASE_VECSZ > blockSize) + { + if (j == 0) + break; + j = blockSize - FASCONV_BASE_VECSZ; + tail = true; + } int k = 0; const float* rptr = rowbuf + j*vecsize_aligned; @@ -243,9 +268,16 @@ void fastConv( const float* weights, size_t wstep, const float* bias, __m128 m0 = _mm_cmp_ps(s0, z, _CMP_GT_OS); __m128 m1 = _mm_cmp_ps(s1, z, _CMP_GT_OS); __m128 m2 = _mm_cmp_ps(s2, z, _CMP_GT_OS); - s0 = _mm_xor_ps(s0, _mm_andnot_ps(m0, _mm_xor_ps(_mm_mul_ps(s0, vr0), s0))); - s1 = _mm_xor_ps(s1, _mm_andnot_ps(m1, _mm_xor_ps(_mm_mul_ps(s1, vr1), s1))); - s2 = _mm_xor_ps(s2, _mm_andnot_ps(m2, _mm_xor_ps(_mm_mul_ps(s2, vr2), s2))); + s0 = _mm_blendv_ps(_mm_mul_ps(s0, vr0), s0, m0); + s1 = _mm_blendv_ps(_mm_mul_ps(s1, vr1), s1, m1); + s2 = _mm_blendv_ps(_mm_mul_ps(s2, vr2), s2, m2); + } + + if( tail ) + { + s0 = _mm_blendv_ps(_mm_loadu_ps(outptr0 + j), s0, mask); + s1 = _mm_blendv_ps(_mm_loadu_ps(outptr1 + j), s1, mask); + s2 = _mm_blendv_ps(_mm_loadu_ps(outptr2 + j), s2, mask); } _mm_storeu_ps(outptr0 + j, s0); @@ -253,9 +285,55 @@ void fastConv( const float* weights, size_t wstep, const float* bias, _mm_storeu_ps(outptr2 + j, s2); } + for( ; j <= blockSize - 2; j += 2 ) + { + const float* rptr0 = rowbuf + j*vecsize_aligned; + const float* rptr1 = rowbuf + (j+1)*vecsize_aligned; + float s00, s01, s10, s11, s20, s21; + + if( initOutput ) + { + s00 = s01 = bias0; + s10 = s11 = bias1; + s20 = s21 = bias2; + } + else + { + s00 = outptr0[j]; s01 = outptr0[j+1]; + s10 = outptr1[j]; s11 = outptr1[j+1]; + s20 = outptr2[j]; s21 = outptr2[j+1]; + } + + for( int k = 0; k < vecsize; k++ ) + { + float w0 = wptr0[k], w1 = wptr1[k], w2 = wptr2[k]; + float r = rptr0[k]; + s00 += w0*r; s10 += w1*r; s20 += w2*r; + r = rptr1[k]; + s01 += w0*r; s11 += w1*r; s21 += w2*r; + } + + if( relu ) + { + s00 = s00 > 0.f ? s00 : s00*r0; + s01 = s01 > 0.f ? s01 : s01*r0; + s10 = s10 > 0.f ? s10 : s10*r1; + s11 = s11 > 0.f ? s11 : s11*r1; + s20 = s20 > 0.f ? s20 : s20*r2; + s21 = s21 > 0.f ? s21 : s21*r2; + } + + outptr0[j] = s00; + outptr0[j+1] = s01; + outptr1[j] = s10; + outptr1[j+1] = s11; + outptr2[j] = s20; + outptr2[j+1] = s21; + } + for( ; j < blockSize; j++ ) { - const float* rptr = rowbuf + j*vecsize_aligned; + const float* rptr0 = rowbuf + j*vecsize_aligned; float s00, s10, s20; if( initOutput ) @@ -273,10 +351,9 @@ void fastConv( const float* weights, size_t wstep, const float* bias, for( int k = 0; k < vecsize; k++ ) { - float r0 = rptr[k]; - s00 += wptr0[k]*r0; - s10 += wptr1[k]*r0; - s20 += wptr2[k]*r0; + float w0 = wptr0[k], w1 = wptr1[k], w2 = wptr2[k]; + float r = rptr0[k]; + s00 += w0*r; s10 += w1*r; s20 += w2*r; } if( relu ) @@ -294,6 +371,185 @@ void fastConv( const float* weights, size_t wstep, const float* bias, _mm256_zeroupper(); } +static inline void _mm256_load_deinterleave(const float* ptr, __m256& a, __m256& b) +{ + __m256 t0 = _mm256_loadu_ps(ptr); + __m256 t1 = _mm256_loadu_ps(ptr + 8); + + __m256 lo = _mm256_permute2f128_ps(t0, t1, 0+2*16); + __m256 hi = _mm256_permute2f128_ps(t0, t1, 1+3*16); + a = _mm256_shuffle_ps(lo, hi, 0x88); + b = _mm256_shuffle_ps(lo, hi, 0xdd); +} + +void fastDepthwiseConv( const float* wptr, + int kernel_h, int kernel_w, + int stride_h, int stride_w, + int dilation_h, int dilation_w, + int pad_t, int pad_l, + const float* biasptr, const float* relu, + const float* inptr_, + int height, int width, + float* outptr_, + int out_d, int outH, int outW ) +{ + const float w00_ = wptr[0], w01_ = wptr[1], w02_ = wptr[2], + w10 = wptr[3], w11 = wptr[4], w12 = wptr[5], + w20_ = wptr[6], w21_ = wptr[7], w22_ = wptr[8]; + int outW1 = min(outW, (width - dilation_w*(kernel_w - 1) + pad_l)/stride_w); + float relu_coeff = relu ? relu[out_d] : 1.f, bias = biasptr[out_d]; + + for (int out_i = 0; out_i < outH; out_i++) + { + int in_i = out_i * stride_h - pad_t, out_j = 0; + const float* imgptr0 = inptr_ + in_i*width; + const float* imgptr1 = imgptr0 + dilation_h*width; + const float* imgptr2 = imgptr0 + (dilation_h*2)*width; + float out, w00 = w00_, w01 = w01_, w02 = w02_; + float w20 = w20_, w21 = w21_, w22 = w22_; + if (in_i < 0) + { + w00 = w01 = w02 = 0.f; + imgptr0 = imgptr1; + } + else if (in_i + dilation_h*(kernel_h-1) >= height) + { + w20 = w21 = w22 = 0.f; + imgptr2 = imgptr1; + } + float* outptr = outptr_ + out_i*outW; + if (pad_l > 0) + { + out = imgptr0[0]*w01 + imgptr0[dilation_w]*w02 + + imgptr1[0]*w11 + imgptr1[dilation_w]*w12 + + imgptr2[0]*w21 + imgptr2[dilation_w]*w22 + bias; + if (relu) + out = out > 0.f ? out : out*relu_coeff; + outptr[0] = out; + out_j = 1; + } + + if (stride_w == 1 || (stride_w == 2 && dilation_w == 1)) + { + const int VECSZ = 8; + __m256 vw00 = _mm256_set1_ps(w00), vw01 = _mm256_set1_ps(w01), vw02 = _mm256_set1_ps(w02), + vw10 = _mm256_set1_ps(w10), vw11 = _mm256_set1_ps(w11), vw12 = _mm256_set1_ps(w12), + vw20 = _mm256_set1_ps(w20), vw21 = _mm256_set1_ps(w21), vw22 = _mm256_set1_ps(w22); + __m256 z = _mm256_setzero_ps(), vbias = _mm256_set1_ps(bias), vrc = _mm256_set1_ps(relu_coeff); + + if( stride_w == 1 ) + for( ; out_j < outW1; out_j += VECSZ ) + { + if (out_j + VECSZ > outW1 && out_j > pad_l) + out_j = outW1 - VECSZ; + int in_j = out_j * stride_w - pad_l; + __m256 v00 = _mm256_loadu_ps(imgptr0 + in_j), + v01 = _mm256_loadu_ps(imgptr0 + in_j + dilation_w), + v02 = _mm256_loadu_ps(imgptr0 + in_j + dilation_w*2), + v10 = _mm256_loadu_ps(imgptr1 + in_j), + v11 = _mm256_loadu_ps(imgptr1 + in_j + dilation_w), + v12 = _mm256_loadu_ps(imgptr1 + in_j + dilation_w*2), + v20 = _mm256_loadu_ps(imgptr2 + in_j), + v21 = _mm256_loadu_ps(imgptr2 + in_j + dilation_w), + v22 = _mm256_loadu_ps(imgptr2 + in_j + dilation_w*2); + + __m256 vout0 = _mm256_fmadd_ps(v00, vw00, vbias); + __m256 vout1 = _mm256_mul_ps(v01, vw01); + __m256 vout2 = _mm256_mul_ps(v02, vw02); + + vout0 = _mm256_fmadd_ps(v10, vw10, vout0); + vout1 = _mm256_fmadd_ps(v11, vw11, vout1); + vout2 = _mm256_fmadd_ps(v12, vw12, vout2); + + vout0 = _mm256_fmadd_ps(v20, vw20, vout0); + vout1 = _mm256_fmadd_ps(v21, vw21, vout1); + vout2 = _mm256_fmadd_ps(v22, vw22, vout2); + + vout0 = _mm256_add_ps(_mm256_add_ps(vout0, vout1), vout2); + if (relu) + { + __m256 m = _mm256_cmp_ps(vout0, z, _CMP_GT_OQ); + vout0 = _mm256_blendv_ps(_mm256_mul_ps(vout0, vrc), vout0, m); + } + _mm256_storeu_ps(outptr + out_j, vout0); + } + else + for( ; out_j < outW1; out_j += VECSZ ) + { + if (out_j + VECSZ > outW1 && out_j > pad_l) + out_j = outW1 - VECSZ; + int in_j = out_j * stride_w - pad_l; + __m256 v00, v01, v02, v10, v11, v12, v20, v21, v22, unused; + _mm256_load_deinterleave(imgptr0 + in_j, v00, v01); + _mm256_load_deinterleave(imgptr0 + in_j + 2, v02, unused); + _mm256_load_deinterleave(imgptr1 + in_j, v10, v11); + _mm256_load_deinterleave(imgptr1 + in_j + 2, v12, unused); + _mm256_load_deinterleave(imgptr2 + in_j, v20, v21); + _mm256_load_deinterleave(imgptr2 + in_j + 2, v22, unused); + + __m256 vout0 = _mm256_fmadd_ps(v00, vw00, vbias); + __m256 vout1 = _mm256_mul_ps(v01, vw01); + __m256 vout2 = _mm256_mul_ps(v02, vw02); + + vout0 = _mm256_fmadd_ps(v10, vw10, vout0); + vout1 = _mm256_fmadd_ps(v11, vw11, vout1); + vout2 = _mm256_fmadd_ps(v12, vw12, vout2); + + vout0 = _mm256_fmadd_ps(v20, vw20, vout0); + vout1 = _mm256_fmadd_ps(v21, vw21, vout1); + vout2 = _mm256_fmadd_ps(v22, vw22, vout2); + + vout0 = _mm256_add_ps(_mm256_add_ps(vout0, vout1), vout2); + if (relu) + { + __m256 m = _mm256_cmp_ps(vout0, z, _CMP_GT_OQ); + vout0 = _mm256_blendv_ps(_mm256_mul_ps(vout0, vrc), vout0, m); + } + _mm256_storeu_ps(outptr + out_j, vout0); + } + } + + for (; out_j < outW1; out_j++) + { + int in_j = out_j * stride_w - pad_l; + out = imgptr0[in_j]*w00 + imgptr0[in_j + dilation_w]*w01 + imgptr0[in_j + dilation_w*2]*w02 + + imgptr1[in_j]*w10 + imgptr1[in_j + dilation_w]*w11 + imgptr1[in_j + dilation_w*2]*w12 + + imgptr2[in_j]*w20 + imgptr2[in_j + dilation_w]*w21 + imgptr2[in_j + dilation_w*2]*w22 + bias; + if (relu) + out = out > 0.f ? out : out*relu_coeff; + outptr[out_j] = out; + } + + for (; out_j < outW; out_j++ ) + { + int in_j0 = out_j * stride_w - pad_l, in_j1 = in_j0 + dilation_w, in_j2 = in_j0 + dilation_w*2; + float s0 = 1.f, s1 = 1.f, s2 = 1.f; + if (in_j0 >= width) + { + in_j0 = 0; + s0 = 0.f; + } + if (in_j1 >= width) + { + in_j1 = 0; + s1 = 0.f; + } + if (in_j2 >= width) + { + in_j2 = 0; + s2 = 0.f; + } + out = imgptr0[in_j0]*w00*s0 + imgptr0[in_j1]*w01*s1 + imgptr0[in_j2]*w02*s2 + + imgptr1[in_j0]*w10*s0 + imgptr1[in_j1]*w11*s1 + imgptr1[in_j2]*w12*s2 + + imgptr2[in_j0]*w20*s0 + imgptr2[in_j1]*w21*s1 + imgptr2[in_j2]*w22*s2 + bias; + if (relu) + out = out > 0.f ? out : out*relu_coeff; + outptr[out_j] = out; + } + } + _mm256_zeroupper(); +} + // dst = vec * weights^t + bias void fastGEMM1T( const float* vec, const float* weights, size_t wstep, const float* bias,