From b90f20c3b1f680c0281db3493b2344ebb1f89ff6 Mon Sep 17 00:00:00 2001 From: zhanghuilai Date: Thu, 16 Apr 2026 13:11:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=94=9F=E6=88=90=E8=AE=AD?= =?UTF-8?q?=E7=BB=83=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/bil2rgb.cpython-312.pyc | Bin 0 -> 2049 bytes __pycache__/mask.cpython-312.pyc | Bin 0 -> 48977 bytes fliter_sample_spectral.py | 2 +- only_mask.py | 3 +- shape_spectral.py | 14 +- train_sample.py | 517 ++++++++++++++++++++++++++++ 6 files changed, 527 insertions(+), 9 deletions(-) create mode 100644 __pycache__/bil2rgb.cpython-312.pyc create mode 100644 __pycache__/mask.cpython-312.pyc create mode 100644 train_sample.py diff --git a/__pycache__/bil2rgb.cpython-312.pyc b/__pycache__/bil2rgb.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92feb4e22e7a68b4bcb535f6095b3a451ca7ac52 GIT binary patch literal 2049 zcmah}>u(fQ6u+}Gv#+5~mQsX3ZBo(=0^3DuEsrRVw2cjc^ov=WY^FOyJL~N3MZ491cgs4pyq$RFUBZPo-bfH8sD(oYhLpYhzCM_0sfk~!yh&OLMP zx#ym9f32ztBA{M#O6v0>bdM+wd2Fz>55Oc6kU+^OMuGImo)jIUDPp5#CdJ0sGNxp2 z$`|w7I1md6%n=j|3M_DLgbI5XNyr0X%3#FwTM|gNC&dqn3CiAz2o^pXzNO!RO(M-* zOF9XG-60*4nzrp@)H8iOuCJ%UmvN#kOC9OdD3nI`SaOs@a8!YrCYb>V>?q_pM(cFa zXIUz_<|;|Q3tcd6pQsOoy~FQ=IoJeb&YfI1ITdYLn7dKRepC7=cmMjV`Qc3I)J*C4 zrJ&_9{vN2EWi0R--`Vuwm(R?jUoV_JVje$L`r)h6rJpMOAKW-;e*UH9ZwH+C1e`6O zrq;;j==Sa5a=1lO!^Ht$xQs}Oi;sbYS;Lc7jG!XogqYSOSu~i0EGdSUSG5sEG}vJ& zt#yPMgCQvyw48a{V1}f@AtRt_Skw|jqM(urlSBU94Pbv~eGX_wZLW0s*!^o)%nMihQ&IwF;*R%#BuDY!z!qi1Xq2V2$m6)ZPdpm8v&13T z2HF{^abQ{Wr~z?RQ+wrPWbYn^YoeL zrkE-9VsO53+svU^s#x1O+c#hPO19?~7rM!rG4kkO7 zJNQ#53Dq25G_jt}sMixZe*<^lv)SQ@hBg5EP!|L{RdH+#n z3p6zFAptLvsxR&!>>Oc_fyh(Izayz(4wH^Dn2aK(4IdU^91@}tz#=ci2l%v5Zh1_q zVX&&kC*H(l=8V8$oJsK*^CP$lbX*NA95hx`=4#MVYS8eJDDk$44ca4y-?9Lzv)7zS z69wDU9;qrMqol)^7u&;qn z{T>)haV_F%#>2VrMDNW|>wKtns$r&~80wgPp&0DS?tSP-HTC1ETq^%+v3h;B>sEDL zS=&>r-T)e`jpfGjeZ`vRv)wT6YuaX37aLzLFstq~MqCKi*5aBS1*QR9YU;*^azlm2 zaADKV!tR5G)rShN$9}7RBir@Jk5)ELZauN}{7W~Rqw~$tAEQ5aeAiKI-dU{Qm3{3G zt^p$8RgiXgg~6tWQ_6^SH=L@72@Uh|7Aa%hD1ES}*Sf2^6t5|AMw2D-x)Ee}ZAmM# zW_U8Hb<3nK7g0I9RXhLAR7Mz<#ohQtSRzk>x*pg=nxd%NsQxZmcNeX?i#FUwfxkSp O)W)Ta>!{V`|NjB4nHX>Y literal 0 HcmV?d00001 diff --git a/__pycache__/mask.cpython-312.pyc b/__pycache__/mask.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a62dcd592d2c3fdd2b8f7c76e5384325b915be18 GIT binary patch literal 48977 zcmeIb33wA%nkXt+k}XTJCCl=Pv1PnqfibpO0uD=zF*{~4(BP0b#wCm$ZV_q|L1QL5_Afy+dkQ>P+#b(^LxR*7k<*0?rpotDI7TI1{D;hDNs*QT%2lV_S% zLt8>!LR(^8BKaNLYHTyrnfUxkbxEW?bDbIPajnU1mO4vYN?i({o?4e0qp&Bnln5OR z-x=-4O8N`(#@o{wo!w$jv8Us|y{ZgI!oR(0M*o_+E`u@HRW0+wrG*%iKuXG{?Tuv; zq3kr~8OAt8X_Gw*+D(y9rM=l3L;69(SSIN;P2Kb%YbtEe?qxTC|B?&l$!?S3a2cW z74c4|ll7LqSIcBWshP~;Da%c@VsprvlV2HH#tQGYXv#XLez&>M8{3~yZU&T_HRXDq zy1hIoH~UX0mk;HNnF9GQgDITi`BeRgWoANsb7B;$6-?1<3dZ(v4BZ*(O5zptA5+21 zg0E>d{1wB@&w;-Z_?rvAOCRx-nV2$o6LW=H;uXxZQ`S*#*SEYR>`37|GtXW&)2-(?%x~^ zx!(x&{;Wt$v0>8a@DFJ|nrG~-OAp>SiwU8dr|zE`47rCwZ=DOh_eJQ{llZjC-rCyP z;jl+_qX;t%-3(nFCY3(;;x9wTZi>%nrMht(P>oF)RBvu@?t^=5TL)urb=YEpvCVC) zy@A2Iqv3!Z(&E~g=C+0=J0z+%G&`I@&9<)2Ry*WqYVTm}L0x-STYY0kYX|EH#nv|x|L3nfI$ntJj4h13_xY{#VEtT$%!?R%cT&Wu2j5m zQ=#aNc}&gNkEly{x!tPAl#P!n2tSz^MkOrpZuOr~UM(rFaq5K@S`0!ge0Ql_YM16? zegxgIPNR_Kie)qi5}DW|Fmu9;M5M<(CS5x@eXpuJ&ZTTg5?Tr0U2#GiO2zS8YK2Q# ztFXm)eFQmlR=Dn;IydI-8#{h1bmiT#w}-}$oxK0p96Nh+{KK;kdVi)P*(%v4 zM+J#tq3|NAu#TVYdGOPtv>Gf*3elQq(XC{aNlMc!A@}JA=Li4!*732cCr5`rq7O%h zZx*d6wyrL=ZncehZiQ~0ByEn*g6=lWBiHYjH__2eEWf{(Tw}|}abb@C4-9ZIv-r~% zAB<`5ghk%a&UCZ|)egIz32NY1lRX&M)!w|fgKZ0H>8Ehm5!CH-9H@78)U!={f~w|r zXE3&*v(w(r*t9IZ>0m7X(I}gPs(oGXAvqf0<7sd3Ai z9rZ%)wg$(`C7p+Z#wL5a9on?>Uoe{wRj0zA<8L77QA}7AiKd=a_tde+)*fAZtmbG< zU-^hS^^dWN#N@t;|D2HRR^CfAoow!H_9td@iP^qHt6Oz1CGGUC{$2i*LN2Ay;~1>+ zrIfmL_e|!~@%{0BQ!Z!9_2hXRKGSTs25K^<`4e-wM0|E+Xn`+rv0DXCP04-p`u6uP z9H{DF;xk$=%crTg^FGb;Em-AET)h>lgjdRkiamBdQkOv4K+&N%x(ky}daSQAQD%cG);oTtQ zeh=1R=<`eP;ZyJ<`9M$K|Jjd5KmQWI+vxC#P~Y*X_Xm7?6;=df7vJQe82uRN)*-%9 z*gZbPS|7PxNP9ze1M+!~7QYq9RR}kBCI(rU-#|WXJ5!I{W~bw$1fh%MnFH4X9RQn$$;piXc7@MSC|C+9 z^We|%4g~NqrYf{41IoK`8TX7yClB==@}?IJz?^G2(*lvfTrR8l`idKCuB{nKUfQ!^G{M|g*4GA= zq|W@$2}N#YAY-~G=}d+@Ay8O6xMe8m()ROhZbRP-ceQyF8bzXQLaQ*Od(~-d0rp-) zFodAN(b&*xuix9y=8ei}a+xJO?|xn?2|=Ybq7Ectwd8g(h9;0_k><4UQ? zQjIL7cH(DGt`?ck6Bayx-MukR@dIzcjX3JM90to87knCfW8f2r?fL++QCK5jfE0U^ z1Ak=xDy)dEz5WwEo3Os6lUiZDf9ulNsV_qBc|xD`O$80b_WIre_(`h^{pdLTdMI{C zI#$D)ppRswlP}3`Nf%bs#wi&atSd=9 z)*||ziml|;*``=$VrN2Rok?mBFDZ6Dbls+67s8Ew27+J$T{$(?uy$&<*<$G4xeSsV z2#&2*x*;ZXbeKtxAiFgn5r-sPge9+^f3d^4?SZo>;B`WLS~bubYx5GS3y!0bqHuMfYBa)9fKtGeZVes389H|kVf?A9W5H#S&L>8m^`!CI+MU$jM$kbJKh2R z##@Ke(M5iCbT#e6h;tuoV*5H;8T`@M(YB|#-OkLki49?6bF6&DfOMR@IePQ02VZ=8 z|JDHRqMv_w|A#+^eRYfs=bvx6$3Gi*aOJ{3-|CI7f%ZtKfg(5K1MX1IE!>uW_yNua zHYQxqDCxUUg0@M=8=VmcC*)gGyMtDK|I*Fz)7PW3k_iyCCSJi9_k+6Em4nYSTv z>c-w0d~l)<@xPmIjh*ccT{toJ{woh&JwA5kDozpMcF0aF|I%RJ`s}q(pF3RP*`D#A z9Uc4ekFXT!+9YCejPPKjyA{H?poYAypc>x*5M+)6K{ZZXP(!967%z?sNj%#85!3ee zm)il9iE9%`#8k%av^P5I_cpfzB(2|bxSnE-lb_QDQzqpnJ+MrAj9r?Xne=gT-L%u0 zlPU?1BC3oqrl4*IlAhHp+rh%-Od$ITn4gHvIVZB-PQZ%U`Y_mL*lkdv4NF~t03ddu zLYvr^b~i5lp0U7V_Zf@5+TuXGvG19?@tIMN7T%2q{5IdS-DjNb)y~FT3x1e$&zR?_ z_8Dh+wX^VvOeUGCp1m8Nea~ncEbtjiz1mVNSaCOgx}?F;#B}ep*@LSF7kM-0`w|y; zwF?Nyh~Qu$%11!Oe}S$2@v#2UkX@jufD0C;?Bq~SA|Mj5fCxHJ1_gD+ATLVNGEipG zmn2n&zeMOg9uwIOyM4C`I9lNzCPvo=$a!Roh)PCXk``t9!>Ad}$Nb2fDUa)2Nw7jp-LVi)0$xLG5AY#?7itsQ zYeDod>T<;jefYC`Z*VW827(qze{#8!g%JP} z3h$f!$hjb#CaD#%?5OLqL0CE67D?|HMP-AZE{o7gcZy_vRLJBsi#byzbs`HW>T;#J zQkp=hEsRYmrIeojdsd2LNt3iI_dTadW<~A`Ok?zt?>XI-4k)%6Xsv{X^9qP^`1;)MgkB#EUF)Gg0kL{; z{oJp09R$Ep&@}@ZM7Rl#afDp(2-suo?SLaSA82+SCbS|vRK09JY|9~pB4AhtoK+}N z3MN)<+OTPB{nphh%2#i#+!ZveZs>A2nj6|zw05!VTBt9Wux$-cl56T$tgWfsx+|#X ze{R}VyFHlHz%+D1JN9h?&L7OITv@q!+u9w~^?b(FmD_7;*H+flR|Qjm)~|K4U5&tq zZ*Fg@Znd}BfpMR(ansh#YwD{vY*@RwwmN8N>tH*9e&}dATzx30qlud~SJwpfG+wn~ z6J*QcM`>rOI@&rr+My=L_nMviYMl*EN6=7JRbRWUavNcxP%dLE@EY104uPD&K{$|e za28S66-)vWrGY(+IAv=+v}}j+dz;&#;&x|87YN=GwpMT3T3@{rcrrDW8-mGIYbw{) z)K_laymiyg`r5S{H*cs8s#@*sK@~Qjhn``%O5iyLb@1bW{m`1O*4Cho@Hy*Sn_spE zwbjq$Xuu=7-#~C3bP%I-(z<;3FRKtLW}hc z&=Mi^gRw8$*>-y?Od^&AE_?$JUsQ)TQanpg2XaenDy`!z81G!dwJ;2d&AV3mG zwMlovwP3g4E5qOv{5jg;^8jAO4CGZT>0L6QIqUG}lyNy_K7D!5N)&yVsn}$|>De*3 z#g{m@XEi*vq@7;cztod9m^)Z|Jq6T_8f+cDd~QT zjkDMST4O+~zo*svwS}CvkVG;#ZAL(=3uxmXCd8%0_G|=EPEtzG+JMp2v*w$m%z=#~ zrde+FXp+UBG>c1`b$OnD_7ZOPlHq;6q}A@&duf^ew3%Gm%t7_##;fg@+K2agw`?6r zt92W~Nrvl(ESJiP+H}-Gz z%=TGI-0|?9P8xa*eY-psPwb#-L|Y6wGP3;XWn6lh@ZxXp@TG5XC)|T~ol?N16nL7i zC*R1qmUDZKclQe;DKENp-xxEz+6-V_dey0ui5J|f3Gwn%Sd9OVC0#c4D#V;3Ing46 zhzKRA@E%av@Yv-@fmkLE&=!7#gcOMD)^^8t>s)b6JV6b&0dWz}=$?=e&^vKcBUg)+ zk4SDVz1Y9_Bk;W2;L^Gbgb?`iN17)z6h_dyV_mU;gz3AELK?wGWSMU~2aup*-yL=X zoIGS|eg2`qZ~{aId8O>z7~q_bBSkgNKmbX&5ZE&qApXO?fB^~v2tHF|GgFrL9(>Y> z0Tv5tsv6qc53|kqpap}MF+ffU0rV`3vHcj}iem`|(2lVV3_2kQrgZ>9(*`n_`o?Cq zu?qkiWiZ(iD6__eIlD2Z1{p~X_En4)BVaDUbaHL)+P` ziyhDm9R4OQsju>tAADm<>1*iUb2iVPIg87jtn71Z&#VQW6$nlDb6LPg z$_SWJy_vHi*>9Z38RtX+s@TYj7x*M4dRSQw`Cb>Q_{A$*^ASzkbtB(Ny{?8z$Midk=y>`81>~?Vdf%$ z#p7y|;RON6h>NH#SLk!g3?UZ2hc{_iE{e$cX#p-#^d$n37{UXR&gQJ>yugQuWwe*$ zg}Em{j)1ssy-UjwUJ$ztcw%u;Ku(4q!*ja~PSngGmz?6e%OLhIjsUp?SG+4>N^aNF zjkHW?IXr(Nki*Sh0_3Ffp?@C;M;Z&$?CehH0964vg|X)`z>g;k%xZx6L#7goa4eV* zCdOB+-YU@M5GAxZp~hJ|=H80|3hUW@SS~4oLa$$2vm>bA)9gIh?6B8^E}bkmY{k+@ z{5}CpWZ#2)wnPg5aP6`P1cPeOMlB1*QIUrjDW}j6p&}az0@)wnGX#FYIG#>)Am2Lz z08;TZy8*LeUiom(w-`WQj`ExovrmxpUX|3>(iG4 zT+#vsN9ck4LFM2)k;16@<)*JTaiz6B%eJE%dsez<-UG0hn8zjNc~%bQU3U2AZsg`} zyjM`HXf$k-S};+R6jn{Q(Me15*H9v*om{-!@R~1IlX)XD)Qd z0n8nk35tV$qm47#F3-4Hbg9T^oHx|S85chh$i>Z{fZTlbzZ1yC7NRax`(R>3%0{Zp zhbTbQg#wi+=pgyrAT$x{mI`a+bH{;&56%Ew-5LoXk^|qcp6S&hlZrY~!uAZb507d@ zfFpxYK75w|N&KjyE=Jt&yQM(#>FW^%B@v<{8H6DM*vg;`pyn*hR=hJs=x&P)_;!^cO*MiwsB?N`jyTDD?=zl3bsqf+abSu4N3D6GQ|-DyDi|ZE`a(b#2!0 z_=FgMR@r_fM9!;Ajhhch{Hf7(1{6U=nmpfQl zuskJ1ZpGFjNmW}?G({RqsL-+?y@NI(`8|(4i%lDN&MN`E;x9*ALu)JhKGu$y*OVZe zy$Goe9C#$ShF_Fs-H4?zcn%@<`xIhZ1jzh^tl7k*le>C%^&JGw!zy1w5m2T;#nLA# zPpvP(CVdj)S>a2V*|Q4ZKjfl8Z0b z`sXa;<}ACd^(C+E*+7V1ndhUEh~W(+{}U6#2BQS#BV;eWQ#PUpOd}HJBQ~()PUVQc z=06ykPeC+`5WEofiVgrsokLE4?eur6-d0xF#@3m@TU!f=P@7vizGY(U`dHk7z}Tp(ZCYfWOMsgw8oN!Tm(Qxfv-8( zY$VX4w4{MTu2qm8)Ugd3w(MT?9%B|GEgI^x&JTI zdH9AYod@{zcL*i;eF;>c#9atl;;*Ns^CDH}WN0i2wIl-za0d}~Xc-2o3>=%JAeboh zJ$!%aHlkwj~au}_cnAmOXHi2SdBBMnZ3W|w;=Q1%` zMjZh~i-a1&cOHr+IcE#cTuEYYsM1@CGfzlsDHdYkdpLhP@LamhF0+eBL>;I&XmXih zog{Q?A)X3~gIc0EC{-?%8=v-Z;{!(Y(~T}Xf|790g;;n5j22gZce2aqN+vkMpZg}Y z&N8tT(a#G=jgijPcg=y#jlgV5=ZYo*K;CWw6?mX*CmRb)#vG!H&2(5d61y8HKQ?f6 zbhrmBLHLS#ddJ?p1iEdbw+5&NoT%+jmEZ(@{^PV;S6&76w+CMyquOwx;cyz(96Het$~klHouDVSY~zYt6Y zx1KN)UCKk3(A#Spp(8zPjw`~Q5wACA`pBR&o6Bi%AY7b)2iNSji*ep>b zIpKK+HK^rOMsMZxHjip(InaXL$sT5pVim7ofL{s~Dkl=E{ zky0`T7I+H0$wfUI0wxQuZZ&GkdW5DGX#8Z@xD4B1{&m$2<2B>$RPVO!BN;o~iTA{$ zl3RISmV8=rr_lStiz6BJ?nLN*TDCuRE|)rYDAAX?+@HFNOI`If`^!UL9rC4a_SWv; zQg^uZkWEy`(tGzbj?849Tp_D??vUo=b;C&?)toIqxA4qDPr=!xx0OWg%9JJ5v6@MB ztfq%`tTKp>l_&sMi@HjAFaB8qfRt$i2f?3!-va7lC70Q&hb|rRSr!e?<1EWaV<2;1 z?9vB_fK$u*|?DSt%e=Qy3isP{~w~JQ|STsTkGE zP|jflW_aw&yCJ3ni+K7>gD46) z<5B=K9nfHU$+Gg}7)@9^8(8My+%jk<$X`JLDa;mk#dPZ!RkuFuYotX6i3=-F0TQZ3 z;#?SUL`u9gMItmYxD4Qb0QQpZ1VA`cF9U+aDv!rIMFdt(C5utIG_S`%2o@0(wIFW} z&=UZuDwORrF-HJpbtSrp7X$hWfiAQ`Qm`GcR(O)!Vr`^MlFNj35Eg>Um1G1`&t*CS z`&qYHGEZ`7V7$wWd|VhKpiaUZ0TPf5i~@>Gz2-^=DR@G+?szXCF$lbMT{8sWJ?8mz z?8Fsb|C?xj-~ZVc_s?H>F!U;TCPLMw6F&@n@frn%6rKXG9s8h^j!(od|`uRd0_xs@gK{}2}Ty(%F0Ps_bWIiLd#GAUqC(Cmj zc3|uh1|LCi|L=Z{*Z;A+iAE-t+YHq7odD5=m~RgTjTkT(yo&*XUC`GiK47Soyr!dx zZDxWhM^~EwY=40{zs8)(LqX-?pmJYOd60;xiJlhae(Qix)53i^^$5I4UK~q z)(%SMRL>0DI?(o5KMZ6H!SlNifN39qXYP< z3w*|fz3Oj_79!@A*O;E9N(SvFXY{NOq^9+3f;KFvrx*7xK3nTa9n3#J-8X&i_2i)) z!_2i8d}UR)xA>A*_iXrmTAo`U0Q>*kyZUJXg9S=uThHx0v(vN3v){94aK>QS;0(`R zZu%Tfo9Wi}6$O$q1}girJW6zDvvWv!e)mu%m%o5BEf}7Cd;g~;oN^ie<*vVN| zf{t)%`suy>d%;=3VrY6u$xScwrIx$(klTl6vGoOPJ=1 z5BC-{h1ISYtWgSjfhttWIW!_O35JJG5iyYC;4>N*aLgezL;&7|?nD5!(y=5&j|Jq% zWRwJm0+^PS0EF9qlq{V%LIY6$_!fz*fNyst0r)0i1rd-9=8BK)H9=`4eFu}p$9zf9 z5}Pi0V{+>ZPzOW?gg4x7d0c)WCvZMY-%0zXi1y*TBB+R&qHu`(vU?)dQUn4A#)hJ# z$E9;waFs>mCNnSeS^UOzPcYx#^(rwEG-`>6MxFXO_}HO15p@!PNRY&~4)7i7p+IV0 zHx)ib-C;lxn)!b3r=c&7qIZllHy^zE`50-7wt`p{ZH2f$cmx{7`|%;p5p)6?g}_}v zkR-khFgX$ifCCNE>isjoGkIg|>M7vzl$MmvDJv-jMh$e0y0chNKzlF=!J?%nyL<_w zRz!}2Yr2LiBK!?RS=6L&`o87L>VG=&+H#wb{S`hW$W<}MqA)CiS7{FJv$J-JR;k;- zPz+q|?Pr~orEv#K?Z*IxIJOkZ*C4!!06ukLa2Ep~1YiP2D8c$eV(f4*o&k534eh|Z z2qre7QCqu+R3)K(7z=)^z!evd_xu{``a2B%7K8tUwHhVa@CC5H!Kb=rux@0j^_z*t z_kdTVea?1ZlLU@*oZq}lLRe7v%~}dP&3l@eJGR% zZ^3aI0)m)n4aW{0J@o34zAdl(MZlO$*a1(6Ze?bjOFxtD$sbHQU*yY}&8bttyH~q_pISEP@_J*bZE`+ zA#VQaJGtDv^<4UTpJ@ZQZURH89sN57*7{NkdupIqM%F;hV8c)eSMnT}Rq0D#;Z>&~ z4rD?nKor-!r%yP!sCQA{ioPvR)K0GkDR7w46He0@a*T(iUuo(w3jvv zmw~w(m$t-PxfK{LT;+Byb$idIKx% zLRT#*eTVv&cyc*&o@f8yqVuky1`cf7%+Gk2)_AvUjCNWYfu%d8l#^8QN-!RDgQ181kxQ!i2oN8>Gr%n6Q)5V~RMlO?U4+^ITa_9$ z$Y8U~RBeM+1>%Mv72^91j2;mSZIQz#!a6KkSKQHGN^;BLonTD{QX8#+!wGO&&c2Ni zH5(%OASV?A4OFa?;aM_5tti2B#Ur+{8&*QM4&7UXb^pM5n$D%)8v|!_lthVCY=)RYj6}E+$rm4s5s;0c zo}`*SK#5fQJV}iR!J;l;n`s!6IC`TbcTrSU_~|lAMlx%1x+E1LZ`38ULe{y=x9UoOwx`k_5Teks$K7VMw}0kf&jXGarh~)a?O{M z#W~Wtw15R$x_$wlm<}-xDhZs*=NA?J@i;Q!{Q(k5Id4);*eFk7kY^3L6th-=;bN=Z zx(&El4s@C<6%gM4>}2TmVMLgTEhaB!B(By_j)#4ls#nz0#@KKl`YF40a_pzC+<)sB z-v{EVOy~e@-$Bt`K*K{9&QZA}KQ4kQy(h*$d_Q#I z9ok~JF6mP`C1nNT{NDfMo%?V9B%*E1Gt>{$fB)?>@OohWr0?tzG~5$-UXgOL={yVM zsA#8rJapq{Qle4l8)$^b!?(_kV}Rt?ID(rd_=D?TmlM8s)4ONz8eeXU4aP8?!ML{O z_Lb=0KNdU{H?)D0Ho2Dr9~sr^P=1CiG6MPJ2MR)`rN}Ah)2C`A`-)YdiX4Cf7YwE!P%*wUZHQ+L3!!~Lk zjXW^$z~0dXMr4E*?8Iu2Lk*%ovdPE_&^Y*DX{b@aMsU$RQyfM?2-940;fs1IM0pv%Z-*L`X_P zTn3eFP%oHy0|82;?L;O{V%E|?@m$oq023kJSoxr++iH)Bm0 zplfr-OAvs-eg4x3+<`Pm$vC~Pe;t^rtpYC|;B$A!z;<5}5II~D7+Ftx048bz6CeDR z5ML$PoHje4PeeDq;3&jrnh`K21&ro^ISc;(F)7{{3zlu*%suhs(%z*57N0)5XC<_& zHG1PR?}4pYQGXHGyOn*|;F*7Bsn2Zln@c%!=}?N#{ERyeh)1AeGtOjqp82S3uwiii z`K7*$GIwIYoH0c%sbIM*{QZ;x^fzcUrIAe}SeWCGU$N7$-19x&qj2nKa{-Z&W zWI-SJ12aA4VgL8wX(hFgOD*(tiP{Ru{>q(PB@myxdi5Y{$o(gM@@RIhr-&*DjATFO zMyZB1&!4k^%ULkg;mcXY8M1oUxVQG1`}She{GsYwRkve4Tm5zI9rG`~=Y4kLuN~gn zU4Q$1U(WMhLl$HKnaR4|b$!mWjh-3rHC=EFmjC#mclum!S>^3{cVb2i>mg5ShCii* zODRE{!{>n9yItr@S?iXVjx~?nR$AmRaD!CArjVC`DsLt4HH; z4zCzFOi9GHP_^pW1fT6l5u9iGiJx1OTri9SZJ&_i)h%_90 z3j7u3bAQasMF0JC3gJLE`$4=rOdpn@}(3{e)6qKnL6j2Ng2P@ z#K7ayGQ5|AA29&PyM;Tjp?E+kUZ!EgD$d|rk*ukZ*AQ}rP z#e*AtmWrN@-{|28jP%JoP5jyrUOg<2f@pFF$VfOUYA6$R!NFI!*5P`r!(gdq8b zEZ?PefZZJMGw@p`mrH8XW)Yr-@0Y{SOv;g!gJz<$*a$mxnK~s7J*0Z%au5&>=n~&z zJV@OsJji0=9&HxGsHRZfXu zO88RG`yinNMo;MVpO3wFeeA8DJovJoa*E`LZ7LLvIQ)XtI!UN0rM0D^Uy_@WwYV@T zjCl!S+bI3}zvDv`Z4ybR;PfjBiVy%oK*>}zCwmyG2*!ho*9Log6F4lvl^u-fY^IRv z`}oVew;7yYQfd)&vTtH-L) zdlL_5$^lCF9ds^l|(PhLQ~11y*v)dY27=%avKwcM0{6vfQVi4HnO)K$NbR0md#Cb$N$AT3 z8JfM{4n9a2^#0g9WaA2-y=z_qz3y3$q-SzpE%qtnk!_c(nS#h~QPdx3n>)8Q>xI1FwemwcnofQ*lTD=T2qrIeB^ zToJXoLGxL$cE1FF#=QUZOcF_VXVBL zNox5M*M(Rv+2cY(Z}4o}H_yR&8gOdjcd)BY-brBS&5=sz?yp^mNa|lheA| z+Ur3vqw!@nh}jQd@DCW=g8bCm;(V+g8LzGE<4~DD+l{KO!zMt z{38ZmWAJMX{tkn`#o#|dK=(pkjluySR*HjD6dcauhQnYXCi6oh) zu#xe45~&|5J!KyCnXExANbbQeZu9s!7Hc*@Z zlVS8naoCrT+p`LGs;AJ9u%rxV`!{&XxMcK4wdRsxXg|1M9& zr~A$MoH_r(){8sO@AR2VhLSn+d~$SFSnE_g1dMn;3F^TQGoFQlFiZXrrhkJ;M;i>D zT_SEV@R+}xxOB)Rx1EX0n|hd&Zej{K(Y~0U9@Y_`FeCGK> z4$fRbFcHw4TISd1aQYlyoYhl#H?9ECn$t@_r$>*TTb6Tkmiv;Q>(zdfobA@a7YuH^ zm-jFCEE@uis3koczR`nPHa#z~5n2>4#2)c_I1IsQgZY z6UdWbCyEz))l3o`+?|NEGAX1^X?=claz+8XfFjwe{d(XQaLJ(jT_ zXl}Fz6NKeXPk+PJAzZkbz`IvGTn7PcJb>BY>2mY}zbuM+aSH+?B1OHp`G9LsMLm`z z7w7{i>cx5wD{ZQ-1V|*G3ob<7Ugh{ZykPmvApMjuEs`0APr^f}5RdmB8$1t3Zauhh z6)kr#lW@^7!jX|zz6f172KKO!4NgOA>?CKMHFhx#c)D3bm$M`4WV47#5qAM{hB>vm z{dYT44ZHs5pR2~#LJrRoPe7CU&IBPW9Z1A{@x@U2QY9^ut4yTDu z$2}bVMT3zsez4@wP!^A1w5jnx?bf{{mFC08QG2?!zP`B~=-~PzIr7_0iIAZazC(u% znue`?h9YgcTYX#~$jpbEF_4l0H(emh>Q;|{JLl$C@;N?+dBm$l z05$X{35ELEwGt^0O7NpD;0K~oGPxez3Zo1kUJARTP)HHB2LP)R*^x+3om48?XFje+ za3oi(fJjZzlH{m*N&8w?3>(A511C)v+2&zoo+9k8KVQKvfYS&>I|fGYQoW~O4DYLi z8HG0*mS)M!8j}FJezJYs1@w2f>IbUBXjcLEgUW-7L#kbhgG!sRYZ**h=!c#MpMPFu zZ*A=am+ce`pe72KH@@!1J>|-~qo1O>K61h?p9gIqP}>o*_13^?y`5b)RZ!K`*%dT_ z5g=%@<1v@@j|0w8AoCiy-Ji!k#KyNt>;( zlAK*uNTsF4S}D&Cj(Mce3TjoY-n>1is@lB03zrq2o%A4d;o5`ipk?FkLM9{ZBsj+R z;QXT=aPeS;64u$)#>38z@>S3^yaN|37rTagOHhL+Pwxw=5da1a&5rtp0}ah^piHZs zZY&78!R_E7P;_yy2)V(Z6hFrsaYF*bO(*zz>IADfXE46{P@^5Z?RT^T`iXY7LG8f? zFcN^N4aRkW^J1J_r9Eno(zSLp@bi2mcZyvqoaGqqQ}IxDj{@Z5sLk%x=LQUB6tiTI zGmRI3q{Xcbq~-K2xoci_Vf)3p^L74$C0xN0U%@hW+=MzMexnl9@K6555C7uA{6RG` zzkGR%{CUf{yyYW#m7~-1{L{<8a4?Xb15SenEmw0c<@gE~2XgZM7^luQ_o+|m{-{$V zrFzrLhvwf{er>t8yvm!p@;4^*$e*1r77pYT{!ydi3uv)GYT1aXeAJNSwaovt>Du-? z3%v8Uc+FdXW2pVtd&cxXC{)lhl5B&sY?8gjtG(tmBZjs2GIIPGbGVE-Lj|{2k7R6c zuS8XZ|27ea`Tvcav-6d5MOoE6#V_W?uPjsjV#(~4#j3B1H4q2uinazcj73aO*U{zd z>~hvK&1_H$Tmj13Oxz0|yXr-_7&JHH8)iH9NS7;pQzv)xyT8iP#uL78R&t%a#alj3Ca4g@cj9 zqnB>mVX&hEN4q>C4&v^}5~6`4yc2Q5Mv=H!0z?fFZHP{Ll?Yg6s3SQ8L~t<+&X0i| zr(<+YF_-m%aye042O~!?I*e>ZbjCzl5tS8$RRaQ^1Ob?Uw*eFMFh@vpnS>MsRG^9- z%Niwfl;BE&IZu?%xeHt!v7dy`?gKspzk1OfQcIptbNJ2}8RKP>Fh?+Vxk6fa?aDcd z0#m?*mYG7{@ZDJ?#N|$66nkTVu@p+a9b^DRT@s~pvnv@!n)H4Qiob+9;Iu-1EdZ)8 zkw?ws-BGeSI3q46q zDN!|v-^f$flp0l&c-G`o*OV4jlX%F{Q`eLpRg>rt9BK;hFc~g$0*MCB}95OV27~0XS$8O$#?@H+N$V0>hFj!%wZQln~@hILwBzy!Oz+WGw zG^02Q9LZ#;iKlJ9@!-`Dc+Glpl6gcC0#u=IL$5x#`ZgkUw@w1~wvFwwkDdNG4(`~^ zvECjy=o^&l!GG8N&;D}kgR^j^`h%-Kg_=jdJU@2yYIv?DF&xA5%a{D*G}sD=J?KKY z$Jl8P9&Ud1GdMhxPGp6ZBuE*eA;L|91OydP94IkuHl#iFxO;06B^s+m$Fs?;l*AP#u#SAk6V@<_TbAtI6qWCWa$!w0)+c| zNzFbB3zS6zXLczBU;(=iPN4#~A_VuQK45rm0eK-%@?Vh9Ny;MKtL zL3l1s3D2;P$YG14-qgUt7^cbD3}!D5;9%_S2qv|6wM7ieL3rD2I=&$dexYy@CY%Eb z1;BsYB7Av-Lyj7+Y%K=!@EI-%b}0ts7$D1p9KOz0;!osp6XFPtwLj3%8Z^UkD-ErO z;p{N6H&ncapa^>UG9uDyhtu8`=FYb}Kmwp2nDv5WCR z1qP8Tja`P%%CPPv$?5QP_F1$>3Z@C{NaW~C@&ql?1d(Zvv%{{&U>yeQF<67aS_nXA zo{|HEHZV4~BWVED*g=|TZ{trK1rdOw;eeejfz}sM^3f&rTo#S45&z$AWnK!go&Z7{)WUN~ZS28tIi8LqxP-(R(jtJ>z9y`9q*ft~Ka z(%i2^%b1@XF)X>4Q|z6y@^+gqXPZ}>6;4|;Vpx1HZT`@9 z?~={Fv@LE!IO(|&LnV;1*8Fov&Kx=S7iaz=U`P+7Ob<-61#-&3JbAsJQcp| z5`XqQE_Iy4c6KWm23`+9LFn+_Xh(Pfq+!wi=VWq~$dH55LGL_UA)ld8>XuNOZ-> zDcFD#YnT@y@*5=2M6LxGtLs6f$KcZKRZG%EN*_$X)n~<-Rw}?LaVhxo17DFgP1oBn zH6ltYMa}@_0BO$S2@1r59AOC}MY~ZB^wy;ZZ=8J$dQGdRn0Uy2`oZ}@u`g7Xk6dnI zQfSizW11QE7w|i%-m|CU5Q|*QV6uIGS2N%m=uAZ*ML;j-AQnS#OBL{cg)yStLlk@d zfIm^YhmC_eSY-SXlRNMegKSp{@e$4k^#bAo7IW-e%y$<99|lCz2X%e`lL7m?!-#qv zA~*PTi2kCzWOqYd4itw(L4K<3vk_8{*rtH;lToN_;3GQ_2Lc#x0p&h-;x`D+2deSp z(D&94mfg)N4kYJ#4Y{z%X61U4Jk=N1o?rXp^+UPmH~FW{2iP=yhUaDA(7HE{fty_`3=@8db%%te8W zY>&p%HE8#y&%c)r=gYkpADCJ3tv)s{@xLl!6O0pc6{wXMU;fwf>BF@Eu%hJ+O^Dy@I5E%7{MQT=E zihT@fkC-@^^zOu4tb`VbBm;tRtliPo>U22p4bd--;@1WcOfk)kPC~97$(!PflV;k4 z-`XOm2EMf{MRFQF#66If8%UcL#w*Qf6A6ms;)ja3WF1II%nDOl-$5|R1dNs}HJhpi zG@?N_g3wPkO$|AegC~HaydpYl7an0)rG8m@=fsU5UF#BNG@OK)1N>1@)XD_ zDWt`1h4en4Hedzj(rWC_L<@) zA-|yk)32tZ-458p{R=m#0t}r!vD}m_NGM9%vX++27qdSZFH%~zR4hv*-b7v)MvADw znX*_TI!ndc045$>`Q-j*uhM*CRZpdKMM_QDcV+inYY}jRIuBdP=Wl}!ja@wn+%}$p zdukBiQK;`Y;&5+Yhg}*xBtN+N2F2v64>h!Pw%RMiJ}z6f%!(+Wb*WW`AwhQ9qM2m9 zA%{z%9EJt+Xi+$>A*!EZpLjop;OL^~7Ja|K(G6YuKtxT~u8imkt+50!u_Bul>ZM~E z>-h}EK{8%ag+FLs6No~c$gdt05Xi28JEBcXb3Af$0D&;Cgy_Kil!6^WH#B{!sbRaI z{$>O+$W#L*?{bByFpxYQycGvhQC@C}?OB7S92URc%IU3`l#~%jD+o-RGZC*a6e`MCSBN0U(Oayn7MALXp;hjup@i0d^-w2!KJSkN9EGX z9dj?^-PY?{W(X~X?=ADfaUli*Es8*cg$W3><0AyxN!?};^d`BC zdyzENb?t{GN50w7&)$*>sea#cl6SK%tXY z!G8~IB7$cn;iH~orHDG+&_kb`zJK|rqr*S57J)KP*o!>oo@15lwALa}FCX*VqGGDX z1LY;nZLGb4fxV0Za@gadi^I@L)}jUqIDUF??Yy;U>*^J>ig3<ya;9hrV@hk8@zW>hDP+R0fmD#H{OFfXn?|v-h6BPD43p}7(aF*bm0Wm zn3L+dMr`wdp8*){`zd%M1L52ll>`z!Yd{pK*CwbIg`+$ijZC8jAjhhPRtKL2WVyuT z6{URyB?8qz5!&L2gvEfh((mej4g!*Ag)JiDnnS@)a4K7vzee#XmFBh#e_|~; zFm7LiqrnM^qbhiz>|v}MaUd2=dg!?!9*hwLHWyQgJU1-1-G-?Io2|rH24>j+fpCJz zBN1Jy{dxe)V9UXHGNbiu(;gPFNp>p+C~ReGF}4i@89C}>4g<-X3S*YMOZF(#-G|8Y zOArC%xlXCjn)?dQCXd8T=Peyi{-E~<1NISP{ylS^w{YpOefWFc{A!|I1D8coei5`V9lS zF01@Si@Bo3K2wET10`gT_(X*^!5fzjj7qomcp`8*H3@!o8mCShQD=bEPMb11`&p2& zF7j9HDmy31}@M84)lig9qzWkcwuZR5UAtQ>XV-yBG8oPM}oOYcBNa z3%%+>LSHn(dlfH{mOy^`Y1A->V~(VLL*S?!O$zLfJRPy=2JkV7SkeS#nJ+R z^#i+=_!?r+k8eDq1NBFq1_3R3zBC+PBvE;kJWT*!Sc!=AgDRgN~b6lpgAAct^R@fa2&l$H0P7LP>pkR__NTl&jA+&WDnR6qhGv<+?T(4 z`$+c6irp(4oDI9-)2OGa0=qYE#wX7ZRgessbegRz59(dIbSdaRy$06NRON@_wx9s? z*5HE^eKsqkvuhzAFhuct1@54zf?Puxh~Gl$HntHGNrk#7|ESVxLsyQEx%+b2D#%Qf z8`zattQ=~1L@78T@&4eOpj-utR`=f;8b5XB!PTo3R?uE2$|7X{L1ryG9|ADPAuKjj z+z2Mp&%1-I--nh+!33UVOMkM@KpqD!3M*ced8=*%ivsoyNcmU%Mt2z0jZjESLT);oRnWHgIXBV3re@ zmL15+4VY7beVefa*tZ!v@VH}A#3y=9^TF%hJ#9jtZeXd`wuGCu)SJ1?yKIX$aqDli zwf{P*xBNkUlgHm$f_c013TxXQ0x&1qNvw+R)d{F?(;M}MWNGDY!KN_^!))mPbx zm1U~0$}|v1wk{5+z8>D66{kl@nZrunQRXFZlu4fOFB7@JHSAu@sg-|Tv(2`EZG{X3 zTm&@)O`)vbq_zfUXKRPEwRulT=V6S2(K@}WI$NEnROQ?Ui7fIdSv;Q;&n=*~Ak=I@ zFZ?WN?qKoFu=ouHHIByS&cnoA6&fqB?cl@G!Q#M!v0&{1zbJPZSrF{^vED=qa>cwz zj(9A5ty|Ff3C-10|py0sKH9~4IT|Bs67e^A7Kqe$z~`W0!MB5goB zqR5?y%~YB_zzK)jpn7oo(7a*QaP81iZcZgvwBjK?o~TGsrVs2n*K(!>IPA*w;bd~V zZT@BESDC^-bKa zecp}xxYf-MF~>xaURkdkh&iV_1Kf0s52Xw_hO34SUCW`rZ*To&-B)!FN!qtr`O1ZZ zah&u@2j83dnrYX~fzCrX(`QKOk3SJvTy>+|&bqrU>Jj7rB*ZjjOrS)3{h7*V4pu-@o z*|<5dd0Sw1*|%}|%Gg0zZ*Uuisel`i*5JK*-GmD6L{@|MbsHx%aEG0^&^CePAok4S z8!gvb9+F=*N=3DDgEFx5`M~q_f!!|!maX_U-mX;69B!OY;5|_O%!G 1 if isinstance(x, list) else True)] + + # 过滤面积过小的样本 + df = df[df['area'] >= 500] + + return df + + +def rename_wavelength_columns(df, prefix=''): + """ + 将列名中的 'wavelength_' 前缀移除,替换为指定前缀或直接波长数值 + """ + new_columns = {} + for col in df.columns: + if isinstance(col, str) and col.startswith('wavelength_'): + # 提取波长数值 + wavelength_value = col.replace('wavelength_', '') + new_columns[col] = wavelength_value + if new_columns: + df = df.rename(columns=new_columns) + return df + + +def save_spectra_to_csv(df_corrected, df_original, bg_spectrum, bil_path, output_dir, plastic_label, + all_corrected_data, all_original_data, all_background_data): + """ + 保存三种光谱数据为CSV文件 + - 背景校正后的光谱 + - 原始光谱 + - 背景光谱 + 同时收集数据用于统一合并 + """ + base_name = os.path.splitext(os.path.basename(bil_path))[0] + + # 创建输出子目录 + corrected_dir = os.path.join(output_dir, 'corrected_spectra') + original_dir = os.path.join(output_dir, 'original_spectra') + background_dir = os.path.join(output_dir, 'background_spectra') + + os.makedirs(corrected_dir, exist_ok=True) + os.makedirs(original_dir, exist_ok=True) + os.makedirs(background_dir, exist_ok=True) + + # 获取光谱列 + spec_cols = [c for c in df_corrected.columns if isinstance(c, str) and c.startswith('wavelength_')] + + # 移除波长列名中的 'wavelength_' 前缀 + df_corrected_renamed = rename_wavelength_columns(df_corrected.copy()) + df_original_renamed = rename_wavelength_columns(df_original.copy()) + + # 获取新的波长列名(已移除前缀) + wavelength_cols = [c for c in df_corrected_renamed.columns if c not in + [col for col in df_corrected.columns if isinstance(col, str) and not col.startswith('wavelength_')]] + + # 保存背景校正后的光谱 + df_corrected_out = df_corrected_renamed.copy() + if plastic_label is not None: + if len(df_corrected_out) > 0: + non_spec_cols = [c for c in df_corrected_out.columns if c not in wavelength_cols] + if non_spec_cols: + first_col = non_spec_cols[0] + df_corrected_out[first_col] = plastic_label + + # 添加文件名列用于区分来源 + df_corrected_out.insert(0, 'source_file', base_name) + + corrected_path = os.path.join(corrected_dir, f"{base_name}_corrected.csv") + df_corrected_out.to_csv(corrected_path, index=False) + print(f" 背景校正光谱已保存: {corrected_path}") + + # 收集到合并列表 + all_corrected_data.append(df_corrected_out) + + # 保存原始光谱 + df_original_out = df_original_renamed.copy() + if plastic_label is not None: + if len(df_original_out) > 0: + non_spec_cols = [c for c in df_original_out.columns if c not in wavelength_cols] + if non_spec_cols: + first_col = non_spec_cols[0] + df_original_out[first_col] = plastic_label + + # 添加文件名列用于区分来源 + df_original_out.insert(0, 'source_file', base_name) + + original_path = os.path.join(original_dir, f"{base_name}_original.csv") + df_original_out.to_csv(original_path, index=False) + print(f" 原始光谱已保存: {original_path}") + + # 收集到合并列表 + all_original_data.append(df_original_out) + + # 保存背景光谱 + # 移除 'wavelength_' 前缀 + wavelength_names = [col.replace('wavelength_', '') for col in spec_cols[-len(bg_spectrum):]] if len(spec_cols) >= len(bg_spectrum) else [col.replace('wavelength_', '') for col in spec_cols] + + bg_df = pd.DataFrame({ + 'wavelength': wavelength_names, + 'background_value': bg_spectrum + }) + bg_df.insert(0, 'source_file', base_name) + bg_df.insert(1, 'plastic_type', plastic_label if plastic_label is not None else 'unknown') + + background_path = os.path.join(background_dir, f"{base_name}_background.csv") + bg_df.to_csv(background_path, index=False) + print(f" 背景光谱已保存: {background_path}") + + # 收集到合并列表 + all_background_data.append(bg_df) + + +def save_combined_csv(all_corrected_data, all_original_data, all_background_data, output_dir): + """ + 将所有收集的数据合并保存为统一的CSV文件 + """ + combined_dir = os.path.join(output_dir, 'combined') + os.makedirs(combined_dir, exist_ok=True) + + # 合并背景校正光谱 + if all_corrected_data: + combined_corrected = pd.concat(all_corrected_data, ignore_index=True) + corrected_combined_path = os.path.join(combined_dir, 'all_corrected_spectra.csv') + combined_corrected.to_csv(corrected_combined_path, index=False) + print(f"\n 合并背景校正光谱已保存: {corrected_combined_path}") + print(f" 总行数: {len(combined_corrected)}") + + # 合并原始光谱 + if all_original_data: + combined_original = pd.concat(all_original_data, ignore_index=True) + original_combined_path = os.path.join(combined_dir, 'all_original_spectra.csv') + combined_original.to_csv(original_combined_path, index=False) + print(f" 合并原始光谱已保存: {original_combined_path}") + print(f" 总行数: {len(combined_original)}") + + # 合并背景光谱 + if all_background_data: + combined_background = pd.concat(all_background_data, ignore_index=True) + background_combined_path = os.path.join(combined_dir, 'all_background_spectra.csv') + combined_background.to_csv(background_combined_path, index=False) + print(f" 合并背景光谱已保存: {background_combined_path}") + print(f" 总行数: {len(combined_background)}") + + +def process_single_bil(bil_path, output_dir, segmentation_model_path=None, + all_corrected_data=None, all_original_data=None, all_background_data=None): + """处理单个BIL文件""" + try: + print(f"\n处理文件: {bil_path}") + + # 从文件名获取微塑料标签 + filename = os.path.basename(bil_path) + plastic_label = get_plastic_label_from_filename(filename) + if plastic_label is not None: + print(f" 检测到微塑料类型: {list(PLASTIC_TYPE_MAPPING.keys())[list(PLASTIC_TYPE_MAPPING.values()).index(plastic_label)]} -> {plastic_label}") + else: + print(f" 警告: 无法从文件名识别微塑料类型") + + # 验证输入 + validate_inputs(bil_path, output_dir) + bands = [912.36, 915.68, 919, 922.31, 925.63, 928.95, 932.27, 935.59, 938.91, 942.23, 945.55, 948.87, 952.18, 955.5, 958.82, 962.14, 965.46, 968.78, 972.1, 975.42, 978.74, 982.06, 985.38, 988.7, 992.02, 995.34, 998.65, 1002, 1005.3, 1008.6, 1011.9, 1015.3, 1018.6, 1021.9, 1025.2, 1028.5, 1031.9, 1035.2, 1038.5, 1041.8, 1045.1, 1048.5, 1051.8, 1055.1, 1058.4, 1061.7, 1065.1, 1068.4, 1071.7, 1075, 1078.3, 1081.7, 1085, 1088.3, 1091.6, 1094.9, 1098.3, 1101.6, 1104.9, 1108.2, 1111.5, 1114.9, 1118.2, 1121.5, 1124.8, 1128.1, 1131.5, 1134.8, 1138.1, 1141.4, 1144.8, 1148.1, 1151.4, 1154.7, 1158, 1161.4, 1164.7, 1168, 1171.3, 1174.6, 1178, 1181.3, 1184.6, 1187.9, 1191.3, 1194.6, 1197.9, 1201.2, 1204.5, 1207.9, 1211.2, 1214.5, 1217.8, 1221.2, 1224.5, 1227.8, 1231.1, 1234.4, 1237.8, 1241.1, 1244.4, 1247.7, 1251.1, 1254.4, 1257.7, 1261, 1264.3, 1267.7, 1271, 1274.3, 1277.6, 1281, 1284.3, 1287.6, 1290.9, 1294.2, 1297.6, 1300.9, 1304.2, 1307.5, 1310.9, 1314.2, 1317.5, 1320.8, 1324.2, 1327.5, 1330.8, 1334.1, 1337.4, 1340.8, 1344.1, 1347.4, 1350.7, 1354.1, 1357.4, 1360.7, 1364, 1367.4, 1370.7, 1374, 1377.3, 1380.7, 1384, 1387.3, 1390.6, 1394, 1397.3, 1400.6, 1403.9, 1407.2, 1410.6, 1413.9, 1417.2, 1420.5, 1423.9, 1427.2, 1430.5, 1433.8, 1437.2, 1440.5, 1443.8, 1447.1, 1450.5, 1453.8, 1457.1, 1460.4, 1463.8, 1467.1, 1470.4, 1473.7, 1477.1, 1480.4, 1483.7, 1487, 1490.4, 1493.7, 1497, 1500.3, 1503.7, 1507, 1510.3, 1513.6, 1517, 1520.3, 1523.6, 1526.9, 1530.3, 1533.6, 1536.9, 1540.2, 1543.6, 1546.9, 1550.2, 1553.6, 1556.9, 1560.2, 1563.5, 1566.9, 1570.2, 1573.5, 1576.8, 1580.2, 1583.5, 1586.8, 1590.1, 1593.5, 1596.8, 1600.1, 1603.4, 1606.8, 1610.1, 1613.4, 1616.7, 1620.1, 1623.4, 1626.7, 1630.1, 1633.4, 1636.7, 1640, 1643.4, 1646.7, 1650, 1653.3, 1656.7, 1660, 1663.3, 1666.7, 1670, 1673.3, 1676.6, 1680, 1683.3, 1686.6, 1689.9, 1693.3, 1696.6, 1699.9, 1703.3, 1706.6] + + # 修改HDR文件 + change_hdr_file(bil_path, bands) + + # 处理BIL文件生成RGB图像 + print(" 生成RGB图像...") + rgb_img = generate_rgb(bil_path) + + # 分割阶段 + print(" 生成掩膜...") + mask, filter_mask_original = run_segmentation(rgb_img, segmentation_model_path) + + # 提取特征 + print(" 提取光谱特征...") + df = extract_primary_features(bil_path, mask) + + # 背景校正 + print(" 计算背景光谱并应用校正...") + bg_spectrum = compute_background_spectrum(bil_path, mask) + + # 应用背景校正(不进行重采样) + df_corrected, df_original, bg_spectrum_aligned = apply_background_correction(df, bg_spectrum) + + # 数据清理 + print(" 清理数据...") + df_corrected = clean_and_select_columns(df_corrected) + df_original = clean_and_select_columns(df_original) + + # 保存三种光谱数据(同时收集到合并列表) + save_spectra_to_csv(df_corrected, df_original, bg_spectrum_aligned, bil_path, output_dir, plastic_label, + all_corrected_data, all_original_data, all_background_data) + + print(f" 处理完成: {filename}") + return True + + except Exception as e: + print(f" 处理失败: {bil_path} - {e}") + return False + + +def parse_arguments(): + """解析命令行参数""" + parser = argparse.ArgumentParser( + description='批量处理高光谱图像,提取并保存背景校正光谱、原始光谱和背景光谱' + ) + + # 输入文件夹(包含BIL文件) + parser.add_argument('--input_dir', required=True, help='包含输入BIL文件的文件夹路径') + + # 输出文件夹 + parser.add_argument('--output_dir', required=True, help='保存CSV输出结果的文件夹路径') + + return parser.parse_args() + + +def main(): + """主函数""" + args = parse_arguments() + + input_dir = args.input_dir + output_dir = args.output_dir + + # 记录总开始时间 + total_start_time = time.time() + + # 检查输入目录 + if not os.path.exists(input_dir): + print(f"错误: 输入目录不存在: {input_dir}") + return + + # 创建输出目录 + os.makedirs(output_dir, exist_ok=True) + + # 获取所有BIL文件 + bil_files = [f for f in os.listdir(input_dir) if f.endswith('.bil')] + bil_files.sort() + + if not bil_files: + print(f"警告: 在 {input_dir} 中未找到BIL文件") + return + + print(f"\n{'=' * 60}") + print(f"找到 {len(bil_files)} 个BIL文件需要处理") + print(f"{'=' * 60}") + + # 用于收集所有数据的列表 + all_corrected_data = [] + all_original_data = [] + all_background_data = [] + + # 使用tqdm显示进度条 + success_count = 0 + fail_count = 0 + + for bil_file in tqdm(bil_files, desc="处理进度", unit="文件"): + bil_path = os.path.join(input_dir, bil_file) + if process_single_bil(bil_path, output_dir, + all_corrected_data=all_corrected_data, + all_original_data=all_original_data, + all_background_data=all_background_data): + success_count += 1 + else: + fail_count += 1 + + # 保存合并的CSV文件 + if all_corrected_data or all_original_data or all_background_data: + print(f"\n{'=' * 60}") + print("正在生成合并的CSV文件...") + save_combined_csv(all_corrected_data, all_original_data, all_background_data, output_dir) + + # 计算总耗时 + total_time = time.time() - total_start_time + + # 打印总结 + print(f"\n{'=' * 60}") + print("处理完成总结") + print(f"{'=' * 60}") + print(f"成功处理: {success_count} 个文件") + print(f"失败: {fail_count} 个文件") + print(f"总耗时: {total_time:.2f} 秒") + print(f"平均每个文件: {total_time / len(bil_files):.2f} 秒") + print(f"{'=' * 60}") + print(f"结果已保存至: {output_dir}") + print(f" - 单独文件:") + print(f" - 背景校正光谱: {os.path.join(output_dir, 'corrected_spectra')}") + print(f" - 原始光谱: {os.path.join(output_dir, 'original_spectra')}") + print(f" - 背景光谱: {os.path.join(output_dir, 'background_spectra')}") + print(f" - 合并文件:") + print(f" - 合并后的光谱数据: {os.path.join(output_dir, 'combined')}") + + +if __name__ == "__main__": + main()