From 0b1eff36b77ce8446b13d4a159427a5dc9fb059e Mon Sep 17 00:00:00 2001 From: s212246 <s212246@student.dtu.dk> Date: Tue, 16 Apr 2024 11:12:16 +0200 Subject: [PATCH] Watershed --- .../operations-watershed_after.png | Bin 0 -> 8152 bytes .../operations-watershed_before.png | Bin 0 -> 6532 bytes docs/processing.md | 1 + qim3d/processing/operations.py | 57 ++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 docs/assets/screenshots/operations-watershed_after.png create mode 100644 docs/assets/screenshots/operations-watershed_before.png diff --git a/docs/assets/screenshots/operations-watershed_after.png b/docs/assets/screenshots/operations-watershed_after.png new file mode 100644 index 0000000000000000000000000000000000000000..d4d2f64aeae05356731f0b4ba467bef3ff33d4a7 GIT binary patch literal 8152 zcmeAS@N?(olHy`uVBq!ia0y~yVE)X&z;Ky^je&vT><(uR1_lPp64!{5;QX|b^2DN4 z2H(Vzf}H%4oXjMJvecsD%=|oKJqtY}9fgdNl7eC@ef?ax0=@jAbbW>2|Bf&)FmM)l zL>4nJ@F#*W;|lxbnG6i_uAVNAAr*7p-mRQ4r*x<Ohx8db$!02(W^7<hYV<xS=AhHK zIEH1B5<4$rimpRn4yVS7f*mrA6S%KGVG-zi6v)zB!0a5sFO<UFrIW>>xwj!;Q-z)y zi;{p+^t7Gz0k+@He7XJioKN}wzh(7yp(|(A{r3Hye?i^$e&xLH-?x>PmX@+IFfdGz zmQLNvz`($;puVM&fq~(KWTG4c14EJ940Z;FhB<=I7#SE8(y>WNPWpCaZuz~P(_TwV zY4`u<^8Nbz-_!rUxqd&k{@1+D^IPM8J!rV@QvCAOE3Mx(%Gcd3`|bZ#T=QPQxuXBt zmOn>of62_Qc)C||&615P`~Us^9Vo79XI}L0rfGHjtM!qu7ti^3<y?B${<zJhI&zyo zHvE4lsju_?<B$95zA|r$iXJzW%X`+myWdv3Y1RACm3B(2F3h~2Iz2Y&U=ypLpkdyf z9XnpFTFv%*l5Ne`)$zTz^LFdz?S8w>;^~y&Ro`~K_P@V5XF_|{iqzUSd%xc+{QLF# z@g`R8q=$!EZC^c3mj4|QQ+(F+;{|8_qkAepulhDGz<2AvKQ~gR$3A*)|G)B1#pB+M z1rHD1NNkr?T2%Aaz+x$r9dq#MUoT#~==gljT0d{c!?qnSm(5Okc4nsSz3&g(<@;E< z#Y+B5+SOECy(hhD;k2)T@6uQN{eItGOeaEM?%cT-Z{C!2mn{wXUd%36k<h<u=lgxX zliuCg85%9#yYN<H?S`Q8XO}B}KAryf$K(F>w_f|sG*VsWH&?1%rpRMW{C>N2JD<&p z*p?G%^J77u<<H=^zbd|5bWi^H=;+0(S4ExMcsf_F-)A+i;!)?0|NnkJo*Ew4X<7X2 zh`ZgVi8qq_Z9zWNzPhfz@bR&utl}{O%jZ>P*?hlKY*_N*!aIkcb!7_#LwDQt+5h{I zk)Pl1%x9_6#v>^-J+3OV=G*4^z18n_sw*kQRXl99c(dW~s&91x-dET47uh?njo7H< zXZdtW#MZ3P9w}3;b$h?vs(93?o^*1O>fN))o6em(x8w6U>($%zG*nAx$lKLa%&GtP zbK~1>w~y^AeVuf5RcPU-lj`3s(jOh^1V@tn-^=!{E=TyR-v}(9Usu&5V`-$MRQI7- z{>Y=F-N~!hZtF5WZ)1F{PgdHwov(Lx-Y(5``~Us2d%yF3-S4Ba<#z=0_x~+(ak*1; zTGz1j)s;z!`}RNnnki!S{n*=;D&4;-KA$zO-t&J$;^AG#3&YmMNNR_#>p3}D{raou zwkw-f^uN5k{P^7Rdy?mEzsI<^tcl%ic5Pj(wBXb1_L7nZtJS-I-N@Vhc9%2A@sB3D z%XKpISuC(V<GlF9BD+(6dA8=<-1Kh!^)->g=k5R3<ZQc{wlU@8B)R9ce;&*CZ%jUZ zjG5oY;KBR7)0Dq4U#;G=@B7Cv$?f?|-qpM^_`lM>R?DqlPWJLL-|mhM!{lRAZ0pa= zFf`1+x97(*^Zk<E)Af3{ZQCYcTUC;?<)T~RMOX2ome1#aZ7L}#IpSac>++Ao^8W<< zZ9cm6U!P%+=+yt(Ynpz%T<~(gx1Zy#?(wsGS<^VLXw!=Rjt<%KJBH^hpU=6GwR-KM z&6|zI^y6Z>^ZD6SyMN8FsVvfo-)FOK&!<xr|9{_?2ibgDZ}*zt(+_90yG?YhwfXsE z^2Yc3ejnTW{hl-^>Fxb~&)Th5>gwM=V$nH**JI0Lb8c)<%-j3*+KV@De7^3Lxv_KA z@7K4N)hoQMXY!bG^?Z1y&paE;vKxu*Gi<BN=0E4Nda+=~<38)8ySqx6t8zWGOJ~&o zdbvD#cJ8*$&FAf`r|Con6<(=rmo4iMkE>9erWY$E_&)Z){;IF9K+Xjjrnm3Mqj$yb zeKL~rzb>@1#rRCvy5?2#%}uF=CluR{sLjq1Dt>;hS2K9ok>q~cu)FzuY?|G_B#cr# zd}bP{`q_LuQt^82_D6d@pX;9NXQipP^U0)+0Be&zomY=vtzO?Z(>VRupP!$T&(1Ra zc-;P<VcG56?HwHzuU0NkdUa*x#<a7uB<$;IV(NZA{dg;T{n5MS_hX;Fm(j|;^2f05 z&yO8XCV3})dvkMR(bH3M=SxdUj{N)mUjDdDvCsZ^@n0a%emp9kd}~YQ$4>tmrLz0A z-!1-rx%~KoGr#PG+3Vu=T3y{5p&hoSqf_|5;X1>@M@J&|?fFu{o}$_POXJ(C)$5Nn z^V>=Mez$wQgVW)Yi|jy=UjOUz{71d!_c}T{T)V}N79N+q{@iA(v!%UddhYk@$Ir?| zP5ypjk=?z@=W}Nmr~7?>oZN3~_V3Sgdv}*3_y7O<{_Zg-XY78rOM98m%pkKf;^j}e z`(K_jj)?qU6MAY#;p0cAwAc5@|Nn7ZRp0k!`Tg3*H`C|$rq8b}yYT+1$0WBm)$=cF zE&kT4^fm9><KzAP>(;HSc+kkctGsNEL88;6pQoqkcI$4xv+4IVq1@bD!?ZIqDjv3q zC!L*TTKJ%my=?yOr_-XR$;{sQ``zxx-0?r0KuP?<Lg&W|n)$jwuKH?zeYWhI$+Zt^ z^}qjc{+|*kADzFqbj#MQt}aJ91eKG{+kWp^KEH0)tovdiu3}#|W?Wo!qx5=g@{0@K znQq8czquGIpVeMeS9I>yJNu=5;n8AW4U3+f02S{Y9cRsM>n!u1FZcQR`TmX$U-P?L z+-u)#y&m`RO0Ylgi)!l)#i1t`#Cu+P`~1$dbzf5g<)7y4dbzCd>D2IJrq^SHx8JX; zK3NP-(od&F|N6RXDbKTOg(2V0aOO|>GueEl_2=7pyK~RXFjT&E>(-*Zdu`wCc-&X< zY-W1W^w=`Z%74=Ndj!+x6uQ+smcHL1sO;tv9v)uv|M&g=_`k2h3vXpEKRPpgo}{}> zq05%-+mC0j-z%0r|L%AB7pmUVj_B9_JpC?vYu(S&@yFKJ|9#C^w>rQ&^2+hL-*3f# zzu#ZKCVIP`*{zJlJD$(0e)Md1eqTq2=VY~`{PjN$gZ%#RaQpE^uHBDTtzPF<dsjIm zSnTV@oSU0KF$b!5H`e|ARq^d+`r|{~`aK<=wlaU6=31Mx@8`3Rci-2UUt1q9|N7e6 z?w!TY%l<oM&#(Q~2`Wy1eSN(c<jH-%-|hH%Ejs(xeTGS(Fso~`dbwnB5~$$+@v!~) z!*+Q&L2%jeUGLjuHQz3fn+%hW_1yaF-l&uttGWGy?w_{Rf};78rXO?I_4({R#<(E! zx~tKTU+tN6EM%pR)K0roFZ16zXueXuIlFrA-Nzq0;>&q{nM(V9Joim_{T}nfQ$yTm zy{oQwdl$XXPOJ2O@9oJ;z|D}FZC8rie>ax=)9$_XJoSj3FMHi>`QCMhy-s-xUk)yR z7X7pRUmE`>o;dC6>>-y<eKmY^UAC5~c5`MM!~CUb>-ZJt9n5<6>%?NGi1)IuJ_|ki z{dlJEy^Icrc+Xeapw?Bxu?f43{kMh1)CBujygqGO{Wmnf_qAbG{vNpnR<jDX$aRU9 zKj2pWzUz}gMQh-XtiIdf$;o@u-W+)z>fQG9o434A>D`)ZkH2c`?bG~NsN1xcfuG^& z)mLJrXPr9QkEOQ%d6s+z+@w?cn)j`>y3cI(J=tGtc7GJCwf^+<O3{~j^(#Wu&PK^k zX#2H5^6R~;bqi!GzcQYjwbf29YHRfT<n;On<;_)R5BA)8ed2p)ru%QV8-MhCee!=A z+|T$W{Dhn3*RAYp{L(AfzA~P?!mg5i?U#n=Gi5gU7u>&u-?0At)a6{O%<>~CGijG$ zHK>6(bJ`sSeg+1G{*v3P(-rRi(BEHDGC$e8_CxyB2*3R=&p1nF+tsG6`T1pLq&_o4 zgUsq{9kw^MM4z0NU2h6$n;x4{+dQ-2+I03UoN`x}EAulr)W19wtZ((%GF`ozfkEo% zuUI?T*X2J;uAOd}b>h{nA1a4z7#J9y^!z?!zM<&xH>*!y10}Y~@2v2<`S}X_+BK2y zg?X+nu**>0YyIi1x12`xzF!R~nMu10_%(lQXiRy<JZWYBvrk{rub0*Dy=&`i9OIe1 z(j;uY$g8XDD&E4Edv7u`FgTpMadzIMwmmh)^OIj6tJQ3t`s8qA^tu=Sem(j>Z^A<_ z2C2g{Oea^_#M!=T?FnPr`teKp^;hTIpRThBus-%i({slAl|eJ-?7ix3E64q1i%{|; zkuQ87mTrk!5iW1C`d{0RpvB)_F;9}*3~H6DrJR{}M)vEwS(A=G=a&wBJ~gC$oy~=; zOC?Xb&*yG^XTxx%$*|gJs>qXWQ>PW?Y-}g5u>a-!EZA$Fwg31le>ayS`NwR6zFrTL zH(6cPb94XCS6Afv-TU^gj(^WtnFdZPvnHIgndx<TX8(zO*6TMjfed(iM%*N-eV^DB z_Op7q?fazW{$!G^%33;6@4v6`<yd2XwM%Uk3ruB;pWm8vy#ANv_Qou=<ZC`%w)g+` zcRl}`^oFrCf;T{WY11DEj*k~6Lz05z+)4&1ub}XG$3i8h`&;MDUnb4}#QFCmb|Lq- z?6)Ug?`;3nQfU;p<DH8B?wia3H(v$ntFZlg^!jnV;D3qP|Nq?oxBA&@rmWQhx30hc z^m0}273Qgs5SnvwCi{Ygf4&qu_uhIQq5UR+f66j#|9hhT{Ld4uZmfNIB1ZWxlTv3i zx8tU$Ywm?Bwom^1;P3vczt!!wADxl2-uG_i`Owbuw*MZmzuGbB)u*4}l#Ph$7iXNg z>WX<zUU7e{eSPA4-P3%vh2?hV@BT;vr4@dUX==-Mr^zv7aGVu-z_{W~@$PSXu6#Rp z-~62Fw#r0s02jHX%P}xC?0Ru`;``c|c01d|eXcQ8A8yz7&8<szXVYeE_+GN^=I-N< zUoL)kK0}ouWK-Vf$h-0Ul^^dg?sW^Ake<*3Np&yIY;OpP{dw<r=}X2HQ}4<CFnRv+ z()Mjz|No8_6g2#D`~KMqRR@>z>uNqeZY+DTk}q*zr)p~jLzMT!vf{rxUGF9=<^3@A z-@btRR$PpBFJ~n1|15w0-d%F*dZpxVpzfiu)n{L?aJhziT(ZA9=EeSc^qAT3hF;Cm z>(}Py*Dc-k$>FiYr$;+$-QKdV+7P|>_nGgdKmPFkwc5XS_3G8yS37fanWF@@mOp&7 z|Es0ht1iL6RlL{FOb=h_bA^4aPwkdI=I}o@N=j~bYb$DAdjG!i_wQ$kS6AID|MGrx zdpo=P*NNq&v(Fc;tr1ma{gK_j=Fk6nsH={>DP9#~zVAkD_#KJ=kFPXq@9XQcVaOEO z^(oS*=>Cm)HOV1&EWYelQhIc!?|jN`i3MpTPo>)p?k}<Xc;&hFJmnM27vvYev$J`v zdgJN7M$x7kmm_Poi!bN;(z>zo`Wfc6%l2PCK0OH*Rr@+$?qLqlb?@D!^~gIsb#G7I z%};CR&2Rqy*RH&3<@BhYo45b)El}Tm^Lfb9>}UU<ryskPsk-)H-s%Z!B40mVlO6um zvh1Uv{D}nB-o?|lFOcpCTKsJ<bB*R#p08)4<hM>R$<jY!uK(3hd$mbgzB#Cr%y6>$ zJfZ2njPs_nHT^-cKbykdoimS0-!~<Hi~XEed#XyG&)#UaAPN+U>2eG!X1`qgZhN;4 zL&(8W_gs<dvZgyM^v*y_B~aOKG~vqJ{ohWU3P1e%46}p2=k=r8KYjgl_K5B)jU8{! zzTW+x;YqInKWMZAR9ARiXg%M5Z}unEyV-H>at&#Zu9Zw^ieBzu^z~wu)Kjt2${UgK zwGKvK4J+bnssq1Y-(K!>wm>x`de)3QNQfPqVaqVVYjMdF#uqoI>esDtzHilY)0yko zfee-Te?C~N_S=72{;)LeWc3yIe`{lZ9SwPYchlQhQtMUr+VtFTU%{`jJgC;D<kqTp z>%afFw`^<Nxdk#Gzh5eM*-`dnVQBsOdy4x+8twi=a)7W=8vg|qyPprsjb5Ld?4N1< zi6Qd$*)!q0_UCQUs|^a@_hV;N$qUCB>?b;xe5_hAy?LIbsNl`M+s{+?{9F2RdCFdv zjHvxHe|jBe{pFT)WM8QSxQGQ6ASXHxaqQ)@jkJC-GjL|fbLqX>>!ta>221SDKgw6T z@bkTDWgFR_*ObpNI|%>yeqCOt@=s6i_cbSfi?Y9ty1!}NMdz9p1^?RG=WBna&bR+x z>wYy;)n!k)ZH;aDW_^KshH2pNUTn-Cx}oU$-)bAV|G#$|MRBe@(Dzlu`_&0?`}nu- z{#=-w|Ni5SX|ca-N}ev9r&ap&WZT_WCz}lT87xCJPlN|?Jk87xyl#DDdJxC`X5Oz( zHeasH7x+JS`!ngS?P3X#*l<hV*SV*z>U^)c*}f|~{KL4CzaM+sXd|)f^IOr~pEGxT zI=ZZX*Z%u=EALh)tPQ(!RIV!f^{ZE}yh@Xzqt{+P#PF5x<6h3M&EYG3;_j{elDFuP z&DsS)wLku>SZlKQ+tynb>lCWk|D^GJIBI>nfB(a-P0v^H|I&WDqgL+N8|~UUP&`gL z&RQAeI14#>m~3==b;{i&U47qn{<44W->=68?lb1!I-z}Cjg-}gfO&?$)h3zb<)5kh z@XI<af6u(Iq%(4pR`O>lW?r$&SB$H5FannZ7g|c5DYlx-t-M<iHT4{qO0fI{pIV1a zCWf&y+C^$^I2b`1CBgC&&dji7U|=v&OqA2ezIwdBGgRJQ?R6>x1B2_GS$&St2069; z$J_Vbo_Eo!p-GhgU$M`P&)3#WXJl~beF4o$4E>C+?@rXuICgFiZ`6rqkfM{1x4yfu zn%`rYox)5=o58S}ZH>UKZs%HKwn_$txz_PE7D`HX+kf^-u4h^Ban6@>(zShm6Mnp4 z+&>Rq2eSE^%Wax!62~8qZ}o{`>C{)J_@|w-aX9CD<8zqxb!LVw5{aNpTy$)Pt;6I? zYuOnxc<d$Yb{${wH^FS5c0sn4$HBG1U<ZJzpZ;gtULA{7R(izD{@?EL)F;6x;qD+> z`+n2*&2dZ)%eZ1Iv%F`pGpt}zlzU+7_WJc<a1cG|fs_Qw5N~sUMnoqVAF^R^5ItkF zRyl3nwTWMi7%~KNV>92m$qVM@=5CGSHd*79y2vgg732U=aI8rAn4Mg0^Y6^>|I;pd zz0&vfxjqxrbb$;gW>j>?OW$4|eg727z+#%mHExE6JyoA~7Aq?y9WmQ%6vxS6vOnw= zgMM$!+qD1ZL{EFm$=AI)Vzs^{EP4CYV};-9_g#8^!}b5BOg8O>3$A_Ln09RM-T3}p zHS-<!UP}-?RBhR0d$gtwoDAN8Gn}u6_}rgM`f3dCR%V^d@7o-@O8WlncQs{Mk@81l ze<nqizPMcSOu6LwPxkq+q+~le``LE8??>OQpFe+V<;~*DER_o?mvVkO`keFY6{lMQ z_kY(clw(*S3Qmv{j7#625ift*Eg$~s0`pqcT=#j;%wBz}mC9naVQ6p*+-`8+`pENx z(fu`Be!u=+`{^W4IMan)EENn5`yl1nxs*+earHd*rAcbDABchsdVRt9t>i}a_c=A} z3|FG==KEf+zO!%t^;6>PzoYK-tt;<%?>i&kH*aoGJu~l@vd!!Fhppn@zHIUSsFijL z_FqA6qF$*zQ@3IFwd;$d<JVlMTz_RD`+~1MH`2n6zT30Th9Q8zRDSb$<=wZEd33BZ zkH77`p6(7R=E030V@T+Eq|a;n`d8chi)GoT&YOS!frD_R^?L33Ypbpv|Ft;3=i7YQ zn5oyBsy@OSO|6wuK`RyFC%7*7p2&PMD^mV-|31TymIvqAeE4Z-;O_G`+QlVicSg=J z?S<2>u&Y3ATJdi8P4i~`Jc+x{Z@iV>JMo|wLsa;}?Dfw4XBS@ReP8QSF1NrWai7<| z9f?~U_ybg*9(&EmU;uXIPUSO`wIkoA@iSbxwzd1%H_4UeN&FMe<bC^Fa!vLBj(M;D z&of(jy!hCg+0*ZaDbBq6MsenOP@+|sdG`$?1H%H&muHp--0Af%`gpy!(bRaqWn0SD zb^SqiD`P7^Eefh#^ZSaV;g^S%rBS>lV)pTl;L^r_g4%)aVKOhwWr~ZAem4L0^84?< zaw&(~d3)2I&ARO+_y67s=GS|KzA`>t0kI04`!k&08Q(wcVD*VLbJxcJ{rtFpS@V;X z({d&q^jfiP$-0`4#gQd17#UW`&;6;?%=w9V<HH$~|1veKs`~sXeD{A9TmNhg@gIx~ zC+raggx`y8%nShvpv)U`a^rg)t;#>I9tOYOBQ$F+*vb=<bAR&eJa6+g&HQ(b_M3qG zJ8}$C!JvB5QnqT9>x}i2y7$|e>FE{PWNxo=oEN3R_xh;yb?%RA)!%Plw)?@-{<8YN z`SLYJho>?)q&{`3Sy{|lwdx?G<nW0O4-XGtC4Bo<*4}At7w%V|jsNp?qiGap?~<UI zTfAy7R8;lfNxwL8eOawY`BUYRXD7|)%THJ{^VMSexj#7;e+!wWwv78T=cSe^$9<(H zm)m(mqPM<U3`*cD)cb4d95$t`>i^gFlWE~R6?k`2Qu=}Fjvud+z001LK4#2%{N?`N z$M^4emw(RJWjO2YJ}*n)*=d10jGNN;$T2L?hvreM&kPJ#&WO+dQ{8`jdwofYn|9+Z z&7QN<Z*!c_u)UgQUhT1PW?6Ku%G~=gfuDYSu@ru_M~KZClo=Gygdgs{t>1I@zk%-S z)R4Kq8dA!@Ee5qE#{8N;&K8!cmOklzdG2}puZEOYi__EN!smf{1xq_$uA9mJO3QZw z`+`c24-8vj{Q$^3i(#7oy4c^ZcB=NvZ#=oiYJJO=W#?xmT#;j7VDkj^6hIR)>f0yn z`ed^2WwF|nyKC?HePdt<m}lT0yzAT5;?}=10=F0$5)z>0sq}-3Q*s)n%eTJU<NJ|; z;oj%<-1j^Go90$rJH6oGR?ytfQp=AI4o{zMv+u+IoUp5`j!{pKy;v>#Ona(lbaZs+ z{q>=9znv<+8y~;zrJ3ZqmVW`@!qDjJ#q0a^YL-7KJh<=clFpaMK-onhoy|7Q{;hWX z)w$}zZZBug*0W`};5BL2rwL26uAlM$eJWo0&<R_Ef};;@Us^7dV_2}|{MLMp%0K76 zwr!j}^?xcOY=WtwM>V%-dfMmROV-sq+*x#fa(td|c=Ed6tPBj7He}oWU1$t$F)5$9 zej;<d&GmHW^+nP(j0_A8QK6EXw|Cc8l|5~{q<6bSdjAI|hAgd@>AidY=hQv_)%zyx ze$yX)Zcy{q_{F(B>uUZ#`MbSt0&6KV1CQI%m-{crRqB1W&wp`X`@C)I)~#C?qP}hG z)hb=zmEY}UD*wAL3Jui~{_3b5EWh?-YVyk!{2pQFf4w-rwB}#zV!<VyFY|oe58upO zK6g_blZg(zy`i)ItKymKGw#2+dj250yo|D2PsjYfZ_-!(KR3s+IO(`-c@Jo|C9e9d zX!f-=D<5(xTEA+}(t1~5dN?C%-mAk$<iAc^{>vk&IW|l6^)G`o|HCVv=N|(N{#N{Y zx%~0I-|w`eeY~gZ>HfBQ)m#-QZ_@QhzE4^;z^u47giE>i(|*R@)iYl&p7gJ+^6QnV zPZ9EhR-a8)+}xag{91IrENEDMdR&#}Is5;AK$A0|QSNir@Ap`II-#8W_0`pnZ}aP| z+jynLHm9BKT3`D%+py}(iy7ACc{%(4ek;5dneJL$T@4yv<Tbwon!c*N_xz%}{MiS) zn-2y;QwrnBPZ9EmY<M%@-P!r^)#~+bE=M*Vmy=eXSCMpPo~^Z9^_z`5o=%H?)WogV zVf}80a@oDg=N7+SEdKrH@8dpey=Uj=%Xf?Ec6D@IT<m_m^lyOot7f+gE9R~aTic(u z<4)tP?5n>TOrTc0y0WtH03-X64T*=7Zfr;d4YHTof1f=6kIK3okGd?r-zk24Lb<=E z{C@5B^Y{PXeP1W8KBvGbXY19lkGJptGn1?T^YNFiT$T?ggEO9t+G+<%Mc2;;2g<!Z ze3m2A!usu&;F_n}@twi`wx-KKW53VNc0WAaUT$w+^yI{iq;B0uYq#I)@-@4;<Vki+ z`Q1{`$RudCF8NrGWZ}1)>DRM=1_Z;}MhcN}ubpQsf7l~wtah*F^Vy2OU#};hn4oBw zduxl_`TFP9_dDbNJQDx7HosO|Z_kHAH!2?Y{@!zJiRa`;>+An!->Lb0w(x3b_|b2- z^W)b)b@p8esZf5cc(ciOd*M#6?o-*d5}TJlwE1$u`Qy*?^>%stem(<P^7x{=eDBA{ z$K73yENqvPN<P-pDgXC{`^BqQMd!|)YnXj)%?!)pwEpX$S-hm}cgwoBW?w(n#w(q4 zZ%?J_{nyp^f5+u)zgs3K2%7x-aXS8=5GWXP_d80kASe5W*Gf$0RNa$O(%pV<QQ!)G zk85YXPJC7sFY9_L^Vu&CXWl?Rx!1~z<iT}T2G2UAhM@x1nPx%IFe!GapZ}ZBd@1#3 S)cgvX!}fIbb6Mw<&;$S)zEXMs literal 0 HcmV?d00001 diff --git a/docs/assets/screenshots/operations-watershed_before.png b/docs/assets/screenshots/operations-watershed_before.png new file mode 100644 index 0000000000000000000000000000000000000000..95db63626d6ac8e8eceae237b03fd2c4de8a8118 GIT binary patch literal 6532 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 literal 0 HcmV?d00001 diff --git a/docs/processing.md b/docs/processing.md index 2987f9f7..550cb100 100644 --- a/docs/processing.md +++ b/docs/processing.md @@ -15,3 +15,4 @@ Here, we provide functionalities designed specifically for 3D image analysis and options: members: - remove_background + - watershed diff --git a/qim3d/processing/operations.py b/qim3d/processing/operations.py index 70193564..b932c7f8 100644 --- a/qim3d/processing/operations.py +++ b/qim3d/processing/operations.py @@ -1,5 +1,8 @@ import numpy as np import qim3d.processing.filters as filters +import scipy +import skimage +from qim3d.io.logger import log def remove_background( @@ -49,3 +52,57 @@ def remove_background( # Apply the pipeline to the volume return pipeline(vol) + +def watershed( + bin_vol: np.ndarray +) -> tuple[np.ndarray, int]: + """ + Apply watershed segmentation to a binary volume. + + Args: + bin_vol (np.ndarray): Binary volume to segment. + + Returns: + tuple[np.ndarray, int]: Labeled volume after segmentation, number of objects found. + + Example: + ```python + import qim3d + + vol = qim3d.examples.cement_128x128x128 + binary = qim3d.processing.filters.gaussian(vol, 2)<60 + + qim3d.viz.slices(binary, axis=1) + ``` +  + + ```python + labeled_volume, num_labels = qim3d.processing.operations.watershed(binary) + + cmap = qim3d.viz.colormaps.objects(num_labels) + qim3d.viz.slices(labeled_volume, axis = 1, cmap=cmap) + ``` +  + + """ + # Compute distance transform of binary volume + distance= scipy.ndimage.distance_transform_edt(bin_vol) + + # Find peak coordinates in distance transform + coords = skimage.feature.peak_local_max(distance, labels=bin_vol) + + # Create a mask with peak coordinates + mask = np.zeros(distance.shape, dtype=bool) + mask[tuple(coords.T)] = True + + # Label peaks + markers, _ = scipy.ndimage.label(mask) + + # Apply watershed segmentation + labeled_volume = skimage.segmentation.watershed(-distance, markers=markers, mask=bin_vol) + + # Extract number of objects found + num_labels = len(np.unique(labeled_volume))-1 + log.info(f"Total number of objects found: {num_labels}") + + return labeled_volume, num_labels \ No newline at end of file -- GitLab