
    i*                       d Z ddlZddlZddlZddlmZmZmZm	Z	m
Z
 ddlZddlZddlZddlZddlZddlmZ ej"                  j%                  e      Zej"                  j%                  e      Zeej"                  vrej"                  j-                  e       ddlmZ 	 ddlmZ ddlmZ dd	lmZ d Z# G d de      Z$y# e$ r4Z e d
e         G d d      Z! e!       Z G d d      Z"e"Ze"ZY dZ[CdZ[ww xY w)u[   
极耳翻折检测器实现
从原始ear_fold_detection_plugin.py中提取的检测逻辑
    N)DictAnyListTupleOptional)datetime   )BaseDetector)yolo_model_loder)yolo_cls_model_loader)utilsu    ⚠️ 无法导入utils模块: c                       e Zd Zed        Zy)	TempUtilsc                 0   	 | 0t        d       t        j                  dt        j                        S | j                  dd \  }}t        |d         t        |d         t        |d         t        |d	         f\  }}}}t        d
t        ||dz
              }t        d
t        ||dz
              }t        ||z   |      }t        ||z   |      }	||k\  s||	k\  rYt        d| d| d| d| d| d|        t        j                  t        d|      t        d|      dft        j                        S | ||	||f   }
|
j                  d
   |k7  s|
j                  d   |k7  rGt        j                  ||dft        j                        }|
j                  dd \  }}|
|d|d|f<   |S |
S # t        $ r`}t        d|        t        j                  |j                  d	d      |j                  dd      dft        j                        cY d}~S d}~ww xY w)u9   从图像中根据AOI提取子图像，包含边界检查Nu   错误：输入图像为None)d   r      dtype   xywidthheightr   r	   u   警告：无效AOI区域 x=, y=, w=, h=u   , 图像尺寸=r   u   图像提取失败: r   )
printnpzerosuint8shapeintmaxmin	Exceptionget)imageaoiimg_himg_wr   r   whx2y2resultpaddedresult_hresult_wes                  ;   D:\pyccd\极耳翻折-拆分\detectors\ear_fold_detector.pyget_cv_img_fronm_aoizTempUtils.get_cv_img_fronm_aoi"   s   d=8988MBB${{2Au S]CCM3s7|;LcRUV^R_N``
1a 3q%!),-3q%!),-Q&Q& 7a2g7s$qcaSQC_d^eefglfmno88SAYAq	1$=RXXNNqtQrTz* <<?a'6<<?a+?XXq!Qirxx@F)/bq)9&Hh39F9H9ixi/0!M d,QC01xx3!7#9NPQ RZ\ZbZbccds1   1F, C?F, 4A5F, *F, ,	H5AH
HHN)__name__
__module____qualname__staticmethodr5        r4   r   r   !   s    	!	d 
!	dr;   r   c                       e Zd Zd Zd Zy)TempModelLoaderc                     d| _         y )Nu   模型加载器未正确导入)model_load_errorselfs    r4   __init__zTempModelLoader.__init__J   s
    $DD!r;   c                      t        d|        y)Nu   ⚠️ 临时模型加载器: F)r   )rA   pathdevices      r4   load_from_path_with_devicez*TempModelLoader.load_from_path_with_deviceM   s    24&9:r;   N)r6   r7   r8   rB   rF   r:   r;   r4   r=   r=   I   s    	E	r;   r=   c                 X   	 | \  }}|\  }}|\  }}||k(  rd|z  |z
  }	|}
|	|
fS ||k(  r|}	d|z  |z
  }
|	|
fS ||z
  }||z
  }||z  ||z  z
  }||z  ||z  z   }|dk(  r| S d||z  ||z  z   |z   z  |z  }|||z  z
  }	|||z  z
  }
|	|
fS # t         $ r}t        d|        | cY d}~S d}~ww xY w)u  
    计算一个点关于一条直线的镜像点
    
    Args:
        point: 要镜像的点 (x, y)
        line_point1: 直线上的第一个点 (x1, y1)
        line_point2: 直线上的第二个点 (x2, y2)
        
    Returns:
        tuple: 镜像后的点坐标 (x', y')
    r   r   u   镜像点计算异常: N)r%   r   )pointline_point1line_point2pxpyx1y1r-   r.   mirror_xmirror_yabcdenominatorfactorr3   s                    r4   mirror_point_across_linerV   U   s   %BBB 82v{HHh'' 8H2v{Hh'' GGGb2g !ea!em!La"fq2vo)*[8F
?F
?(## 's+,s-   !B B &B 'B 	B)B$B)$B)c                       e Zd ZdZ fdZdefdZddeeef   de	fdZ
d Zddej                  d	eeef   deeef   fd
Zd Zdej                  d	eeef   deeef   fdZdeeef   fdZddedej                  d	eeef   deeef   fdZddej                  d	eeef   deeef   fdZddZdej                  d	eeef   deeef   fdZd Zdeeef   fdZddZ fdZ xZS )EarFoldDetector   极耳翻折检测器c                 "   t         |   ddd       d | _        d | _        d | _        t        j                         | _        t        j                         | _        t        j                         | _	        d| _
        d| _        d| _        d | _        y )NrY   z1.0.0u+   基于YOLO的极耳翻折单图检测算法)nameversiondescriptionzcuda:0r   )superrB   	cut_modeldetect_modelgm_cls_model	threadingLockcut_model_lockdetect_model_lockgm_cls_model_lock	cuda_name	run_counterror_countcached_paramsrA   	__class__s    r4   rB   zEarFoldDetector.__init__   s    (E 	 	
    (nn.!*!1!*!1 "  "r;   returnc                      y)u'   返回当前检测器的配置文件名zear_fold_detection_params.jsonr:   r@   s    r4   get_config_filenamez#EarFoldDetector.get_config_filename   s    /r;   config_paramsc                 `   	 t        d       ||| _        n| j                         | _        t               | _        t               | _        t               | _        | j                          t        d       d| _	        y# t        $ r(}t        dt        |              d| _	        Y d}~yd}~ww xY w)u   
        初始化检测器，加载模型和配置
        
        Args:
            config_params: 配置参数字典，如果为None则使用默认配置
        u&   🚀 初始化极耳翻折检测器...Nu   ✅ 检测器初始化成功Tu   ❌ 检测器初始化失败: F)r   
parametersget_default_parametersr   r_   r`   r   ra   _warm_up_modelsinitializedr%   str)rA   rp   r3   s      r4   
initializezEarFoldDetector.initialize   s    	:; ("/"&"="="? ./DN 0 2D 5 7D   "01#D 	23q6(;<$D	s   A9A< <	B-B((B-c           	      X   	 t        d       | j                  j                  di       }| j                  j                  di       }| j                  j                  di       }| j                  r|j                  d      r	 |j                  dd      }|j                  dd      }|rt        d	| d
| d       | j                  j	                  || j
                        r~t        j                  j                  dd||dft        j                        }| j                  5  | j                  j                  || j
                  |d       ddd       t        d       n"t        d| j                  j                          | j                  rA|j                  d      r/	 |j                  dd      }|j                  dd      }	|j                  dd      }
|j                  dd      }|	rt        d| d
| d       | j                  j	                  |	| j
                        rdddddd d!}| j                  j                  |       |j                  d"i       }|j                  d#d      }|| j                  _        |
| j                  _        |r|j                  d$d%      |j                  d&d%      |j                  d'd%      |j                  d(d%      |j                  d)d%      |j                  d*d%      d+}|j%                         D ]!  \  }}| j                  j'                  ||       # t        j                  j                  dd||dft        j                        }| j(                  5  | j                  j                  || j
                  ||d,       ddd       t        d-       n"t        d.| j                  j                          | j*                  r|j                  d      r	 |j                  dd0      }|j                  dd      }|rt        d1| d
| d       | j*                  j-                  || j
                        r}t        j                  j                  dd||dft        j                        }| j.                  5  | j*                  j1                  || j
                  |2       ddd       t        d3       n"t        d4| j*                  j                          t        d6       y# 1 sw Y   xY w# t        $ r}t        d|        Y d}~d}~ww xY w# 1 sw Y   xY w# t        $ r}t        d/|        Y d}~d}~ww xY w# 1 sw Y   xY w# t        $ r}t        d5|        Y d}~d}~ww xY w# t        $ r}t        d7|        Y d}~yd}~ww xY w)8ui   
        预热模型：使用虚拟数据进行一次推理，确保模型完全加载并优化
        u   🔥 开始模型预热...   极耳裁切模型参数   极耳翻折检测模型参数   隔膜检测模型参数   模型路径   输入尺寸    u     🔥 预热裁切模型 (r   z)...r      r   r   F)rE   imgszverboseNu        ✅ 裁切模型预热完成u%       ⚠️ 裁切模型加载失败: u"       ❌ 裁切模型预热失败:    置信度阈值皙?	   IOU阈值?u     🔥 预热检测模型 (JEjezaGMqiaoqigemofencengclass1class3class4class0class2class5   独立置信度参数   启用独立置信度   极耳置信度皙?   折痕置信度   月牙置信度   极耳内插置信度   极耳内嵌置信度   分层置信度r   r   r   r   r   r   rE   iour   r   u        ✅ 检测模型预热完成u%       ⚠️ 检测模型加载失败: u"       ❌ 检测模型预热失败:    u!     🔥 预热隔膜分类模型 ()rE   r   u&       ✅ 隔膜分类模型预热完成u+       ⚠️ 隔膜分类模型加载失败: u(       ❌ 隔膜分类模型预热失败: u   🔥 模型预热完成！u   ❌ 模型预热异常: )r   rr   r&   r_   rF   rg   r   randomrandintr    rd   	predictExr?   r%   r`   set_class_namesuse_independent_confglobal_confitemsset_class_confidencere   ra   load_from_pathrf   predict)rA   cut_model_paramsdetect_model_paramsgm_cls_model_params	cut_imgszcut_model_pathdummy_imager3   detect_imgszdetect_model_pathdetect_confidence
detect_iouusr_class_nameindependent_confindependent_conf_enabledindependent_conf_values
class_name
conf_valuegm_imgszgm_model_paths                       r4   rt   zEarFoldDetector._warm_up_models   sh   n	2./  $223MrR"&//"5"56VXZ"["&//"5"56PRT"U ~~"2"6"6~"FD 0 4 4^S II%5%9%9."%MN% ;I;a	{RVWX>>DD^UYUcUcd*,))*;*;AsYPY[\D]egemem*;*nK!%!4!4 $ 8 8T^^clv{ 8 | "5!"DE!$I$..JiJiIj"kl
   %8%<%<^%L7D#6#:#:>3#OL(;(?(?PR(S%(;(?(?@QSV(W%!4!8!8c!JJ( ;L><.X\]^,,GGHY[_[i[ij *.)-)-)3)/)2.N !--==nM 0C/F/FG^`b/c,7G7K7KLcej7k4E]D--B<MD--97*:*>*>?PRU*V*:*>*>?PRU*V*:*>*>?PRU*V0@0D0DE\^a0b,<,@,@AXZ],^/?/C/CDUWZ/[;" 7 ?V>[>[>]$:J
$($5$5$J$J:Wa$b ?^ +-))*;*;As\S_abDckmksks*;*tK!%!7!7 $ 1 1 ; ;$/+/>>(2*6,1 !< !" "8 ""DE!$I$J[J[JlJlIm"no
   %8%<%<^%LJ266~sKH$7$;$;NB$OM$ A(1XJVZ[\,,;;M4>>Z*,))*;*;AsXxYZD[ceckck*;*lK!%!7!7 $ 1 1 9 9+dnndl 9 m "8!"JK!$OPTPaPaPrPrOs"tu ./o "5!4
 ! D>qcBCCD` "8!7 ! D>qcBCCD "8!7
 ! JDQCHIIJ
  	2,QC011	2s   A=V  BT *S46T >V GT3 ++T&6T3 V +BU$ 	)U26U$ (V 4S>9T 	T#
TV T##V &T0+T3 3	U<U
V UV U!U$ $	V-V ;V  VV 	V)V$$V)r'   paramsc                    | j                   sddiS t        d       ||n| j                  }	 t        j                         }| j                  ||      }i }d|v rd|d<   |S |j                  dg       |d<   |j                  di       |d<   |j                  d	d
      |d	<   |j                  dd \  }}|j                  di       }	|	j                  dd      }
||
z  }||
z  }| j                  |j                  dg       ||      |d<   t        j                         }t        d||z
  dd       |S # t        $ rE}t        dt        |              ddl}|j                          ddt        |       icY d}~S d}~ww xY w)u   
        执行检测（仅翻折检测）
        按照run_all的输出格式设计，主要输出标注相关信息
           错误信息   检测器未初始化u    🔍 开始极耳翻折检测...N   异常结束   推理异常结束cbv1_text_itemsresult_info   结果NGr   rz   r}   r~   
draw_itemsdraw_items_original   检测耗时: .2f   秒u   ❌ 检测异常: r   u   检测异常: )ru   r   rr   timeperf_counter_run_detectionr&   r!   _scale_draw_items_to_originalr%   rv   	traceback	print_exc)rA   r'   r   detection_params
start_time
raw_resultr/   original_heightoriginal_widthmodel_paramsmodel_input_sizescale_xscale_yend_timer3   r   s                   r4   detectzEarFoldDetector.detectA  s   
  7  	01%+%76T__.	**,J ,,U4DEJ F +)=~& )37H"(MF$%$.NN="$EF=!)~~h=F8 /4kk"1o+O^+//0PRTUL+//D %'77G%(88G -1,N,N|R0'7-F() ((*HN8j#8"=SABM 	&s1vh/0! .Q 9 	s$   2D.  CD. .	E<7:E71E<7E<c           	      f   i }|s|S t        |      D ]  \  }}|j                         }|j                  d      dk(  rdd|v rdd|v r_t        |d   d   |z        t        |d   d   |z        d|d<   t        |d   d   |z        t        |d   d   |z        d|d<   n|j                  d      dk(  r1d	|v rt        |d	   d   |z        t        |d	   d   |z        d|d	<   n|j                  d      d
k(  rHd|v rg }|d   D ]4  }	|j	                  t        |	d   |z        t        |	d   |z        d       6 ||d<   nd|j                  d      dk(  rPd|v r,t        |d   d   |z        t        |d   d   |z        d|d<   d|v r||z   dz  }
t        |d   |
z        |d<   ||d| <    |S )u  
        将512x512图像的绘图项坐标还原到原始图像尺寸
        参考主程序detect_only的坐标还原逻辑
        
        Args:
            draw_items: 绘图项列表（512x512尺寸）
            scale_x: X方向缩放比例
            scale_y: Y方向缩放比例
            
        Returns:
            dict: 还原到原始图像尺寸的绘图项字典
        type	rectangletopLeftbottomRightr   r   r   r   textpositionpolygonpointscirclecenterradiusr   item_)	enumeratecopyr&   floatappend)rA   r   r   r   r   iitemscaled_itemscaled_pointsrH   	avg_scales              r4   r   z-EarFoldDetector._scale_draw_items_to_original  s.    !&& ,GAt))+K xx;.+0L #4	?3#7'#AB"4	?3#7'#AB.K	*
 #4#6s#;g#EF"4#6s#;g#EF2K.
 &!V+, #4
#3C#87#BC"4
#3C#87#BC/K
+
 &!Y.{*$&M!%h%,,!&uSzG';!<!&uSzG';!<.  "0
 -:K)&!X-{* #4>##6#@A"4>##6#@A-K) {*!(7!2a 7I,1$x.92L,MK)/:%s,a -d #"r;   c                 09   i }i |d<   i |d<   g |d   d<   g |d   d<   d|d<   |j                  di       }|j                  dd	      }|j                  d
d      }|j                  dd      }|j                  dd      }|j                  di       }	|	j                  dd      }
|j                  dd      }|j                  di       }|j                  di       }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  d d!      }|j                  d"d#      }|j                  d$d%      }|j                  d&d      }|j                  d'd(      }|j                  d)d*      }|j                  d+d      }|j                  d,d-      }|j                  d.d-      }|j                  d/d      }|j                  d0d(      }|j                  d1d      }|j                  d2d      }|j                  d3d4      } |j                  d5d6      }!|j                  d7d8      }"|j                  d9d      }#|j                  d:d	      }$|j                  d;d<      }%|j                  d=i       }&|&j                  dd	      }'|&j                  dd>      }(|j                  d?i       })|)j                  d@d      }*|)j                  dAd      }+|},|,j                  dBdC \  }-}.t        j                  |,||f      },t	        dD|. dE|- dF| dE|        t        j                         }/|/}0| j                  j                  || j                        }1|1sRt	        dG| j                  j                          |d   d   j                  dH| j                  j                          |S dIdJdKdLdMdNdO}2| j                  j                  |2       |
| j                  _        || j                  _        |
r|	j                  dPdQ      |	j                  dRdQ      |	j                  dSdQ      |	j                  dTdQ      |	j                  dUdQ      |	j                  dVdQ      dW}3|3j                         D ]!  \  }4}5| j                  j!                  |4|5       # | j"                  5  	 | j                  j%                  |,| j                  ||dX      }6	 dBdBdB       t        j                         }8|8|0z
  }9t	        d\|8|0z
  d]d^       | j                  }:|:j+                  6      };t        j                         }<t	        d_|<|8z
  d]d^       | j                  j-                  |;d`      \  }=}>|;D ]  }?|?da   |2v s|2|?da      |?da<    t        j                         }@t	        db|@|<z
  d]d^       d}At/        |;      dck7  rd}A|rr|d-k7  s|d-k7  rU|,j                  dBdC \  }-}.t1        |.|z        }Bt1        |-|z        }Ct	        dd|. dE|- dF|B dE|C        t	        de| df|        t        j                  |,|B|Cft        j2                  g      },|;D ]  }?|?j                  dhi       }D|Dst1        Ddi   |z        |Ddi<   t1        |Ddj   |z        |Ddj<   t1        |Ddk   |z        |Ddk<   t1        |Ddl   |z        |Ddl<   t1        |Ddm   |z        |Ddm<   t1        |Ddn   |z        |Ddn<   |Ddk   |Ddi   z
  |Ddo<   |Ddl   |Ddj   z
  |Ddp<   |Ddo   |Ddp   z  |?dq<    t	        drt/        |;       ds       nt	        dt| du| dv       t        j                         }Et	        dw|E@z
  d]d^       g }Fg }Gd}Hd}Id}Jd}Kd}Ld8}Md}N|;D ]e  }?|?da   dIk(  si }O|?dh   di   |OdE<   |?dh   dj   |Odx<   |?dh   do   |Odo<   |?dh   dp   |Odp<   t5        j6                  |,|O      }P|P|?dy<   Fj                  |O       g d}Qt/        F      dck(  r|rd}Q|;D ]  }?i }O|?dh   di   |OdE<   |?dh   dj   |Odx<   |?dh   do   |Odo<   |?dh   dp   |Odp<   t5        j6                  |,|O      }P|P|?dy<   d}R|?da   dKk(  rd}H|?da   dJk(  rd}I|?da   dNk(  rd}J|?da   dLk(  rd}K|?da   dMk(  rd}LQrt/        F      d8k(  rFd8   }Sdz }T|?da   dKk(  r( TOS      }U|U|k  rd|?d{<   d}Rt	        d|Ud}d~| d       |?da   dJk(  r( TOS      }U|U|k  rd|?d{<   d}Rt	        dUd}d~| d       |?da   dNk(  r( TOS      }U|U|k  rd|?d{<   d}Rt	        dUd}d~| d       |?da   dLk(  r1OdE   |Odo   dCz  z   }VSdE   }W|V|WkD  rd|?d{<   d}Rt	        dV dW d       |?da   dMk(  r1OdE   |Odo   dCz  z   }VSdE   }W|V|WkD  rd|?d{<   d}Rt	        dV dW d       |?da   dJk(  rd|?da<   |?da   dIk(  ri }XP|Xdy<   O|Xd<   |?da   |Xda<   |?d   |Xd<   |r|?da   dv rt/        F      dck(  rt	        |       Odp   |Odo   |d   z  kD  rXOdE   Fd8   dE   z
  |Fd8   do   |d   z  kD  r;Odp   Fd8   dp   z  |d   kD  r'd|?d{<   d}Nt	        dOdp   |Odo   z   d|?d    d       [Rs_Gj                  X       rRsvGj                  X       t	        d|?d    d|?da    d        t        j                         }Yt	        d|YEz
  d]d^       d	}ZdB}Sd}[t/        F      d8k  rAt/        G      d8kD  r|d   d   j                  d       dc}Mn|d   d   j                  d       dc}Mt/        F      dckD  r|d   d   j                  d       Zdz   }Zdc}Md}\d}]t/        F      dck(  ruFd8   }S|Sdo   ||z  k  r|d   d   j                  d       dc}MZdz   }ZSdp   ||z  kD  r|d   d   j                  d       dc}MZdz   }Zt/        G      d8kD  r	 GD ]	  }^|^d   }_|^dy   }`| j                  j9                  S|_      }a|a|_d<   d8|^d<   |_dE   |SdE   dCz
  k  r6ad   d   Sdo   d*z  k  sTdc^d<   dc}M|d   d   j                  d       Zdz   }Zx^da   dKk(  rt;        t=        _dE   SdE   z
        t?        |Sdp         z  ]      }]Md8k(  rdC}M|r5_do   Sdo   z  |kD  r'_dp   |_do   z  |kD  rdc}M|d   d   j                  d       |d   d   j                  d       ^da   dNk(  rt;        t=        _dE   SdE   z
  |Sdo   z
        t?        |Sdo         z  \      }\t=        |_dE   |SdE   z
  |Sdo   z
        }b|b|Sdo   |z  kD  r#t/        G      dck(  rMd8k(  sMdCk(  rd}Mndc}MZdz   }ZnMd8k(  sMdCk(  rd}M|d   d   j                  d       _dE   |_do   dCz  z   }c|_dx   |_dp   dCz  z   }dSdx   |Sdp   dCz  z   }e|_dE   |_dx   f|_dE   |_do   z   |_dx   f|_dE   |_do   z   |_dx   |_dp   z   f|_dE   |_dx   |_dp   z   fg}f|d|ek  rfd8   }g|fdC   }h|fdc   }id}jnfdc   }g|fd   }h|fdC   }id}jtA        igh      }kcdfj|i|k|g|hgd^d<   d}l|kd8   SdE   z
  |Sdo   |z  k  r dc}MZdz   }Z|d   d   j                  d       d}l_dE   SdE   z
  |Sdo   |z  k  rFlsDdc}MZdz   }Z|d   d   j                  d       t	        d| d_dE   SdE   z
   d|Sdo   |z   d       d}llrMdck7  rd}M|d   d   j                  d        \d-k  r]dQk  rdc}MZdz   }Zt        j                         }mt	        d|mYz
  d]d^       d}n| jB                  jE                  |'      }o|*rMdck7  rMd8k7  rd}n|+rd}nNrd}ni }pdB}qSSjG                         }q|qdE   t1        |      z
  |qdE<   |qdx   t1        |qdp   d*z        z
  |qdx<   |qdp   dCz  |qdp<   t1        |      |qdo<   |qdE   d8k  rqdo   t1        |qdE         z   |qdo<   d8|qdE<   qjG                         }r|rdo   dCz  |rdo<   t5        jH                  |,|q      }st        j                  |sd      }sdB}t|rtqq	 t	        dSdBu d|         |S%| d8kD  rSdE   |Sdx   |Sdo   |Sdp   f\  }u}v}w}xt1        |w| z        }yt1        |x| z        }z|u|w|yz
  dCz  z   }{|v|x|zz
  dCz  z   }|g }}tK        d      D ]  }~tK        d      D ]  }|z~dcz   z  dz  z   }{y|dcz   z  dz  z   }||,j                  d8   k  s2|,j                  dc   k  sEt/        |,j                        dk(  r!}j                  t1        |,d8f                ~}j                  t1        |,f                  g }sj                  dBdC \  }}tK        d      D ]  }~tK        d      D ]|  }~dcz   z  dz  }|dcz   z  dz  }||k  sk  s%t/        sj                        dk(  r!j                  t1        sd8f                ^j                  t1        sf                ~  t/        }      dk\  rS}jM                          t/        |}      dCkD  r}dcd n}}tO        |      t/        |      z  }|t/        |      dCz     }}d   }nd8x}x}}t/              dk\  rSjM                          t/        |      dCkD  rdcd n}tO        |      t/        |      z  }|t/        |      dCz     }d   }nd8x}x}}t=        z
        }t=        z
        }||||||t=        ||z
        d	}tt	        d|dd|dd|d       |"|cxk  xr |!k  nc }|"cxk  xr |!k  nc }|r0rs,Mdck7  r\dc}MZdz   }Z|d   d   j                  dddd       n5n4t	        dSdBu d|         |St	        dū       | d8k  rt	        d|  dǝ       nt	        d|        SnrorddddddМ}| jB                  j                  |       | jB                  jQ                  sddѫ      }| jB                  jS                  |      }t	        d|        |rTda   pd<   |d   |pd<   |da   dk(  sda   dk(  sda   dk(  rdpd<   n&dpd<   dc}MZdz   }Zn| jB                  j                  pd<   os| jB                  j                  pd<   t        j                         }|mz
  pd<   t	        d||mz
  d]d^       d|d<   Md8k(  rd|d<   nZMdck(  rd|d<   nOMdCk(  rd|d<   d|d<   n?Mdk(  rd|d<   d|d<   n/Mdk(  rd|d<   d|d<   nMdk(  rd|d<   d|d<   nMdk(  r
d|d<   d|d<   g }g }|;D ]&  }?d{|?v r	|?j                  dhi       }D|DsDdi   |Ddj   }}|Ddk   |Ddl   }}|?j                  dad      }4|?j                  dd8      }|4 d|d}}j                  |       d8d6d8dd6d8d8dd6d6d8dd6d8d6dd8d6d6dd6dd8ddW}|j                  |4dddd      }dt?        |      t?        |      dt?        |      t?        |      dd8dC|dd}j                  |       |4 d|d}dv}d|dd|t?        |      t?        |dz
        ddd}|j                  |       ) GD ]  }^d{|^v r	d^v s^d   }|d   }|d   }|d   }|\  }g}hdddcdCd6d8d8dt?        |gd8         t?        |gdc         dt?        |hd8         t?        |hdc         dgdd}j                  |       ddd8dCd8d6d8dt?        |d8         t?        |dc         dt?        |d8         t?        |dc         dgdd}|j                  |       |D ]Y  }ddd8dcd6d6d8dt?        d8         t?        |dc         dt?        |d8         t?        |dc         dgdd}j                  |       [ dt?        d8         t?        |dc         ddd8dCd8d8d6ddd}j                  |       dt?        d8         t?        |dc         ddd8dCd8d6d8ddd}|j                  |       D ]<  }dt?        |d8         t?        |dc         ddd8dcd6d8d8ddd}j                  |       >  St1        SdE   |Sdo   |z  z         }ddd8dd6d8d8dt?        |      t?        |Sdx         dt?        |      t?        |Sdx   |Sdp   z         dgdd}j                  |       t1        |SdE   |Sdo   |z  z         }dt?        |SdE         t?        |Sdx         dt?        |      t?        |Sdx   |Sdp   z         ddcdCd6d8d8ddd}|j                  |       dpv rdpd    d|pd    d|pd   d]d}|pd   dk(  rd8d6d8dnd6d8d8d}ddd|ddddd}j                  |       dtU               v rqpd   dk(  rd8d6d8dnd6d8d8d}dt?        qdE         t?        |qdx         dt?        |qdE   |qdo   z         t?        |qdx   |qdp   z         dd8dC|dd}j                  |       d|9d]dd |d    d| jV                  dg}tY        |      D ]T  \  }~}Md8k(  r~dck(  rd8d6d8dnd8d6d8d}|d   dk7  r~dck(  rd6d8d8d}ddddd~dz  z   ddd}j                  |       V t2t	        dtd   dd|td   d       d|td   dd	|td
   d}d|td   dd|td
   d}d|ddd6d6d8dddddd}j                  |       j                  |       d|td   dd	|td   d}d|td   dd|td   d}d|ddd6d6d8dddddd}|j                  |       |j                  |       d|td   dd|td   d}d|td   dd|td   d}d|ddd8d6d6dddddd}|j                  |       |j                  |       nt	        d       t	        d       dZddd8d6d6dddddd}j                  |       j                  |Z       ||d<   ||d<   |S # t&        $ rT}7t	        dYt)        |7              |d   d   j                  dZt)        |7              d|d[<   |cY dB}7~7cdBdBdB       S dB}7~7ww xY w# 1 sw Y   WxY w# t&        $ rG}7t	        dt)        |7              |d   d   j                  dt)        |7              dB}tY dB}7~7		dB}7~7ww xY w(  uR   
        核心检测逻辑 - 基于原始run_delect方法的完整实现
        result_imager      算法错误   算法消息r   r   rz   r|   r   r   r   r   r   r}   r~   r   r   F   横向纹理附加检测T   横向纹理附加检测参数   极耳翻折用户参数*   翻折保护距离（极耳高度比例）0   翻折起点保护距离（极耳高度比例）{Gz?0   翻折起点扩展距离（极耳高度比例）           极耳高度（像素）      极耳高度保护阈值333333?   极耳宽度（像素）     极耳宽度保护阈值      ?   分层保护阈值皙?   月牙宽高NG   月牙宽度皙?   月牙高度      ?   启用自动缩放功能   检测后图片高度缩放      ?   检测后图片宽度缩放   启用相对位置筛选器   重叠度阈值   启用灰度检测   灰度范围NG   灰度内缩ffffff?   灰度差值MAXr      灰度差值MINr      算法存图   算法存图路径"   算法存图最大占用硬盘(MB)   r{   r      隔膜用户参数   启用隔膜分析   隔膜全检Nr   u   🔧 缩放图像: r   z ->    模型加载失败: u   翻折模型加载失败: r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   u   ❌ 模型推理失败: u   翻折模型推理失败: r   u   翻折模型推理时间: .4f    秒u   提取检测列表时间: g333333?   类型字符u   合并检测列表时间: r	   u   🔧 自动缩放图像: u      宽度缩放比例: u   , 高度缩放比例: )interpolation	   AOI位置rM   rN   r-   r.   center_xcenter_yr   r      面积u5   ✅ 图像和检测结果缩放完成，共缩放了 u    个检测框u*   🔧 未启用图像缩放 (宽度比例: u   , 高度比例: )u   自动缩放时间: r   r'   c                    t        | d   |d         }t        | d   |d         }t        | d   | d   z   |d   |d   z         }t        | d   | d   z   |d   |d   z         }||k\  s||k\  ry||z
  ||z
  z  }| d   | d   z  }|dk(  ry||z  S )u-   计算item_aoi被container_aoi包含的比例r   r   r   r   r   r   )r#   r$   )item_aoicontainer_aoirM   rN   r-   r.   intersection_area	item_areas           r4   calculate_containment_ratiozCEarFoldDetector._run_detection.<locals>.calculate_containment_ratio  s     Xc]M#,>?BXc]M#,>?BXc]Xg->>c@RUbcjUk@klBXc]Xh-??sASVcdlVmAmnB Rx28" *,bR"W(=% ( 1HX4F FI !A~",y88r;   u	   不显示u    月牙检测项包含度不足: .3fz < u   ，设置为不显示u    折痕检测项包含度不足: u    分层检测项包含度不足: u&   内插未超出左边界: item_center=z > je_left=u&   内嵌未超出左边界: item_center=zhehengr(      索引)r3     横纹最低长宽比   横纹最低风险高度   横纹最低风险宽度u5   🔍 检测到可能的横向纹理误检，长宽比u   ，AOI索引 u    被标记为不显示u
   AOI索引 u
   ，类型 u4    被添加到其他AOI列表，包含度检查通过u   检测框处理时间: u    ❌ 未检测到极耳,有翻折u%   ❌ 未检测到极耳及其他翻折u;   ❌ 检测到多个极耳,理论上拆图只拆单个极耳zduojier;
   u1   ❌ 极耳高度过低，判定为首极耳翻折zgaoduguodi;u(   ❌ 极耳宽度过大，判定为错位zcuowei;u   与极耳关系posu   位置关系u   水平距离u   ❌ 检测到极耳翻折zneicha;u   ❌ 检测到月牙宽高异常u    检测到月牙   z
dafenceng;u    检测到分层u7   上半部分，沿左上-右下对角线镜像右上角r   u7   下半部分，沿右上-左下对角线镜像右下角)u   中心位置u   位置描述   原始角点	   镜像点   对角线端点u   镜像分析z	dafanzhe;zfanzheguoshen;u!     保护距离判定:判定阈值u    水平距离 u    > 保护距离 u&   ，且未被之前的翻折判定为NG   u       检测到小翻折zdafencengC2;u   翻折识别时间: )r   r   u&   🔍 灰度检测条件检查: je_aoi=z, gray_inward_ratio=   )	je_mean	je_medianje_maxgm_mean	gm_mediangm_maxmax_diff	mean_diffmedian_diffu*   ✅ 灰度检测数据已创建: JE均值=z.1fu   , GM均值=u	   , 差值=zhuiduNG;u(   ❌ 灰度差值异常: 最高值差值=r   u   , 均值差值=u"   ⚠️ 跳过灰度检测: je_aoi=u2      - je_aoi为空，检查极耳检测是否成功z   - gray_inward_ratio=u   ，需要>0u   ❌ 灰度检测异常: u   灰度检测异常: u1   ℹ️ 灰度检测已禁用: gray_detect_enable=OKfanguangfanguang_plusedazhouneicha)r   r	   r   r   r?  )top_kuse_yolo_preprocessu   隔膜分类Top1结果: u   类别u   分类置信度	   置信度zgemoNG;u   模型错误u   推理耗时u   隔膜识别时间: u   月牙u   异常u	   无极耳u	   多极耳u	   小翻折u   分层或月牙unknown   综合置信度:)rgrR         r   r   )r   r   r   	lineStylepenWidthcolorshow(r   Arial   )r   r   
fontFamilyfontSizer[  r   r\  r<  r;  r=  r   )r   isClosedrY  rZ  r[  r   r\  r   g      @)r   r   r   rY  rZ  r[  r\  g      @zGM: ,zs)   g      $@g      Y@gm_aoizModel: szResult: zcount: dg      9@u(   🔍 准备显示灰度检测数据: JE=rA  z, GM=rD  u   极耳: 平均值=u    中值=rB  z	JE: Mean=z Median=g     @_@u   隔膜: 平均值=rE  z	GM: Mean=g     b@u   极耳，隔膜: 平均值差=rH  u    中值差=rI  zDiff: Mean Diff=z Median Diff=g     e@u+   ⚠️ 灰度检测数据为空，未显示u   准备显示结果数据g      i@r   r   )-r&   r!   cv2resizer   r   r   r`   rF   rg   r?   r   r   r   r   r   r   re   r   r%   rv   extract_detection_list$merge_overlapping_detections_inplacelenr"   INTER_LINEARr   r5   calculate_aoi_relationshipsr$   absr   rV   ra   r   r   get_cv_img_fronm_aoi_exrangesortsumr   get_top1_resultlocalsrh   r   )rA   r'   r   r/   r   
model_pathmodel_confidence_thresholdmodel_iou_thresholdr   r   r   horizontal_texture_checkhorizontal_texture_param
usr_paramsfanzhe_protect_ratiofanzhe_protect_startfanzhe_protect_expand	JE_heightJE_height_ratioJE_widthJE_width_ratioJE_fenceng_thresholdyueya_wh_ng_enableyueya_width_ngyueya_height_ngenable_auto_scalingdetect_img_height_scaledetect_img_width_scaleenable_pos_filterpos_filter_thresholdgray_detect_enablegray_ng_enablegray_inward_ratiogray_diff_maxgray_diff_minsave_image_by_modelsave_image_pathsave_image_max_sizer   gm_cls_model_pathgm_cls_model_imgszgm_cls_usr_paramsenable_gm_clsenable_gm_cls_all	src_imager   r   r   model_startload_resultr   r   r   r   model_resultsr3   	model_end
model_costcur_delect_modeldeleted_listextract_detection_list_endmerge_success	merge_msgdetect_item	merge_endhas_other_item	new_width
new_heightaoi_posauto_bg_endje_aoi_listother_aoi_list	has_yueya
has_fanzhehas_fenceng
has_neichahas_neiqianfanzhe_resulthas_horizontal_texturetemp_aoiimage0use_pos_filterneed_appendje_aoir1  containmentitem_centerje_left	temp_itemaoi_seg_endng_infosee_gm
fenceng_up
yueya_down
other_item	other_aoiother_imageother_aoi_resultfenceng_posother_center_xother_center_yje_center_yother_cornersdiagonal_p1diagonal_p2target_pointposition_desccur_pntisNGcheck_je_end
use_gm_cnncls_load_success	gm_resultre  jegm_aoigm_image_clsgray_detect_dataje_xje_yje_wje_hinward_winward_hinward_start_xinward_start_y	je_pointsr   jr   r   	gm_pointsgm_hgm_wje_filteredrA  rB  rC  gm_filteredrD  rE  rF  rG  rH  max_diff_in_rangemean_diff_in_rangecustom_class_namesresultstop1_result	gm_je_endr   r   rM   rN   r-   r.   
confidenceconf_str	color_mapr[  	rect_item
label_text	text_itemmirror_analysismirror_pointoriginal_pointdiagonal_pointsdiagonal_linemirror_line
diag_pointconnection_lineoriginal_circlemirror_circlediag_circle	protect_xprotect_linestart_rect_rightprotect_rectgm_textgm_text_colorgm_text_itemgm_rect_colorgm_rect_itemstatus_textsr   
text_colortemp_strtemp_str_enje_text_itemdiff_text_itemng_text_items                                                                                                                                                                                                 r4   r   zEarFoldDetector._run_detection  s'   
 !#~ "}02}n-02}n-x zz"BBG!%%nb9
%1%5%56G%M"*..{C@  5'++,CRH#3#7#78OQV#W #/#3#34NPT#U #/#3#34TVX#Y  ZZ :B?
)~~.Z\_`)~~.`bfg */acf gNN#=sC	$..)CSI>>"<cB#(BCH)~~.BCH'^^,<eD#<$..=(nn-GO",..1NPS"T!+0Ms!S&NN+H$O)~~.?E'^^,@$G#(8%@&NN>3?"'8#>"'8!<(nn^TB$..)=rB(nn-QSWX %jj)CRH/33NBG044^SI #JJ';R@)--.BDI-11.%H	*3//"1*='JJy5%.9	#N#31_4ET%PQRWQXYZ&&(
  ''BB:t~~^():):)K)K(LMN=!.188;UVZVgVgVxVxUy9z{M 
 	)).9 2J.(B% $&**+<cB&**+<cB&**+<cB,001H#N(,,-DcJ+//0A3G'# +B*G*G*I&
J!!66z:N +J ## $ 1 1 ; ;>>+! !< ! $ %%'	,
*9{+B3*GtLM,, (>>}M%)%6%6%8"*+E	+QRU*VVZ[\ $(#4#4#Y#YZfhk#l y'K>*n<.<[=X.YN+ ( %%'	*97Q+QRU*VVZ[\ |!!N %,0G30N2;//"12E/  1G GH	 3J!JK
1.1A?BSSWXaWbbcdncopq/0F/GG]^u]vwx  JJy9j2IY\YiYij	 $0K)ook2>G(+GDM<R,R(S(+GDM<S,S(T(+GDM<R,R(S(+GDM<S,S(T.1'*2EH^2^._
+.1'*2EH_2_.`
+ ,34=74=+H(,3DMGDM,I) 180@78CT0TH-! $0$ McR^N_M``mnoBCYBZZj  lC  kD  DE  F  G'')$[9%<S$AFG
 	

!&'K>*d2 +K 8 > +K 8 >$/$<W$E!%0%=h%G"33IxH'-G$""8, ( {q %6!N'KH'4T:HSM'4T:HSM +K 8 AHW!,[!9(!CHX//	8DF#)K K>*d2 	>*d2!
>*i7">*j8!
>*f4"{#q( %Q90 ~.$6"=h"OK"%9937K0&+ @S@QQTUiTjj  A  B~.$6"=h"OK"%9937K0&+ @S@QQTUiTjj  A  B~.);"=h"OK"%9937K0&+ @S@QQTUiTjj  A  B~.*<"*3-(72Ca2G"GK$SkG"W,37K0&+ F{mS^_f^gg|}~ ~.&8"*3-(72Ca2G"GK$SkG"W,37K0&+ F{mS^_f^gg|}~ >*d2.7N+>*d2	%+	'"#+	% ,7,G	.)&1(&;	(#+N0K{0Z_bcn_ost_t23 *Xg->AYZqAr-rr$SMKN3,??+a.QXBY\t  vP  ]Q  CQ  Q$X.Q1IILde  MA  A37K015. UV^_gVhkst{k|V|U}  ~K  LW  X`  La  Kb  bx  y  z&*11)<"&--i8
;x+@*AKXfLgKh  i]  ^  _y (| '')'k(A#'FdKL  {q >"Q&}%n5<<=_` !}%n5<<=de !{a=!.1889vw
*GM

{q  ^Fg_!<<}%n5<<=pq !!M1h(^";;}%n5<<=gh !!I->"Q&,
&u-	(1#'#4#4#P#PQWYb#c /?	+,$%
5!S>F3K!O3'7G6RY?]`K``,-
5)()}-n=DDE`a")I"5 ".1T9%(Ys^fSk-I)KeTZ[cTdNe)egq%r
(A-,-M-(1F7OCnTYbckYlox  zA  pB  ZB  ET  ZT01 &} 5n E L LMn o}-n=DDEWX#N3y@%(Ys^fSk-IFSZO-[)\_deklset_u)u  xB  &C
&))C.6#;*FPW*X&Y&;O)OO">2a7#0A#5!9K45M01*1L*@,1]a5G01}-n=DDEWX *33)G:LPQ:Q)Q)23)H:MQR:R)R '-SkF84D4I&I 's^Ys^<&s^i.@@)C.Q&s^i.@@)C.S\]eSfBfg&s^Ys^i>Q-QR	) *K7*7*:K*7*:K+8+;L,eM +8*:K*7*:K+8+;L,eM #;<Va"b .<^,L,9,8)00;[/I6
>2  %"1:s3vgI]7]],-M&-&;G"=1.AHHIde#'D %S>F3K76'?Ma;aajn,-M&-0@&@G"=1.AHHIde!$EFZE[[ijstwjx  |B  CF  |G  kG  jH  HX  Y_  `g  Yh  k  Y  X@  @f  #g  h#'D#,101"=1.AHHIabU -X 
S 0M.G((*$\K%?$DDIJ
,,;;<MN!mq&8!
J!J	[[]F +I6F3K +F8,<s,B(CCF3K%h/!3F8!)nF7Oc{Q"(/Cs4D"Dws{{}H ( 1A 5HW 88FKL::lJ?L   &"4g(>vT?Q>RRfgxfyz{%*;a*?-3C[&+vgX^_gXh-h*D$d  #4*;#;<H"4*;#;<H%)TH_,B%BN%)TH_,B%BN !#I"1X!&qA .QU1Cq1H HA .QU1Cq1H HA 9??1#55!iooa>P:P#&y#71#<$-$4$4S1a79K5L$M$-$4$4S1a45I$J "* & !#I!-!3!3BQ!7JD$"1X!&qA $A! 3A $A! 3A 4xAH#&|'9'9#:a#?$-$4$4SaAg9N5O$P$-$4$4Sad9K5L$M "* & 9~*!(9<Y!9Ki"oQZ"%k"2S5E"E$/K0@!0C$D	!*27888)f 9~*!(9<Y!9Ki"oQZ"%k"2S5E"E$/K0@!0C$D	!*27888)f  #6F?3H #Gg$5 6I $+%."(#*%."($,%.'*9y+@'A
($ FwsmS^_fgj^kktu~  @C  uD  E  F )6(R](R%)6))T})T&
 &/@EW(A-,-M&-
&:G"=1.AHHKst|  ~A  tB  BQ  R[  \_  Q`  Ja  b >vT?Q>RRfgxfyz{~ RT(A- 78I7J+VW EFXEYZ[ *!'&" !!112DE++33L^b3c #//??H0>?*5n*EIh'-89J-KIk*">2d:{>?Z^h?hlw  yG  mH  L\  m\/3	(+/3	(+()")I"5,0,=,=,N,N	.)#,0,=,=,N,N	.)%%'	$-$<	.!$Y%=c$B$GH  xA#F8a#F8a#F8'F8a#F8*F8a#F8*F8a#F8*F8a#F80F8< 
 (Kk)!ook26G B B(__^YG
(__->B
(\:c*:;&&x0 !"!4 #!!4 ##A6&) <"##C8%(s;	 "j#C2PQ (%*2YU2Y?).rr#C!" !" 	 !!), !+|1Z,<A>
"&") ""&+BieBFm D 	 !!),[ (` )Jj(+",^"<  /{;!0!@"12C"D+:([ & %!" !#&QQ7#KN3%A:OP#KN3%A:OP !! !!-0 & %!" !#$3Q7#N1$56U>RSCT=UV#LO45a;QR ! !!+. #2J )$)%&$%'*1!="'Q"8u\RS_?UV"'
1"6U:a==QR# !%'O %%o6 #2$ %$).*;$<5XYIZC[\!!" !#$137 # !!/2 %$),q/$:|TUAWX!!" !#$3Q7 ! !!-0 #2J ((-jm(<5TUCW"X"%%&$%'*!; $#K %%k2 #2i )B F3K&/<P*PPQI "!"3	*vc{1CD	*vc{VHEU7U1VW L l+  #6#;CW1W#WX#!&vc{!3%s:LM%*+;%<5PSW]^fWgIgChi"3L l+y Yx019X3F2GqSaIbcfHggijG ;DH:MQU:U!#A6adklst[uM%&"&U3L l+ 68#>G>QUY>Yac :ehopwx_y'%*6#;%7eF3K>PQ).vc{VG_/L)MTYZ`adZehnowhxZxTy#z!" !*   !!,/ j%Q'vh'()dnnQ'(
 !.GAt7D7IaSTfqs3`ahkrsZtJh4'AF#&QQ7
 %#"&TAH_=I i( /" '<=Mi=XY\<]]bcst}c~  @C  cD  E  F ,,<Y,G+LHUefqUrsvTwxH%&6y&A#%FhO_`kOlmpNqrK#%"15"&U3L l+""8, ,,<Y,G+LHUefqUrsvTwxH%&6y&A#%FhO_`kOlmpNqrK#%"15"&U3L l+""8, 88H8UVY7ZZefv  xE  gF  GJ  fK  LH,-=k-J3,O}]mn{]|  ~A  ]B  CK#% s5"&U3N n-""8,
 ?A 	(*!3S1"/
 	,'w'  *|$3 ! K  0Q9:}%n5<<?YZ]^_Z`Ya=bc)-~& $# $#p  (0Q9:}%n5<<?STWXYTZS[=\]#' 	(s   6Ap88*Ao@	B1Aq B;Aq CB'Aq E6Aq E<G<Aq o	Ap5o!A Ap0p!Ap5p"Ap8p0Ap5p5Ap8p8Aqq	Arq<ArrArc                 
    ddiS )u<   
        获取检测器可用的检测函数列表
        r   u   翻折检测（仅检测）r:   r@   s    r4   get_available_functionsz'EarFoldDetector.get_available_functions  s    
 3
 	
r;   function_namec                 L    |dk(  r| j                  ||      S t        d|       )u-   
        调用指定的检测函数
        r   u   未知的函数名称: )r   
ValueError)rA   r  r'   r   s       r4   call_functionzEarFoldDetector.call_function  s0     H$;;uf--6}oFGGr;   c                    | j                   sddiS ||n| j                  }	 t        j                         }i }i }i }| j	                  ||      }d|v r|d   |d<   d|v r|d   |d<   d|v r|d   |d<   d|v r|d   |d<   d|v rt        d	       d
|d<   |S g |d<   d|d   v rL|d   d   }		 | j                  |	|      }d|v r!|d   D ]  }
|d   j                  d|
z           d|v rd
|d<   |S 	 d|d   v rL|d   d   }	 | j                  ||      }d|v r!|d   D ]  }
|d   j                  d|
z           d|v rd
|d<   |S 	 ||d<   ||d<   | j                  |||      |d<   |r6|j                  dd       |j                  dd       |j                  dd       |r6|j                  dd       |j                  dd       |j                  dd       d|v r|j                  dd       t        j                         }t        d||z
  dd       |S # t        $ r4}t        dt        |              dt        |       |d<   |cY d}~S d}~ww xY w# t        $ r4}t        dt        |              dt        |       |d<   |cY d}~S d}~ww xY w# t        $ r1}t        dt        |              ddt        |       icY d}~S d}~ww xY w)uo   
        完整检测流程：极耳裁切 + 翻折检测
        从主程序迁移的 run_all 函数
        r   r   N   上极耳裁切框   下极耳裁切框   上极耳AOI   下极耳AOIr   u+   ❌ 检测异常结束，跳过后续步骤r   r   up_jr_imager   u
   上极耳:u   ❌ 上极耳检测失败: u   上极耳检测失败: down_jr_imageu
   下极耳:u   ❌ 下极耳检测失败: u   下极耳检测失败: u   上极耳结果u   下极耳结果r   r   r   r   r   u   ❌ 完整检测异常: u   完整检测异常: )ru   rr   r   r   _run_cutr   r   r   r%   rv   _restore_draw_items_to_originalpop)rA   r'   r   r   r   r/   	result_upresult_down
result_allup_imager   r3   
down_imager   s                 r4   run_allzEarFoldDetector.run_all  s   
  7 
 &,%76T__X	**,JFIK u.>?J#z1/9:N/O+,#z1/9:N/O+,+)3N)C~&+)3N)C~&+CD)=~&(*F$% 
> ::%n5mD" $ 3 3H>N OI(I5$-.?$@D"#45<<\D=PQ %A &21E~.% 3 *^"<<'7H
""&"5"5jBR"SK(K7$/0A$BD"#45<<\D=PQ %C &41E~.% 5 )2F$%(3F$% -1,P,PQZ\gis,tF() lD13T:nd3d3 5t<5 '

>40((*HN8j#8"=SABM[ ! "7Ax@A/Fs1vh-OF>*!M"" ! "7Ax@A/Fs1vh-OF>*!M"<  	,SVH56"6s1vh ? 	s   A1J J )AH +J <AI >CJ 	I)I IJ IJ 	J)J JJ JJ 	K&K=KKc           	         ddl }||kD  rt        d| d       yt        |t              r|j	                         D ]  \  }}|r| d| n|}t        ||j
                        rt        d| d|j                   d       Dt        |t        t        f      r| j                  ||||d	z          rt        d
| dt        |      j                           yt        |t              rt        |      D ]  \  }	}
|r| d|	 dnd|	 d}t        |
|j
                        rt        d| d|
j                   d       It        |
t        t        f      r| j                  |
|||d	z          wt        d
| dt        |
      j                           yt        ||j
                        rt        d| d|j                   d       yt        d
| dt        |      j                          y)uA   递归打印字典中每个值的数据类型，查找numpy数组r   Nz  u   : <递归深度超限>.u     ❌ z: numpy.ndarray (shape=u   ) <-- 发现numpy数组!r	   u     ✅ z: [])numpyr   
isinstancedictr   ndarrayr!   list_debug_print_dict_typesr   r6   r   )rA   datarD   	max_depthcurrent_depthr   keyvaluecurrent_pathr   r   s              r4   r-  z'EarFoldDetector._debug_print_dict_types]  s   9$Btf234dD!"jjl
U26$qCeRZZ0F<.0G}Tlmnd|400iQ^abQbcF<.4;3G3G2HIJ + d#$T?415$q1~Qqc8dBJJ/F<.0G

|SklmtTl300|YP]`aPabF<.4:3F3F2GHI + $

+tf$;DJJ<G_`atfBtDz':':&;<=r;   c                    i }i |d<   i |d<   g |d   d<   g |d   d<   d|d<   |j                  di       }|j                  dd	      }|j                  d
d      }|j                  dd      }|j                  dd      }|j                  dd      }	|j                  di       }
|
j                  dd      }|
j                  dd      }|
j                  dd      }|
j                  dd      }|
j                  dd      }|
j                  dd      }|
j                  dd      }|
j                  dd      }t        j                         }|}|j                  dd  \  }}t	        j
                  |||f      }t        j                         }t        d!||z
  d"d#       | j                  j                  || j                        }|sRt        d$| j                  j                          |d   d   j                  d%| j                  j                          |S t        j                         }t        d&||z
  d"d#       d'| j                  _        || j                  _        d(d)i}| j                  j                  |       | j                  5  	 | j                  j!                  || j                  ||d'*      }	 ddd       t        j                         }t        d-||z
  d"d#       | j                  j%                        }t        j                         } t        d.| |z
  d"d#       | j                  j'                  |d/      \  }!}"t        j                         }#t        d0|#| z
  d"d#       |D ]R  }$||z  }%||z  }&t)        |$d1   d2   |%z        }'t)        |$d1   d3   |&z        }(t)        |$d1   d4   |%z        })t)        |$d1   d5   |&z        }*|'|)d z  z   }+|(|*d z  z   },|,|d z  k  }-|-r|}.|}/n|}.|}/|+t)        |/d6|z   z  d z        z
  }0|,t)        |.d6|z   z  d z        z
  }1t)        |/d6|z   z        }2t)        |.d6|z   z        }3|0|/z
  }0|2|/z   }2|0d7k  s|1d7k  s|0|2z   |kD  s	|1|3z   |kD  st        d8|$j                  d9d:              t        d;|$d<   d=       t        d>|0 d?|1 d@|2 dA|3        t        dB| dA|        dC|$d<<   U t+        |dD dE      dd  }g }4|D ]u  }$|$j-                         }5i }6||z  }%||z  }&t)        |$d1   d2   |%z        |6dF<   t)        |$d1   d3   |&z        |6dG<   t)        |$d1   d4   |%z        |6d4<   t)        |$d1   d5   |&z        |6d5<   |6|5dH<   t)        |$d1   d2   |%z        |5d1   d2<   t)        |$d1   d3   |&z        |5d1   d3<   t)        |$d1   dI   |%z        |5d1   dI<   t)        |$d1   dJ   |&z        |5d1   dJ<   t)        |$d1   dK   |%z        |5d1   dK<   t)        |$d1   dL   |&z        |5d1   dL<   t)        |$d1   d4   |%z        |5d1   d4<   t)        |$d1   d5   |&z        |5d1   d5<   |5d1   d4   |5d1   d5   z  |5dM<   |4j                  |5       x t        j                         }7t        dN|7|#z
  d"d#       t/        |4      d6k(  r|4d7   }8|8d1   dL   }9|9|d z  k  }-|8j-                         }:|8d1   j-                         |:d1<   |-r?t        dO|        |:d1   dLxx   |z  cc<   |:d1   d3xx   |z  cc<   |:d1   dJxx   |z  cc<   n>t        dP|        |:d1   dLxx   |z  cc<   |:d1   d3xx   |z  cc<   |:d1   dJxx   |z  cc<   |:d1   d4   |:d1   d5   z  |:dM<   d6|:dQ<   |4j                  |:       t        dRt/        |4       dS       nLt/        |4      d k7  r>t        dTt/        |4       dU       |d   d   j                  dVt/        |4       dU       |S d};d}<t/        |4      d k(  r$|4d7   }=|4d6   }>|=d1   dL   |>d1   dL   k  r|=};|>}<n|>};|=}<|;d1   j-                         |dW<   |<d1   j-                         |dX<   i |;dY<   i |<dY<   |;d1   d2   |;d1   d4   d z  z   |;dK<   |;d1   d3   |;d1   d5   d z  z   |;dL<   |<d1   d2   |<d1   d4   d z  z   |<dK<   |<d1   d3   |<d1   d5   d z  z   |<dL<   |;dK   t)        |d6|z   z  d z        z
  |;dY   dF<   |;dL   t)        |d6|z   z  d z        z
  |;dY   dG<   t)        |d6|z   z        |;dY   d4<   t)        |d6|z   z        |;dY   d5<   |<dK   t)        |d6|z   z  d z        z
  |<dY   dF<   |<dL   t)        |d6|z   z  d z        z
  |<dY   dG<   t)        |d6|z   z        |<dY   d4<   t)        |d6|z   z        |<dY   d5<   t)        |;dY   dF   ||z  z
        |;dY   dF<   t)        |;dY   d4   ||z  z         |;dY   d4<   t)        |<dY   dF   ||z  z
        |<dY   dF<   t)        |<dY   d4   ||z  z         |<dY   d4<   |;dY   j-                         |dZ<   |<dY   j-                         |d[<   t        d\t1        |dZ         z          t        d]t1        |d[         z          t3        j4                  ||;dY         }?t3        j4                  ||<dY         }@t	        j
                  |?d^      }?t	        j
                  |@d^      }@t        j                         }A|?|d   d_<   |@|d   d`<   t7        d7|;dY   dF         }Bt7        d7|;dY   dG         }Ct7        d7|<dY   dF         }Dt7        d7|<dY   dG         }E|B|C|;dY   d4   |;dY   d5   da|;d1   d2   |;d1   d3   |;d1   dI   |;d1   dJ   |;d1   dK   |;d1   dL   |;d1   d4   |;d1   d5   db|;dY   d5   |;dY   d4   fd^d|;dY   d4   z  d|;dY   d5   z  dcdd|D|E|<dY   d4   |<dY   d5   da|<d1   d2   |<d1   d3   |<d1   dI   |<d1   dJ   |<d1   dK   |<d1   dL   |<d1   d4   |<d1   d5   db|<dY   d5   |<dY   d4   fd^d|<dY   d4   z  d|<dY   d5   z  dcdd||dedf|dg<   dh|d<   t        di|A|7z
  d"d#       |S # t"        $ rB}t        d+|        |d   d   j                  d+|        d|d,<   |cY d}~cddd       S d}~ww xY w# 1 sw Y   	xY w)juW   
        执行极耳裁切
        从主程序的 run_cut 方法迁移实现
        r   r   r   r   r   r   ry   r|   r   rQ  r      裁切IOU阈值r   r}   r~      合并检测框T   极耳裁切用户参数   上极耳宽度r     上极耳高度r     下极耳宽度   下极耳高度   极耳宽度扩展冗余r     极耳高度扩展冗余   极耳间距      隔膜获取深度Nr   u   ⏱️ 缩放时间: r#  r$  r"  u   裁切模型加载失败: u!   ⏱️ 裁切模型加载时间: Fr   jierr   u   裁切模型推理失败: r   u!   ⏱️ 裁切模型推理时间: u   提取极耳框时间: r   u   合并极耳框时间: r'  rM   rN   r   r   r	   r   uB   ⚠️ 检测框会超出图像边界，将置信度降低到0.1: r%  rR  u      原始置信度: rS  r2  u      裁切AOI: x=r   r   r   u      图像尺寸: w=r   c                     | d   S )NrS  r:   )r   s    r4   <lambda>z*EarFoldDetector._run_cut.<locals>.<lambda>  s
    :K8Lr;   )r1  reverser   r   r(   r-   r.   r(  r)  r*  u   还原检测框时间: u/   检测到上极耳，生成下极耳，间距: u/   检测到下极耳，生成上极耳，间距: r4  u/   ✅ 成功生成第二个极耳，现在共有 u
    个极耳u'   ⚠️ 检测到的极耳数量异常: u   ，预期为2u    检测到的极耳数量异常: r  r  cut_aoir  r  u   上极耳裁切框:u   下极耳裁切框:)r~   r~   r  r  )r   r   r   r   )rM   rN   r-   r.   r(  r)  r   r   )u   原始尺寸u   缩放后尺寸   缩放比例_x   缩放比例_y)   裁切区域u	   检测框   缩放信息)r   r   )	   上极耳	   下极耳u   源图像尺寸   极耳裁切信息rJ  u   裁切出图执行时间: )r&   r   r   r!   rh  ri  r   r_   rF   rg   r?   r   r   r   r   rd   r   r%   rj  rk  r"   sortedr   rl  rv   r   rp  r#   )FrA   r'   r   r/   
cut_paramsr   cut_confidencecut_iou_thresholdcut_input_sizecut_merge_detectusr_dicttop_jr_widthtop_jr_heightbottom_jr_widthbottom_jr_heightjr_width_expand_ratiojr_height_expand_ratiojier_spacinggm_get_deepr   r  
src_height	src_widthresize_imageresize_timer  cut_load_timer   r  r3   cut_predict_timecut_jr_listr  r  r  cut_merge_detect_endrA  r   r   orig_x1orig_y1
orig_widthorig_heightorig_center_xorig_center_y
is_up_jierjr_width_paramjr_height_param	cut_aoi_x	cut_aoi_ycut_aoi_widthcut_aoi_heightsrc_jr_listr  r  aoi_resize_timesingle_jiersingle_center_ysecond_jierup_jier	down_jierjier1jier2r  r  cut_timeup_actual_xup_actual_ydown_actual_xdown_actual_ysF                                                                         r4   r  zEarFoldDetector._run_cut}  sX    !#~ "}02}n-02}n-x ZZ :B?
#;#S9&NN+<cB#<%>>*;TB ::8"=||$5s; %6<",,'8#>#<<(93? (-G M!).H#!N||NC8||$8#>&&(
	 ) 3
Izz)nn-MN'')%kJ&>s%C4HI nn??PTP^P^_()H)H(IJK=!.188;UVZVdVdVuVuUv9wxM))+1-+2Mc1RRVWX.3+%3"V
 	&&~6   $ 8 8 >>)(! !9 ! !  ,,.12B]2RSV1WW[\] nn;;MJ%)%6%6%8"'(BEU(UVY'ZZ^_` $(>>#V#VWbdh#i y#002'(<?Y(YZ]'^^bcd  D.0G >1G ${+D1G;<G${+D1G;<GT+.w7'ABJd;/9GCDK#jAo5M#kQ&66M 'a7J !-"/!0"2 &OqCY?Y,Z]^,^(__I%NaBW>W,X[\,\(]]I17M3M NOM 17L3L!MNN "O3I)O;M AAM)I5N*Z7Z[_[c[cdrt}[~Z  A  B,T2C-DS,IJK(4	{$}oUYZhYijk+I;d:,GH*-&'[  ` [.LVZ[\^]^_ D		IH.0G >1G  [ 1$ 7' ABHSM[ 1$ 7' ABHSM #D$5g$>$H IHW!$T+%6x%@7%J!KHX  (Ie ,/tK/@/F/P+QIk"4(+.tK/@/F/P+QIk"4(+.tK/@/F/P+QIk"4(+.tK/@/F/P+QIk"4(14T+5Fz5RU\5\1]Ik":.14T+5Fz5RU\5\1]Ik":..1${2CG2Lw2V.WIk"7+/243DX3NQX3X/YIk"8,"+K"8"AIkDZ[cDd"dIhy)9  < ++-':N(Ns'SSWXY {q %a.K)+6zBO ):>9J &**,K'2;'?'D'D'FK$G~VWK(4D4K(.,>.K(.,>. G~VWK(4D4K(.,>.K(.,>. %0$<W$ET_H`aiHj$jK!$%K! {+CCDTCUU_`a";C<L;M][\=!.188;[\_`k\l[mmz9{|M	 {q NENE [!*-k0B:0NN!	!	!(!5!:!:!<~!*;!7!<!<!>~	!	)%k2487;;OPW;X\];]]
%k2487;;OPX;Y]^;^^
 )+ 6t <y?UV]?^bc?c c	* )+ 6t <y?UV^?_cd?d d	* #**"5MQQgMg<hkl<l8m"m	3")*"5LAPeLe<fij<j8k"k	3&)-1?U;U*V&W	7#'*<1?T;T+U'V	8$$-j$9C@PTUXnTn@ors@s<t$t	)S!$-j$9CSTWlSl@mpq@q<r$r	)S!(+,<DZ@Z,[(\	)W%),_DY@Y-Z)[	)X&#&wy'9#'>Q\A\'\#]	3'*79+=g+FZeIe+e'f	7#$'	)(<S(ADTWbDb(b$c	)S!),Yy-A'-JM]`kMk-k)l	)W%'.y'9'>'>'@#$'0';'@'@'B#$#c&1E*F&GGH#c&1E*F&GGH33Iwy?QR55i9AUVjjj9

=*=$$&0;~}-2?~/ !WY/45!WY/45Ay3C89Ay3C89
 '2&-i&8&A'.y'9('C!E "+.t4!+.t4!+.t4!+.t4 ' 4Z @ ' 4Z @$[1':%k28<	 &-Y%7%A79CUV]C^$_'1&)GI,>w,G&G&)GI,>x,H&H	!, '4-&/	&:7&C'0';H'E!G $K06#K06#K06#K06 )+ 6z B )+ 6z B&{3G<'4X>	 &/y%9(%CYyEYZaEb$c'1&)Ii,@,I&I&)Ii,@,J&J	!, #$ W/(
#$b  x*8o+Ec*J$OPI  21#67}%n5<<?YZ[Y\=]^)-~& !  ! s6   q**p	q'%.q"q'q*"q''q**q4c                 H   d }|j                  di       }|si S i }d}|r?d|v r:|d   D ]1  }|j                         }	d|	d<   |d   dk(  rE ||d	   d
   |d	   d   d|      \  }
} ||d   d
   |d   d   d|      \  }}|
|d|	d	<   ||d|	d<   n|d   dk(  rH ||d   d
   |d   d   d|      \  }}||d|	d<   |d   d   d   |d   d   d   z   dz  }|d   |z  |	d<   nl|d   dk(  r:g }|d   D ]*  } ||d
   |d   d|      \  }}|j                  ||d       , ||	d<   n*|d   dk(  r" ||d   d
   |d   d   d|      \  }}||d|	d<   d|d}|	||<   |dz  }4 |r?d|v r:|d   D ]1  }|j                         }	d|	d<   |d   dk(  rE ||d	   d
   |d	   d   d|      \  }
} ||d   d
   |d   d   d|      \  }}|
|d|	d	<   ||d|	d<   n|d   dk(  rH ||d   d
   |d   d   d|      \  }}||d|	d<   |d   d   d   |d   d   d   z   dz  }|d   |z  |	d<   nl|d   dk(  r:g }|d   D ]*  } ||d
   |d   d|      \  }}|j                  ||d       , ||	d<   n*|d   dk(  r" ||d   d
   |d   d   d|      \  }}||d|	d<   d|d}|	||<   |dz  }4 |S )u  
        将512x512裁切图像的检测结果复原到原图坐标系
        从主程序的 restore_draw_items_to_original 方法迁移实现
        
        Args:
            result_up: 上极耳检测结果
            result_down: 下极耳检测结果  
            result_all: 裁切结果，包含极耳裁切信息
            
        Returns:
            dict: 复原到原图的绘图项字典，每个项目以唯一ID为键
        c                     ||   }| |d   d   z  }||d   d   z  }||d   d   z   }||d   d   z   }t        |      t        |      fS )u1   将512x512裁切图像坐标复原到原图坐标rI  rF  rG  rH  r   r   )r   )	x_cropy_cropear_typecut_infoear_infox_cuty_cut
x_original
y_originals	            r4   restore_coordinates_to_originalzXEarFoldDetector._restore_draw_items_to_original.<locals>.restore_coordinates_to_original  sw    )H Xn56FGGEXn56FGGE .!9#!>>J.!9#!>>J$eJ&777r;   rL  r   r   rJ  u   来源r   r   r   r   r   r   r   r   r   rI  rF  rG  r   r   r   r   r   r   r   03dr	   rK  )r&   r   r   )rA   r  r  r   r  r  result_dictitem_counterr   restored_itemrM   rN   r-   r.   cxcy	scale_avgrestored_pointsrH   rK   rL   txtyitem_keys                           r4   r  z/EarFoldDetector._restore_draw_items_to_original  s^   	8 >>"6;I 2!,/ $		*5h'<;.<Y,d9oc.B#XFB =]+C0$}2Ec2J#XFB 68b/AM),9;"3EM-0&\X-<Xs+T(^C-@#XFB 57R.@M(+!)+!6~!FGW!X'4^DEUV"WZ[!\I.28ny.HM(+&\Y.&(O!%h!@!#Jc
'"B (..Rb/AB "0 />M(+&\V+<Z(-tJ/?/D#XFB 79r0BM*- #<"45(5H%!g 0l <;6#L1 $		*5h'<;.<Y,d9oc.B#XFB =]+C0$}2Ec2J#XFB 68b/AM),9;"3EM-0&\X-<Xs+T(^C-@#XFB 57R.@M(+!)+!6~!FGW!X'4^DEUV"WZ[!\I.28ny.HM(+&\Y.&(O!%h!@!#Jc
'"B (..Rb/AB "0 />M(+&\V+<Z(-tJ/?/D#XFB 79r0BM*- #<"45(5H%!g 2j r;   c           	      "   dddddd}ddddd	d
ddd}dd	d	d	d	d	d	d}dd	d	d	d	d	d	d}dd
dd}dddd|d|d}i dddd
dd
dddddddddd
dddd d!dd"dd#d$d%d$d&dd'd d(dddd)d*dd+d,d-}dd.d/}ddd0}ddd1}	||||||d2}
|
S )3uN   
        获取默认参数配置（从原始配置文件中提取）
        r   r   r   r~   T)r|   rQ  r5  r}   r6  r  r  r   r	  r?  r  )r8  r9  r:  r;  r<  r=  r>  r@  F)r   r   r   r   r   r   r   g      @r  )r5  r6  r7  )r|   r   r   r}   r   r   r   r   r   r   r   r  r  r  r  r  r  r
  r  r  r  r  r  r  r  r  r  r  r   r   rD   r  )r  r  r  r  r  r  r  r   )r|   r}   )r   r!  )u   更新脚本地址u   更新UI地址)ry   r7  rz   r   r{   r  r:   )rA   
jrcut_dictjrcut_usr_dictr   rz  deleted_dictfold_usr_dictgm_dictgm_usr_dictupdate_dictall_parameterss              r4   rs   z&EarFoldDetector.get_default_parametersX  s    "#

  #"""(+(+"%	
 &+"""%(%("
 &+"""%(%("
 &)(+(+$
  "%5(,.F

8#
>
 ?
 '	

 '
 '
 '
 !#
 e
 C
 C
 '
 *3
 *3
 *4
  s!
$ !$%
& $"  !'155
> 
 #'!
 "$
 )3(6.:(5(/"-
 r;   c                 j    | j                   rt        d       | j                          yt        d       y)u   
        重写基类的预热方法
        
        如果检测器已初始化，再次执行模型预热
        如果未初始化，只记录警告信息
        u   🔥 执行检测器预热...u1   ⚠️ 检测器未初始化，无法执行预热N)ru   r   rt   r@   s    r4   warm_upzEarFoldDetector.warm_up  s+     12  "EFr;   c                 b    t         |           d| _        d| _        d| _        t        d       y)u   清理资源Nu   🧹 检测器资源已清理)r^   cleanupr_   r`   ra   r   rk   s    r4   r  zEarFoldDetector.cleanup  s-      -.r;   )N)r   r   r   )rm   N)r6   r7   r8   __doc__rB   rv   ro   r   r   boolrw   rt   r   r+  r   r   r   r  r  r#  r-  r  r  rs   r  r  __classcell__)rl   s   @r4   rX   rX      s   "60S 0S#X $ Br2j<BJJ <S#X <$sTWx. <|D#L^BJJ ^S#X ^4PSUXPX> ^@!
c3h 
H3 Hrzz H4PSUXPX> Heijmorjres HeRZZ ec3h e4PSUXPX> eN>@Fbjj F$sCx. FT#s(^ FP
Qf{S#X {zG/ /r;   rX   )%r  rh  r(  r   r   typingr   r   r   r   r   rb   jsonossysr   r   rD   dirname__file__current_dir
parent_dirr   base_detectorr
   utils.model_utilsr   utils.model_cls_utilsr   r   ImportErrorr3   r   r   r=   rV   rX   r:   r;   r4   <module>r     s   
    3 3   	 
   ggooh'WW__[)
SXXHHOOJ '8,2;p1h_!/l _!/W  4,	,QC
01#d #dJ KE  '+i4,s   B> >C7*C22C7