From 41e2e8897a135de7ddf6d75905dad6a5e555c2e5 Mon Sep 17 00:00:00 2001 From: larry Date: Sat, 4 Jul 2020 18:28:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A9=E7=94=A8=E5=8D=B7=E7=A7=AF=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E4=BA=BA=E5=83=8F=E5=88=86=E5=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __init__.py | 0 img/meinv.jpg | Bin 0 -> 37727 bytes img/trimap/meinv_org_trimap.png | Bin 0 -> 11105 bytes img/trimap/meinv_resize_trimap.png | Bin 0 -> 21421 bytes u_2_net/__init__.py | 0 u_2_net/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 147 bytes .../__pycache__/data_loader.cpython-37.pyc | Bin 0 -> 8841 bytes u_2_net/data_loader.py | 259 +++++++++ u_2_net/model/__init__.py | 2 + .../model/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 217 bytes .../model/__pycache__/u2net.cpython-37.pyc | Bin 0 -> 11172 bytes u_2_net/model/u2net.py | 526 ++++++++++++++++++ u_2_net/my_u2net_test.py | 103 ++++ 13 files changed, 890 insertions(+) create mode 100644 __init__.py create mode 100644 img/meinv.jpg create mode 100644 img/trimap/meinv_org_trimap.png create mode 100644 img/trimap/meinv_resize_trimap.png create mode 100644 u_2_net/__init__.py create mode 100644 u_2_net/__pycache__/__init__.cpython-37.pyc create mode 100644 u_2_net/__pycache__/data_loader.cpython-37.pyc create mode 100644 u_2_net/data_loader.py create mode 100644 u_2_net/model/__init__.py create mode 100644 u_2_net/model/__pycache__/__init__.cpython-37.pyc create mode 100644 u_2_net/model/__pycache__/u2net.cpython-37.pyc create mode 100644 u_2_net/model/u2net.py create mode 100644 u_2_net/my_u2net_test.py diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/img/meinv.jpg b/img/meinv.jpg new file mode 100644 index 0000000000000000000000000000000000000000..901c08092dc569eb20cf2117b45a6d58aaac8c3b GIT binary patch literal 37727 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 uzaHE6d;b8Zv(g{wNc}`xiT~MmeKPa_ literal 0 HcmV?d00001 diff --git a/img/trimap/meinv_org_trimap.png b/img/trimap/meinv_org_trimap.png new file mode 100644 index 0000000000000000000000000000000000000000..bc0dc634c7151dc019e67c4b3fda778eae25f874 GIT binary patch literal 11105 zcmai4_dnI|`*)6Y?9qus$DTz(LP++?&fc43XUpc;J5*!~Av>ERakBT0$ab%sZqHSX8_y6@|HUeD`!T``*Kie$v}#5g!OWXei%+Bi56sek`4C^#eYOYjN@ zhlg8PPFlw|d-vV57q>8DnA6Wc43H$eAw7X9c)n2f9%E__EuRXu#GhY0vitQ1xZKtg zZnXaB*NwTWuYFtp@=x+R16wU>VBnL&S6oL}@c`Teh`z&dIx$Bibl0BmomD7SZ|bs_OUUoA=L9mRk(V_p*lU z3dbCT=ntao>WEa9D(xpf+-c$>EfMmr2bl+_NKELGK?Z*F=iIwAaXnU+ zh8dfF;L!#n!;E6?4`x;RchWtYO?YXZ6l)i2m+6&HIW~YFA29HVKLcDnKgWxJcov6y z+)EU>;?~sKy0GmjNLtt4ZpuqznBgV%E{s|9oqEZ{oRcv2M68>icc7N{dEFeIv|H;U zIPKE7u(;GsJ7niUM(L`%R@3v={mn{OdDmuzPYv04U z?_GJ5w#BS!#<4-AxVF8$y`e#uFLPl1S8s3c{QP`>fB&yvzkdAq@%i)Ti4qO-Hebkf zs8zYo#gbCgO1%rtFLQX0ASo{Aq+`SUt~Z#uNAvi$XTGLrz;CDE;La&WTLeM8bKzL& zl;e=y4U_f7;Ug-o@@|Jc&8ivjjm6rx(^VE07V_5YM{4~GQGHW+7 zHzz!8HL46NSwvBUBZ-YH613nXBsw{pU1K-#x>gVWT>X_|W*(@WawLoD-u4tr>x+|TQFqz z)U>n`$I3;B9&EnO9cO3f(4?#5?TP)4i@nzUj)3E>vCGTLfy{exJ*=Ym4#^8-#0I$N zH87pr5wN3^sXSU?7R< z@!xZ7Rp;fefhYrySGSZ)XmuX=rGus(SkPT)dQw z>V_Pa+_-1nAfx3`V_;%xYHDI~xsm1i_iQBi@6~>AFqq%`yiu{X^z(0=r1w=|I6wN- zOYW!jnY8)3+u3oZ^~tePl}r#Bx9%Ez@urTp3s*BUF!=Lp;2x8N@4<3c_TNC?yMjB!pomKZ0`|F_ob`YT3fFku3~Znf6p;p z|G@-bt}?~N#jShLsnxVB3u`ZgTBI+!P!NQ7cXx}pd_yoXQABkEH?XQnW;exInz5@h z$Bm8pC9F3U;a5My}qHFFX5_;O{XI|?i;qEL?n?$#PY8G5Eii*OQJ~(^H6nH#FYyR?ZXR6$>Ar`VTVI6BZ>4!jtu3`4} z_O`dT!B%e``Dwvf42r$5LV0se01<#qKLV@OP4W2hctV4gmbS66aqOKWheN2Y!rUsb z+11rmT0WE4+1aYa+I*Q$=4KwSSj66liI~Bvai+ad-8k*MzH0m))Y{S#o26RPRkT{B z7UIu9u6QTC<>lG0hUYWq7Z3%S!K?eyxDaz< z0^Al;AzS6lFyP)k`%CQ}>%`d?_eWwIy>?E{r>CdED=xqT*Lyyl7dz!udiwg7x)oj% zqy*%=UbF2(0pOA5=4Jz46zUZAcF3+$FW~S;4_EHXUkl&={;mqX!UAM?QcTUBzKcdZT<@3GZvw@Tpsw50cppJ3J*boKY@BG1g^ z_=8N{9B<};dC=K}_&zBa+1#$TPL+{V zS9oY>=;=~`Ye2w7IEAF|*)Q8ly@?i6F?`dGRY=YYc51)X1d+Y(ow*~MTJ0Zj>4!Iu z9$%l0+%s)qk7ez}r@*~?AP|D9kgvHlU1{9;r{^940YQZx&xb~aQ6cBLIZjT_{`Fq~ z)Xo3?$^_0cI5AH_+@#C=bbSBRyxso<%)E5TTXv$pdj*)}%k$%HfcrD%!DRT4>RmEB zq-a}o4Khyr+w1D;PWQhvA(3(?-Z*dHFS?upOI!-N*!7i2>~p@5hBV@3Ym2_v7z98l zE+%#d22Cs)M%OxtBEdb4``?;ZPcH;|oGG}MXK*byKYsk^^F7eV-yg(}Rm2WE62n0q z^Y4s{3;E-}jGE{w2von8_j~h;&GF(VW>vIx55y=i?!c5EUu|m${Olw|##M#Be^xT# z_xtCZaia@D95gQNr>g`#Zd&OS*UV?Opuw?8=QUi*IvsdZUGi|KOng7?H>} z_f-_{fanmGEWftf)D86Nas z@Ll(yiIc}}Fh_lM|28^0y4dO?o1gqFp<3Def**mZS=a@b3Y?lT2~&U6!V<#X3=q$} z$*rq?j2C`zjgvSxIjN(spV?Q)h6=HK?JE&<@q5=(%z2nsAAS(5b*Fi7c(}!c@5S&| zFSO<7&$+spDsvHgQ)zG!aul#VUYwJ|_(FYCA;J=oJ94_pbnWZrHX0#70 z6nj8}#E_AbFSYuNL^K<2_%E=572H3~eH0*^u9AQDfJR7-B+PBKH(`7GSzWrA4CLwL za7~v9pNN>4<8bk-u~3KUEY}XY1O+wQ2({x6ia6NPxw*NeB{NdVTU4Tl!7HC5%k`_o zkmN_IUEIspYwC7_bWL=V5`h{B%J8-qn~7zgUTLDQ%S^={KAc-vc)n320bLda8!$37 z^v0ec0{Y${BcaC%Y_nwU2z$Hw9U--V_N6%5d%dgfX$Z?Y62x!=DJkii$3vk`1;VhD zNEu5<$9{GmaOJhFVeW{CpkUZ$P+!RVXJ30`daUgDKfh&EMT>miU}&K1pr@zb+1{?1b21W9G#|YfZIQ>|{*Kt(*odZZPQG+e#FbwF z@o@PwygOmc+d{K>k1+lKgvmGe?Y|Bu3YUeXi$DE!*4Di;+VZevc}vShl&qSUXW$p0 zZhapstjr)JVaY>w-7D2^y7e(0sR_2ZmN7ztf~o2yL>=8-MNm6KVFc;MkzZ}eX5qub zxP5aL?9nZmWDiHj*yZy(c5r^)WDwlI;VgWs%rrpgLuUi|V>Y!3#w2@hZ<{DHJ9y&kofe?WlpUE^nB5ZRLc+HW9(sJ8bK+6{Q#9;h+P zQSz^kk9eDp;Bu|jM5rS{QhYof6!N*vp}=gTp_&)#(foO(8hk+zZrNF9=?R)GD0;lS ziacciSg~OS(LldoX2`=t5(2<}l3rhu$!iS-B7d7R9+nn9D;7AfM^pBz6l=%Gg;lr9 z-XKEIptn7Z;PN?}4K9g}^?X^lx|Ibn)Au#cTdS(>AxKl#m4A$STYd<6=q3}piNMSA+propyL0+Vrxi_2Q`2U)JxGz zDDxp$s>X(Lq*=EeSxN4}F!0WmqxLj4tpshms{e%w%G@pMeFOQ4wzT%{=W`>bRg~!jbdC)rv8w zGYBsPxoC#%u6OIAiy|ZoIhzEGBSk49BqZ8U;r>8v7&B#EU{W?gY4wd5IhX-KmOPrY zyUBzPDn|P7k&s&J;+~tRs+4xfZ9G!Gda&%)n>Y_SG+B8lVR<2B;X`&u7gw))LN&#s zF0O()7j}jHkppljswr|}Tgcy)#nH0H0PGv2wabpGdde|!dwR4zvJ}6Yzm}IPO}Q{& z%#MoR1n$VbY`a(@PFe_2YbEgSLk!IfDeg@?6z!N zaCYb%M60!m&73~obQMubZX$kXpf-QskINiA zsV=}!=!#(8ff7!#rbIKtdKnOFB#8bw%e&+@6qK0Q9xK#G!RM3SjpR1&%bfhROiG)u zNSWS888*a_BMA+uab$s*CKFGJ62iw%zA1zy%=RCR$FURXT;3hI z>D?+2XDxDY+u^P7nMmkUzECM<`UHBRL|bAA$gWluZvW0}+4=g1mkZ?4T5u33r4^$M z@tj7_yhK`y1K#G_eX*S9WKQIO0p7}O@eayYpD#PQh5bY!T1FEiM{30R*6p8#O}?0E zxy$t>y0BjgEhtJ8M|b?g;TQfOKPkq2R0M@(ELudvb5%Jfw(F_Vocn0`XU)P}Mt2=v z)Xho!U{ZsWd=$fkAv zGy8MQ4Qb!Fz(5`)eYZNSMdi70mXKPZKM+o$F#ysqZs8GbB!lkR6WbA~d%ceYr^z+j zTWbt>yDT)}@+iyrV#`#F5Rx5_L=`Q`KQ3vI;ni%?L@>?3I{;E*SlF1ULs6hqg&e#` ziQTGhE`Gg?uB?(P#C8s(=&-Prup3HTq1MVOUgWrBH$UU6YQbNdTdS2TMQQcRDY8;o zFNWC1S`O7#)V$X%Iy#VGB9D5}oL!@yL(OCHwH3Pk1B!S^KU@_L}N7Mnl-i<82jpi$+cFw7Qo1S}3`B$}`@F^O4tN00} zTFCYi_C$e|3U_fzsww0VBZXdsf)QRn)<%#H_ofA_9y%Gt5nC{^{e@EKml5;YZJ3M@ z{e#h!pnvatCH`4LrAYpjXvV<0pvveMM5P3TGK`!coG+6EEWl0XMB4_VM~q2YsRc1N zf$d3*1hkvgqm|0rI}s#IFv|wZULTf`Qaw&B%Jl%g$gIEv|z^c zkaRr6#Af@@H$L@JcH^raYb+9D$;dIznyk6)CW>~y|D~GcDX`QUUaWVk7W!*VNcn-q zn!{p72D2U-i2-pfwjiEbUG5ksLY>r;IYt#CEA-i}E?tE~wLmTrKOR|WJa)&1_;mqy zDJpVYJ`tZcTp&f(dYQEPpIpQ!e5~206bE7(n1FU>xD+JZgbrnCNOPK;Y@PoN=KAVJ zk!3r6z4#mt^DikB}yrZ)6GqmdCa9z{GEE{KqQ}#2d~3h8ax&_F&%57{M(Rpt5@Ew zj}W9X56LTUMIwlrel6^u7KSuHc&it7f$ft=byFr%7V!AyP~bsPU)h+SqJ^{WBEe}( z*<(n7NZ#AG%&>Ecysh>?jJ!bSwkLfXGo0VU@&0x!T*-Oc6S`ppA~!r%p|Co%$g7aD5ZYsV z!W2F2wVH_kB^Stbyfgs02|kd7wvTErG0P*iwbn@7s2HjN8j zduPmIQSYAt1tqR$*+T*VBlo%UTulfpV_`Rgy>Ihq<+jY)D=8TlZa5GW{eQ2*=+=`v zSG-%pyYjeWt6j#9d=x#&<4dKO^NyfC=gx-Mkh6w`-Q>Rnw1Rp5DHAx*-)AqkWEvUP zab!i2XJ#_{Y}l1QFR~R?hEOrm(J7Zq z`14HJNI>fT;mF1LISPe(wUbtA27tWby_2xGpdi$C@A&>KDW}EPm+G8p-~h=6puel4 zrh%FfN(dAY9uy>nK<(1EzZK7J!STY{)3d&_^D&$lh#EqjN`xWQhX3U`Dyi&O6%k~d z7Sfb0t*uc}QPwpGyj=Hv+HD*QiGr~$keLt=5}sH`kljCL@xDnOg~4Dz%G+jE<#8IO zF3BMy?DkzHIQV*fAQPy`>eO}dEEb})KRm@+!DuKHU=e_m_IrU?Fn=$oGZ@foD=QhU zp1pckX&&yzzvL7YT+~Eb@WTyw(Gi;J8i;mTBCg&(KG>D`d2&?rbiY3~S2Q&7%}0ya5;H`Op7I@$Syf+pH|??(UQ@t1}M7xN_P- z$RFhGH8lcFBJim=2N>dJ$;3l3F@K=3xrtU-E*hGW7?c@`2ne`?ELoMaFnfNcI5H8WyCNc)Lv~)q(|7{6s)LEbk3hBv1mI-&>{-T^ zNOZA{OZKAx@0TyXZ5~;!(T!0oGpeKtNlN|&iYm~^&(6*i3dg|S&yl_}vgq++WMFug zl?5`2QZqSyw92ew11EJ%UteEnC`4_i6RVF7W45WAdp`3~I*-D8a4cBi822?@5+-eA z)85`5kl0PO3V)&JZg%|XDnsBH9Q2i796Br8J&JEX2H66WV^|x+hdn7I{E+IjhKb`nM${dQ4HLm3aiTBkS*Wf}ZY&u}FpMmEL4DlNEnKH}%EzVPrA>Wp@QbOQ|v z)7uLqF&o1@1IH+{X|&4QKOnyax(7)lbj?YV+f?q9yK#_Zk&%%nCnrGg@Mcyt zqNOqDQ{#aXpYAP+2mh5oe)_W75v_&8_S3tyZtmyWnvK4`zCG*sJc)spt7L94wzBb~ zS^Eyi99D@1kScOwnFC-f>E>VF*QLEslvmZlE)ep-V6FeDJx0aptY4pL?(}}Ks##iE zQeqzuWgUM@g!pEixGJZ`3nzYjF*maJt@%b=4=)V~qrMa=aW}uj2q82S01bG6+-Cnd zn}z1Rww<-LwX2I$*Y6z+2?`G+G9sBv2%S;~)>SyuG}|f{6`BgQ95|R{-;{zySn^#> zXl{OJnDL-WJq+CUON?E)->xn&Fi^!xFUzBDo^N^aEnfFPZN;KXl0qR69U5J~=e&NM z%uX~FmkdEz8W2&Ckp=!e+XTg_-31ND!jRJ^w29K}>+ zYUWlF#?}xNVcaYAo~NO7X$}|}?nvH8nB{EBYYp1{(}p@h?JCt1wIi$QR)!@4Wht6iH|Jzl)!5m2-Ji~*|ItL5GtHMrMCK0ffDFsp z%F0Uc^~Lw+&!2;OirCHS0`y{wZpFtQs}(;p$_P#FS3`F9Oq%#Xx}Jp5YKL`&Q2q9A z$Hm1>VtnKe^v}!7m*RrzyU}MFHN{gcBxr}1+%zO z#=4E*8zpui=^2(!>G%|Ba4aukJa2A?O@TTTd6aBw5irvP1wsM>@Zg>FRCXc{Iq=pw zZaV}dYpnS-^q$c@=u)9sGN11Nfb)!XH_>cWPJqpVZ&U%b@Nf5SWoV3}JVMu2 zFvGem_^D%}3;yg(@l08dalsEl^=4cepQOT*Fl;GbM@Ka|)06>nIZUp&ar>m?`%@iB zO$Zf9u%{^-W&qhtk1uoTq(Fmp`RdtR{S$C;mXU@f~pR zqPmYu`@FvvnS=?H{60RO+ETM+4fECDtm|GmxVS3QakQ|=tE#GMY!so1^OIoY)=KIT zqKufI(*R4f;%1P_p0oL+I5jrELJz-URy%R^r*{A|rBbmr8yj1s3=1HQ|8mfwqqbCd z%(y%y&WjmXK6Edqix@OYs2dinSO@-E*}YK-@g@}K~OhVT2|876ciXZ{f| zw~iW62hik(6Gz^+A4YFb?vb)6@o>{IgfVjyRPFK!wZHHdL6Cmtu$GmTjgf;+|L~24 zNgDxu6QH9i=T*>kp<>d9sSidPk~-*Ef7$%euV24{Dg+obyo=f9>54NEY+Ou84MYex zQDj`t-~H>qRXTUN%yX7tOck>Hhrs8)#VX;++VXOQu-8k?6`+Fn?s2dg zk>Tw)SDkxdNZMIdpcR4Sucr_~NHXivXfOB%$fbvehX%ZyFla`lO!5Sdw*Z0^CBt&_ z`Ow}?{xu`%t{D&-Yy`JGnyXFjhh;Nn*ve}~gwZ%YI>Lc0IDGSxC-0*8;f&%b6 znf&DL6-@yXlxIBd1$Il_X`&tSl@Wmgw4E{Q{^7odaz5A@Z&>@OTO4p6?>;A9HiAvu#QKsFy}*nvV8T@ z=4Q@&;2BMFtOB6KL@uT>qm$<^PNcJ@DQ|UsnAUZfn2@|{Qbq=sQy^0 zlAK$--C|_vE!Ey{zO&P#K`{B^9!=ax?qmI-NE&%}D=RBEH_E~N?cC_nfuI*fY07#h zc3W%h^D6CT!9bD*G1-D^`5U@SI-C-_PAA81 zvkjkrS{Uk0i{Zi%P6mZW0O2~kG`g)u99cu4wiGs0Wh86pmq?C#XSC?5+}5kEV$xrS zkg;4A9c*S~bPlTHchZTAr`PR*I+^r4G4i?e)7{o5zYRU1ufJQ>{Mi~SjEux@5DvW^ z`y*SOt80Vyp@3*f`IEvi15?w$KL;y2J0FZ#96)q1xT5}Mj5ixG+zIVkmF598R?tEL zYQWVE4O0$6IwV$>zfdj97@d?Wl7Ln1@~MoB3>sS6e<*ifP|uYPZ%XD-+^NBj`4~`jvp=zJ6iy5q4lH>*JLj_$1 zG;nM*gFvnHo>^O|&Ye5&-@Cmck}Uoeb~mU&PcmB14kA~6d7KmM^!-~tABMq0LF6;@ zGWawDobo?5zi8212p(t07^9zb{jJwyqlMWP^a;Hi8yle9Q$F>fic&y=BKUB@FY5aqA4QOolyfy)mJYEf&}VwP^}m~0xk%?Q;1Zj$k*CI@XE-hU7aW8D3N{!m&dyfPIf3O5>dal8G-)gd(HO9ll{S7N&lHAI zn-6cXPxm@;BnIv?<`5FklMYgqVAd2$JZX8hc&HwsDOui3@4>uuD_2GLMxJ+Dict{Z z&vO}i!x{t6)kBjbC;cU!U)u0K0Z2+O+>goz)e^*%flpCWf zc}j8hL3Xk|SJb*W6Lhb#n?L=gH?YXCwY=eLZEYPG*god4cI0Q6F(nq21l41*PS}`8 zT1{)OLOnIZyxg~|>*FWw=BFGgc;;_w%RvdVsRKfLeqxB1tr!e#u%j#LUOk_;zd(nM zv_rfHEiQM`t!kRu+Dxiu0L5-IyJxg4+ok2zf3MoO4^QKeAv*i1cu5L<0zo#1iLvn$ z&NRon;mS9vHwx8`2ukA$R&c+^#mCeJn)d$FK~>_?1dtxGn z>-NzxIjl*$?3Is!nc4ei^e%Rq_%bFANAWSM=$x1?w3B>(>Y?Omp0W%$Xg zDpQ5SAj!$qwS4>mJIvthT+H3%WHf$ptMUV_=XY27R+rg1Y z+P4yQdG?;Q!}^iJm76RI4Yjqk|Fu?`cf15{tTs_Uskyl#NqjxAfYsB;D=!J% zYsr2|lLn)^nFIgq{ifKvVNLGigB97Y{bE-X`60RrjdZ`y$Er8(ZmSY@DOn&0T&^Q3 zcmXkS6YV(P;c55?Q-I`VcZ*3KLFOT(SBU}i-#Z>=S|V~bP5D4pXl*!+J?XENc>MSp zbfuJfb#p&_zD!=%+2S8HBE!Ok)3VLq{K?wV734AA;@$j`x%c42TJVz|TJws^$}-&? zYW$Znd36b1JYhy-^jDqRp~%^vi%dlfJeIKq^a&_tn0m=m%7_uk3sw2+H>|SgcO%4t zTQJE-cx}E>iX`3qdgTw`#1H5bK$h8gwd?AZ1Hu31{Ys<4SMNMtogprb%zVnL^+-38|IzEtK4P3r4=_fWMf+!_|VRd4xm#eos<@`$f56e99syc`+L3C^|ty=$l!Cm z(op61qW~Y2SREV2h1%QN+8P>)t!RWopnsX7>8cb*e~5eked=&>xNzDkq}J{J83<&R zdiiaMEsvw13gl80M%v|MicT|)x-F9*abG9nlVQ%29L9;5718Wx0lOPp6veyt-`d%Q z{iDJho;Mh^n{A4^ym;|+5uaZ^HH1o+zs1fIe^4&=K`%+iLR?wz-roddd%GmvL#|}< zN~9B-q{BRXgTYQztTS$cRm^FeNHdY6>lyo$d8`nGiHy$rvqZLs-B?@e%@bjI(Bzh2 zRQdi~gA!00{#;+5^Xg-oOXUo9-NWz2ix+``45kiv`K96NYgoCD0U?3QAPj%o zM3)z6Ed@J%ui(T8>3O_AeMk%ti<=pt|Ej@sWn8EC2I&U(UBu0rYn#K5vf3ln>WcwBR{t5ZCt4*-~CEO zPyyU{D^ySnD2v#WFa|qAy`D-7IDc3@$=mmLX+Z48xi|k`cbQiL|G&v7H5i#185xg1 vWzzdiLlPsPd$VdloyAd>SC{)JV-fa0_lb2% literal 0 HcmV?d00001 diff --git a/img/trimap/meinv_resize_trimap.png b/img/trimap/meinv_resize_trimap.png new file mode 100644 index 0000000000000000000000000000000000000000..b80bf239d7c0524953ad60cc7888c3654c7fa2a1 GIT binary patch literal 21421 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

1JRo8|cpBZ9LA^>N)j;jEs!2jp9+;C&!o*Jg()$ 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 Rz=rdO)23%l9vZvF{vWimIk5l$ literal 0 HcmV?d00001 diff --git a/u_2_net/__init__.py b/u_2_net/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/u_2_net/__pycache__/__init__.cpython-37.pyc b/u_2_net/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..713831e618ab6987142b8aa29a4c3b6edb8b9705 GIT binary patch literal 147 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 w: + new_h, new_w = self.output_size*h/w,self.output_size + else: + new_h, new_w = self.output_size,self.output_size*w/h + else: + new_h, new_w = self.output_size + + new_h, new_w = int(new_h), int(new_w) + + # #resize the image to new_h x new_w and convert image from range [0,255] to [0,1] + # img = transform.resize(image,(new_h,new_w),mode='constant') + # lbl = transform.resize(label,(new_h,new_w),mode='constant', order=0, preserve_range=True) + + img = transform.resize(image,(self.output_size,self.output_size),mode='constant') + lbl = transform.resize(label,(self.output_size,self.output_size),mode='constant', order=0, preserve_range=True) + + return {'imidx':imidx, 'image':img,'label':lbl} + +class Rescale(object): + + def __init__(self,output_size): + assert isinstance(output_size,(int,tuple)) + self.output_size = output_size + + def __call__(self,sample): + imidx, image, label = sample['imidx'], sample['image'],sample['label'] + + h, w = image.shape[:2] + + if isinstance(self.output_size,int): + if h > w: + new_h, new_w = self.output_size*h/w,self.output_size + else: + new_h, new_w = self.output_size,self.output_size*w/h + else: + new_h, new_w = self.output_size + + new_h, new_w = int(new_h), int(new_w) + + # #resize the image to new_h x new_w and convert image from range [0,255] to [0,1] + img = transform.resize(image,(new_h,new_w),mode='constant') + lbl = transform.resize(label,(new_h,new_w),mode='constant', order=0, preserve_range=True) + + return {'imidx':imidx, 'image':img,'label':lbl} + +class RandomCrop(object): + + def __init__(self,output_size): + assert isinstance(output_size, (int, tuple)) + if isinstance(output_size, int): + self.output_size = (output_size, output_size) + else: + assert len(output_size) == 2 + self.output_size = output_size + def __call__(self,sample): + imidx, image, label = sample['imidx'], sample['image'], sample['label'] + + h, w = image.shape[:2] + new_h, new_w = self.output_size + + top = np.random.randint(0, h - new_h) + left = np.random.randint(0, w - new_w) + + image = image[top: top + new_h, left: left + new_w] + label = label[top: top + new_h, left: left + new_w] + + return {'imidx':imidx,'image':image, 'label':label} + +class ToTensor(object): + """Convert ndarrays in sample to Tensors.""" + + def __call__(self, sample): + + imidx, image, label = sample['imidx'], sample['image'], sample['label'] + + tmpImg = np.zeros((image.shape[0],image.shape[1],3)) + tmpLbl = np.zeros(label.shape) + + image = image/np.max(image) + if(np.max(label)<1e-6): + label = label + else: + label = label/np.max(label) + + if image.shape[2]==1: + tmpImg[:,:,0] = (image[:,:,0]-0.485)/0.229 + tmpImg[:,:,1] = (image[:,:,0]-0.485)/0.229 + tmpImg[:,:,2] = (image[:,:,0]-0.485)/0.229 + else: + tmpImg[:,:,0] = (image[:,:,0]-0.485)/0.229 + tmpImg[:,:,1] = (image[:,:,1]-0.456)/0.224 + tmpImg[:,:,2] = (image[:,:,2]-0.406)/0.225 + + tmpLbl[:,:,0] = label[:,:,0] + + # change the r,g,b to b,r,g from [0,255] to [0,1] + #transforms.Normalize(mean = (0.485, 0.456, 0.406), std = (0.229, 0.224, 0.225)) + tmpImg = tmpImg.transpose((2, 0, 1)) + tmpLbl = label.transpose((2, 0, 1)) + + return {'imidx':torch.from_numpy(imidx), 'image': torch.from_numpy(tmpImg), 'label': torch.from_numpy(tmpLbl)} + +class ToTensorLab(object): + """Convert ndarrays in sample to Tensors.""" + def __init__(self,flag=0): + self.flag = flag + + def __call__(self, sample): + + imidx, image, label =sample['imidx'], sample['image'], sample['label'] + + tmpLbl = np.zeros(label.shape) + + if(np.max(label)<1e-6): + label = label + else: + label = label/np.max(label) + + # change the color space + if self.flag == 2: # with rgb and Lab colors + tmpImg = np.zeros((image.shape[0],image.shape[1],6)) + tmpImgt = np.zeros((image.shape[0],image.shape[1],3)) + if image.shape[2]==1: + tmpImgt[:,:,0] = image[:,:,0] + tmpImgt[:,:,1] = image[:,:,0] + tmpImgt[:,:,2] = image[:,:,0] + else: + tmpImgt = image + tmpImgtl = color.rgb2lab(tmpImgt) + + # nomalize image to range [0,1] + tmpImg[:,:,0] = (tmpImgt[:,:,0]-np.min(tmpImgt[:,:,0]))/(np.max(tmpImgt[:,:,0])-np.min(tmpImgt[:,:,0])) + tmpImg[:,:,1] = (tmpImgt[:,:,1]-np.min(tmpImgt[:,:,1]))/(np.max(tmpImgt[:,:,1])-np.min(tmpImgt[:,:,1])) + tmpImg[:,:,2] = (tmpImgt[:,:,2]-np.min(tmpImgt[:,:,2]))/(np.max(tmpImgt[:,:,2])-np.min(tmpImgt[:,:,2])) + tmpImg[:,:,3] = (tmpImgtl[:,:,0]-np.min(tmpImgtl[:,:,0]))/(np.max(tmpImgtl[:,:,0])-np.min(tmpImgtl[:,:,0])) + tmpImg[:,:,4] = (tmpImgtl[:,:,1]-np.min(tmpImgtl[:,:,1]))/(np.max(tmpImgtl[:,:,1])-np.min(tmpImgtl[:,:,1])) + tmpImg[:,:,5] = (tmpImgtl[:,:,2]-np.min(tmpImgtl[:,:,2]))/(np.max(tmpImgtl[:,:,2])-np.min(tmpImgtl[:,:,2])) + + # tmpImg = tmpImg/(np.max(tmpImg)-np.min(tmpImg)) + + tmpImg[:,:,0] = (tmpImg[:,:,0]-np.mean(tmpImg[:,:,0]))/np.std(tmpImg[:,:,0]) + tmpImg[:,:,1] = (tmpImg[:,:,1]-np.mean(tmpImg[:,:,1]))/np.std(tmpImg[:,:,1]) + tmpImg[:,:,2] = (tmpImg[:,:,2]-np.mean(tmpImg[:,:,2]))/np.std(tmpImg[:,:,2]) + tmpImg[:,:,3] = (tmpImg[:,:,3]-np.mean(tmpImg[:,:,3]))/np.std(tmpImg[:,:,3]) + tmpImg[:,:,4] = (tmpImg[:,:,4]-np.mean(tmpImg[:,:,4]))/np.std(tmpImg[:,:,4]) + tmpImg[:,:,5] = (tmpImg[:,:,5]-np.mean(tmpImg[:,:,5]))/np.std(tmpImg[:,:,5]) + + elif self.flag == 1: #with Lab color + tmpImg = np.zeros((image.shape[0],image.shape[1],3)) + + if image.shape[2]==1: + tmpImg[:,:,0] = image[:,:,0] + tmpImg[:,:,1] = image[:,:,0] + tmpImg[:,:,2] = image[:,:,0] + else: + tmpImg = image + + tmpImg = color.rgb2lab(tmpImg) + + # tmpImg = tmpImg/(np.max(tmpImg)-np.min(tmpImg)) + + tmpImg[:,:,0] = (tmpImg[:,:,0]-np.min(tmpImg[:,:,0]))/(np.max(tmpImg[:,:,0])-np.min(tmpImg[:,:,0])) + tmpImg[:,:,1] = (tmpImg[:,:,1]-np.min(tmpImg[:,:,1]))/(np.max(tmpImg[:,:,1])-np.min(tmpImg[:,:,1])) + tmpImg[:,:,2] = (tmpImg[:,:,2]-np.min(tmpImg[:,:,2]))/(np.max(tmpImg[:,:,2])-np.min(tmpImg[:,:,2])) + + tmpImg[:,:,0] = (tmpImg[:,:,0]-np.mean(tmpImg[:,:,0]))/np.std(tmpImg[:,:,0]) + tmpImg[:,:,1] = (tmpImg[:,:,1]-np.mean(tmpImg[:,:,1]))/np.std(tmpImg[:,:,1]) + tmpImg[:,:,2] = (tmpImg[:,:,2]-np.mean(tmpImg[:,:,2]))/np.std(tmpImg[:,:,2]) + + else: # with rgb color + tmpImg = np.zeros((image.shape[0],image.shape[1],3)) + image = image/np.max(image) + if image.shape[2]==1: + tmpImg[:,:,0] = (image[:,:,0]-0.485)/0.229 + tmpImg[:,:,1] = (image[:,:,0]-0.485)/0.229 + tmpImg[:,:,2] = (image[:,:,0]-0.485)/0.229 + else: + tmpImg[:,:,0] = (image[:,:,0]-0.485)/0.229 + tmpImg[:,:,1] = (image[:,:,1]-0.456)/0.224 + tmpImg[:,:,2] = (image[:,:,2]-0.406)/0.225 + + tmpLbl[:,:,0] = label[:,:,0] + + # change the r,g,b to b,r,g from [0,255] to [0,1] + #transforms.Normalize(mean = (0.485, 0.456, 0.406), std = (0.229, 0.224, 0.225)) + tmpImg = tmpImg.transpose((2, 0, 1)) + tmpLbl = label.transpose((2, 0, 1)) + + return {'imidx':torch.from_numpy(imidx), 'image': torch.from_numpy(tmpImg), 'label': torch.from_numpy(tmpLbl)} + +class SalObjDataset(Dataset): + def __init__(self,img_name_list,lbl_name_list,transform=None): + # self.root_dir = root_dir + # self.image_name_list = glob.glob(image_dir+'*.png') + # self.label_name_list = glob.glob(label_dir+'*.png') + self.image_name_list = img_name_list + self.label_name_list = lbl_name_list + self.transform = transform + + def __len__(self): + return len(self.image_name_list) + + def __getitem__(self,idx): + + # image = Image.open(self.image_name_list[idx])#io.imread(self.image_name_list[idx]) + # label = Image.open(self.label_name_list[idx])#io.imread(self.label_name_list[idx]) + + image = io.imread(self.image_name_list[idx]) + imname = self.image_name_list[idx] + imidx = np.array([idx]) + + if(0==len(self.label_name_list)): + label_3 = np.zeros(image.shape) + else: + label_3 = io.imread(self.label_name_list[idx]) + + label = np.zeros(label_3.shape[0:2]) + if(3==len(label_3.shape)): + label = label_3[:,:,0] + elif(2==len(label_3.shape)): + label = label_3 + + if(3==len(image.shape) and 2==len(label.shape)): + label = label[:,:,np.newaxis] + elif(2==len(image.shape) and 2==len(label.shape)): + image = image[:,:,np.newaxis] + label = label[:,:,np.newaxis] + + sample = {'imidx':imidx, 'image':image, 'label':label} + + if self.transform: + sample = self.transform(sample) + + return sample diff --git a/u_2_net/model/__init__.py b/u_2_net/model/__init__.py new file mode 100644 index 0000000..4d8fa27 --- /dev/null +++ b/u_2_net/model/__init__.py @@ -0,0 +1,2 @@ +from .u2net import U2NET +from .u2net import U2NETP diff --git a/u_2_net/model/__pycache__/__init__.cpython-37.pyc b/u_2_net/model/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dec24c84e9ce1c94dcb512b9d076f74a7f6607dc GIT binary patch literal 217 zcmZ?b<>g`kg1)wYamGOUF^B^LOhASM5Esh;i4=wu#vF!R#wbQc5St0eW{P40vYCS! zG+ACU0+nbo-eL_k@^cLVGT6Y306$IUTdbu<)+ z{hhDp>pfd2WHo#~`PIMP{>`^F?XRp1J_!`g;BY>)I=tZQ6;CG&|8YZd!NDwTzv#Qy*z-SywappZ@0Tni}k^WznmZED}c7PrrX+@VW&UV)^+)tGHYh=TM{2@32iNjZ?t^t^7*r? z=U!iZbI-(Odpe*s_$HpyIB0QR1-P24d)ggi*SLofbIqFxPxlO4w++v%VO%Aecaxsh zNV?{3$}{eveIt#QmYuMZcUjBW8t$B075sXU1k?>bz16hsPVa_q*`03F?eu$B@H5k$ z-d4BSYS*)V(%If>3&F1VR-@7Bb=*e7H+nrkb*|rgZ^8D{Eu0(9yq`PUbXyy%eX$8P zdA&z2ak>54RX;7--ECCs2|wYqyX$_k(`&Rg{8WG2m1nynnr<6+&NLdWZqsoZjo)ei zeDVBq*S0=zH~PJ6%^j59?~8YwE%fVJv$M6)cl+UayRp#dwcTs-@m$+pK>6g>2ZGa; z1L;@*O)nb9^}N0_H5mGngWuCKXvb$T^5;-?jsraXw&7{J8V-!%uECMz-)++~F`D{n z-4s)3CrX3@pq>yFoP7P3Z*1K16Swdi#VoB7=4eZ=_r?27VHZ(xQUJ|J=rhJnIqX@` z0N*a3R`keHdXV+D(CpmT)>dZ9l;WR5yM7f^ThaInB+jZW~iZa_UUu+B- zH@cm7+U&UOs%9KD#Me-3;Rrwc5&Rs?ArqJ1xO!TS_Ff(r4>==$JUzg%;isd{2v;=e zig!Ⓢ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 OoUc4rIaPV4()kZqZlaq2 literal 0 HcmV?d00001 diff --git a/u_2_net/model/u2net.py b/u_2_net/model/u2net.py new file mode 100644 index 0000000..ece59e0 --- /dev/null +++ b/u_2_net/model/u2net.py @@ -0,0 +1,526 @@ +import torch +import torch.nn as nn +from torchvision import models +import torch.nn.functional as F + +class REBNCONV(nn.Module): + def __init__(self,in_ch=3,out_ch=3,dirate=1): + super(REBNCONV,self).__init__() + + self.conv_s1 = nn.Conv2d(in_ch,out_ch,3,padding=1*dirate,dilation=1*dirate) + self.bn_s1 = nn.BatchNorm2d(out_ch) + self.relu_s1 = nn.ReLU(inplace=True) + + def forward(self,x): + + hx = x + xout = self.relu_s1(self.bn_s1(self.conv_s1(hx))) + + return xout + +## upsample tensor 'src' to have the same spatial size with tensor 'tar' +def _upsample_like(src,tar): + + src = F.upsample(src,size=tar.shape[2:],mode='bilinear') + + return src + + +### RSU-7 ### +class RSU7(nn.Module):#UNet07DRES(nn.Module): + + def __init__(self, in_ch=3, mid_ch=12, out_ch=3): + super(RSU7,self).__init__() + + self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1) + + self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1) + self.pool1 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=1) + self.pool2 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=1) + self.pool3 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=1) + self.pool4 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv5 = REBNCONV(mid_ch,mid_ch,dirate=1) + self.pool5 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv6 = REBNCONV(mid_ch,mid_ch,dirate=1) + + self.rebnconv7 = REBNCONV(mid_ch,mid_ch,dirate=2) + + self.rebnconv6d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv5d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv4d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1) + + def forward(self,x): + + hx = x + hxin = self.rebnconvin(hx) + + hx1 = self.rebnconv1(hxin) + hx = self.pool1(hx1) + + hx2 = self.rebnconv2(hx) + hx = self.pool2(hx2) + + hx3 = self.rebnconv3(hx) + hx = self.pool3(hx3) + + hx4 = self.rebnconv4(hx) + hx = self.pool4(hx4) + + hx5 = self.rebnconv5(hx) + hx = self.pool5(hx5) + + hx6 = self.rebnconv6(hx) + + hx7 = self.rebnconv7(hx6) + + hx6d = self.rebnconv6d(torch.cat((hx7,hx6),1)) + hx6dup = _upsample_like(hx6d,hx5) + + hx5d = self.rebnconv5d(torch.cat((hx6dup,hx5),1)) + hx5dup = _upsample_like(hx5d,hx4) + + hx4d = self.rebnconv4d(torch.cat((hx5dup,hx4),1)) + hx4dup = _upsample_like(hx4d,hx3) + + hx3d = self.rebnconv3d(torch.cat((hx4dup,hx3),1)) + hx3dup = _upsample_like(hx3d,hx2) + + hx2d = self.rebnconv2d(torch.cat((hx3dup,hx2),1)) + hx2dup = _upsample_like(hx2d,hx1) + + hx1d = self.rebnconv1d(torch.cat((hx2dup,hx1),1)) + + return hx1d + hxin + +### RSU-6 ### +class RSU6(nn.Module):#UNet06DRES(nn.Module): + + def __init__(self, in_ch=3, mid_ch=12, out_ch=3): + super(RSU6,self).__init__() + + self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1) + + self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1) + self.pool1 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=1) + self.pool2 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=1) + self.pool3 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=1) + self.pool4 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv5 = REBNCONV(mid_ch,mid_ch,dirate=1) + + self.rebnconv6 = REBNCONV(mid_ch,mid_ch,dirate=2) + + self.rebnconv5d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv4d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1) + + def forward(self,x): + + hx = x + + hxin = self.rebnconvin(hx) + + hx1 = self.rebnconv1(hxin) + hx = self.pool1(hx1) + + hx2 = self.rebnconv2(hx) + hx = self.pool2(hx2) + + hx3 = self.rebnconv3(hx) + hx = self.pool3(hx3) + + hx4 = self.rebnconv4(hx) + hx = self.pool4(hx4) + + hx5 = self.rebnconv5(hx) + + hx6 = self.rebnconv6(hx5) + + + hx5d = self.rebnconv5d(torch.cat((hx6,hx5),1)) + hx5dup = _upsample_like(hx5d,hx4) + + hx4d = self.rebnconv4d(torch.cat((hx5dup,hx4),1)) + hx4dup = _upsample_like(hx4d,hx3) + + hx3d = self.rebnconv3d(torch.cat((hx4dup,hx3),1)) + hx3dup = _upsample_like(hx3d,hx2) + + hx2d = self.rebnconv2d(torch.cat((hx3dup,hx2),1)) + hx2dup = _upsample_like(hx2d,hx1) + + hx1d = self.rebnconv1d(torch.cat((hx2dup,hx1),1)) + + return hx1d + hxin + +### RSU-5 ### +class RSU5(nn.Module):#UNet05DRES(nn.Module): + + def __init__(self, in_ch=3, mid_ch=12, out_ch=3): + super(RSU5,self).__init__() + + self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1) + + self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1) + self.pool1 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=1) + self.pool2 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=1) + self.pool3 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=1) + + self.rebnconv5 = REBNCONV(mid_ch,mid_ch,dirate=2) + + self.rebnconv4d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1) + + def forward(self,x): + + hx = x + + hxin = self.rebnconvin(hx) + + hx1 = self.rebnconv1(hxin) + hx = self.pool1(hx1) + + hx2 = self.rebnconv2(hx) + hx = self.pool2(hx2) + + hx3 = self.rebnconv3(hx) + hx = self.pool3(hx3) + + hx4 = self.rebnconv4(hx) + + hx5 = self.rebnconv5(hx4) + + hx4d = self.rebnconv4d(torch.cat((hx5,hx4),1)) + hx4dup = _upsample_like(hx4d,hx3) + + hx3d = self.rebnconv3d(torch.cat((hx4dup,hx3),1)) + hx3dup = _upsample_like(hx3d,hx2) + + hx2d = self.rebnconv2d(torch.cat((hx3dup,hx2),1)) + hx2dup = _upsample_like(hx2d,hx1) + + hx1d = self.rebnconv1d(torch.cat((hx2dup,hx1),1)) + + return hx1d + hxin + +### RSU-4 ### +class RSU4(nn.Module):#UNet04DRES(nn.Module): + + def __init__(self, in_ch=3, mid_ch=12, out_ch=3): + super(RSU4,self).__init__() + + self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1) + + self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1) + self.pool1 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=1) + self.pool2 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=1) + + self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=2) + + self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=1) + self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1) + + def forward(self,x): + + hx = x + + hxin = self.rebnconvin(hx) + + hx1 = self.rebnconv1(hxin) + hx = self.pool1(hx1) + + hx2 = self.rebnconv2(hx) + hx = self.pool2(hx2) + + hx3 = self.rebnconv3(hx) + + hx4 = self.rebnconv4(hx3) + + hx3d = self.rebnconv3d(torch.cat((hx4,hx3),1)) + hx3dup = _upsample_like(hx3d,hx2) + + hx2d = self.rebnconv2d(torch.cat((hx3dup,hx2),1)) + hx2dup = _upsample_like(hx2d,hx1) + + hx1d = self.rebnconv1d(torch.cat((hx2dup,hx1),1)) + + return hx1d + hxin + +### RSU-4F ### +class RSU4F(nn.Module):#UNet04FRES(nn.Module): + + def __init__(self, in_ch=3, mid_ch=12, out_ch=3): + super(RSU4F,self).__init__() + + self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1) + + self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1) + self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=2) + self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=4) + + self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=8) + + self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=4) + self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=2) + self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1) + + def forward(self,x): + + hx = x + + hxin = self.rebnconvin(hx) + + hx1 = self.rebnconv1(hxin) + hx2 = self.rebnconv2(hx1) + hx3 = self.rebnconv3(hx2) + + hx4 = self.rebnconv4(hx3) + + hx3d = self.rebnconv3d(torch.cat((hx4,hx3),1)) + hx2d = self.rebnconv2d(torch.cat((hx3d,hx2),1)) + hx1d = self.rebnconv1d(torch.cat((hx2d,hx1),1)) + + return hx1d + hxin + + +##### U^2-Net #### +class U2NET(nn.Module): + + def __init__(self,in_ch=3,out_ch=1): + super(U2NET,self).__init__() + + self.stage1 = RSU7(in_ch,32,64) + self.pool12 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.stage2 = RSU6(64,32,128) + self.pool23 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.stage3 = RSU5(128,64,256) + self.pool34 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.stage4 = RSU4(256,128,512) + self.pool45 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.stage5 = RSU4F(512,256,512) + self.pool56 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.stage6 = RSU4F(512,256,512) + + # decoder + self.stage5d = RSU4F(1024,256,512) + self.stage4d = RSU4(1024,128,256) + self.stage3d = RSU5(512,64,128) + self.stage2d = RSU6(256,32,64) + self.stage1d = RSU7(128,16,64) + + self.side1 = nn.Conv2d(64,out_ch,3,padding=1) + self.side2 = nn.Conv2d(64,out_ch,3,padding=1) + self.side3 = nn.Conv2d(128,out_ch,3,padding=1) + self.side4 = nn.Conv2d(256,out_ch,3,padding=1) + self.side5 = nn.Conv2d(512,out_ch,3,padding=1) + self.side6 = nn.Conv2d(512,out_ch,3,padding=1) + + self.outconv = nn.Conv2d(6,out_ch,1) + + def forward(self,x): + + hx = x + + #stage 1 + hx1 = self.stage1(hx) + hx = self.pool12(hx1) + + #stage 2 + hx2 = self.stage2(hx) + hx = self.pool23(hx2) + + #stage 3 + hx3 = self.stage3(hx) + hx = self.pool34(hx3) + + #stage 4 + hx4 = self.stage4(hx) + hx = self.pool45(hx4) + + #stage 5 + hx5 = self.stage5(hx) + hx = self.pool56(hx5) + + #stage 6 + hx6 = self.stage6(hx) + hx6up = _upsample_like(hx6,hx5) + + #-------------------- decoder -------------------- + hx5d = self.stage5d(torch.cat((hx6up,hx5),1)) + hx5dup = _upsample_like(hx5d,hx4) + + hx4d = self.stage4d(torch.cat((hx5dup,hx4),1)) + hx4dup = _upsample_like(hx4d,hx3) + + hx3d = self.stage3d(torch.cat((hx4dup,hx3),1)) + hx3dup = _upsample_like(hx3d,hx2) + + hx2d = self.stage2d(torch.cat((hx3dup,hx2),1)) + hx2dup = _upsample_like(hx2d,hx1) + + hx1d = self.stage1d(torch.cat((hx2dup,hx1),1)) + + + #side output + d1 = self.side1(hx1d) + + d2 = self.side2(hx2d) + d2 = _upsample_like(d2,d1) + + d3 = self.side3(hx3d) + d3 = _upsample_like(d3,d1) + + d4 = self.side4(hx4d) + d4 = _upsample_like(d4,d1) + + d5 = self.side5(hx5d) + d5 = _upsample_like(d5,d1) + + d6 = self.side6(hx6) + d6 = _upsample_like(d6,d1) + + d0 = self.outconv(torch.cat((d1,d2,d3,d4,d5,d6),1)) + + return F.sigmoid(d0), F.sigmoid(d1), F.sigmoid(d2), F.sigmoid(d3), F.sigmoid(d4), F.sigmoid(d5), F.sigmoid(d6) + +### U^2-Net small ### +class U2NETP(nn.Module): + + def __init__(self,in_ch=3,out_ch=1): + super(U2NETP,self).__init__() + + self.stage1 = RSU7(in_ch,16,64) + self.pool12 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.stage2 = RSU6(64,16,64) + self.pool23 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.stage3 = RSU5(64,16,64) + self.pool34 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.stage4 = RSU4(64,16,64) + self.pool45 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.stage5 = RSU4F(64,16,64) + self.pool56 = nn.MaxPool2d(2,stride=2,ceil_mode=True) + + self.stage6 = RSU4F(64,16,64) + + # decoder + self.stage5d = RSU4F(128,16,64) + self.stage4d = RSU4(128,16,64) + self.stage3d = RSU5(128,16,64) + self.stage2d = RSU6(128,16,64) + self.stage1d = RSU7(128,16,64) + + self.side1 = nn.Conv2d(64,out_ch,3,padding=1) + self.side2 = nn.Conv2d(64,out_ch,3,padding=1) + self.side3 = nn.Conv2d(64,out_ch,3,padding=1) + self.side4 = nn.Conv2d(64,out_ch,3,padding=1) + self.side5 = nn.Conv2d(64,out_ch,3,padding=1) + self.side6 = nn.Conv2d(64,out_ch,3,padding=1) + + self.outconv = nn.Conv2d(6,out_ch,1) + + def forward(self,x): + + hx = x + + #stage 1 + hx1 = self.stage1(hx) + hx = self.pool12(hx1) + + #stage 2 + hx2 = self.stage2(hx) + hx = self.pool23(hx2) + + #stage 3 + hx3 = self.stage3(hx) + hx = self.pool34(hx3) + + #stage 4 + hx4 = self.stage4(hx) + hx = self.pool45(hx4) + + #stage 5 + hx5 = self.stage5(hx) + hx = self.pool56(hx5) + + #stage 6 + hx6 = self.stage6(hx) + hx6up = _upsample_like(hx6,hx5) + + #decoder + hx5d = self.stage5d(torch.cat((hx6up,hx5),1)) + hx5dup = _upsample_like(hx5d,hx4) + + hx4d = self.stage4d(torch.cat((hx5dup,hx4),1)) + hx4dup = _upsample_like(hx4d,hx3) + + hx3d = self.stage3d(torch.cat((hx4dup,hx3),1)) + hx3dup = _upsample_like(hx3d,hx2) + + hx2d = self.stage2d(torch.cat((hx3dup,hx2),1)) + hx2dup = _upsample_like(hx2d,hx1) + + hx1d = self.stage1d(torch.cat((hx2dup,hx1),1)) + + + #side output + d1 = self.side1(hx1d) + + d2 = self.side2(hx2d) + d2 = _upsample_like(d2,d1) + + d3 = self.side3(hx3d) + d3 = _upsample_like(d3,d1) + + d4 = self.side4(hx4d) + d4 = _upsample_like(d4,d1) + + d5 = self.side5(hx5d) + d5 = _upsample_like(d5,d1) + + d6 = self.side6(hx6) + d6 = _upsample_like(d6,d1) + + d0 = self.outconv(torch.cat((d1,d2,d3,d4,d5,d6),1)) + + return F.sigmoid(d0), F.sigmoid(d1), F.sigmoid(d2), F.sigmoid(d3), F.sigmoid(d4), F.sigmoid(d5), F.sigmoid(d6) diff --git a/u_2_net/my_u2net_test.py b/u_2_net/my_u2net_test.py new file mode 100644 index 0000000..e3d7b1d --- /dev/null +++ b/u_2_net/my_u2net_test.py @@ -0,0 +1,103 @@ +import torch +from torch.autograd import Variable +from torchvision import transforms#, utils +# import torch.optim as optim +import numpy as np +from u_2_net.data_loader import RescaleT +from u_2_net.data_loader import ToTensorLab +from u_2_net.model import U2NET # full size version 173.6 MB +from PIL import Image + + +# normalize the predicted SOD probability map +def normPRED(d): + ma = torch.max(d) + mi = torch.min(d) + dn = (d-mi)/(ma-mi) + return dn + + +def preprocess(image): + label_3 = np.zeros(image.shape) + label = np.zeros(label_3.shape[0:2]) + + if (3 == len(label_3.shape)): + label = label_3[:, :, 0] + elif (2 == len(label_3.shape)): + label = label_3 + if (3 == len(image.shape) and 2 == len(label.shape)): + label = label[:, :, np.newaxis] + elif (2 == len(image.shape) and 2 == len(label.shape)): + image = image[:, :, np.newaxis] + label = label[:, :, np.newaxis] + + transform = transforms.Compose([RescaleT(320), ToTensorLab(flag=0)]) + sample = transform({ + 'imidx': np.array([0]), + 'image': image, + 'label': label + }) + + return sample + + +def pre_net(): + # 采用n2net 模型数据 + model_name = 'u2net' + model_dir = 'saved_models/'+ model_name + '/' + model_name + '.pth' + print("...load U2NET---173.6 MB") + net = U2NET(3,1) + # 指定cpu + net.load_state_dict(torch.load(model_dir, map_location=torch.device('cpu'))) + if torch.cuda.is_available(): + net.cuda() + net.eval() + return net + + +def pre_test_data(img): + torch.cuda.empty_cache() + sample = preprocess(img) + inputs_test = sample['image'].unsqueeze(0) + inputs_test = inputs_test.type(torch.FloatTensor) + if torch.cuda.is_available(): + inputs_test = Variable(inputs_test.cuda()) + else: + inputs_test = Variable(inputs_test) + return inputs_test + + +def get_im(pred): + predict = pred + predict = predict.squeeze() + predict_np = predict.cpu().data.numpy() + im = Image.fromarray(predict_np*255).convert('RGB') + return im + + +def test_seg_trimap(org,org_trimap,resize_trimap): + # 将原始图片转换成trimap + # org:原始图片 + # org_trimap: + # resize_trimap: 调整尺寸的trimap + image = Image.open(org) + print(image) + img = np.array(image) + net = pre_net() + inputs_test = pre_test_data(img) + d1, d2, d3, d4, d5, d6, d7 = net(inputs_test) + # normalization + pred = d1[:, 0, :, :] + pred = normPRED(pred) + # 将数据转换成图片 + im = get_im(pred) + im.save(org_trimap) + sp = image.size + # 根据原始图片调整尺寸 + imo = im.resize((sp[0], sp[1]), resample=Image.BILINEAR) + imo.save(resize_trimap) + + +if __name__ == "__main__": + test_seg_trimap("..\\img\\meinv.jpg","..\\img\\trimap\\meinv_org_trimap.png","..\\img\\trimap\\meinv_resize_trimap.png") + #pil_wait_blue()