
    iR                       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 ddl	Z	ddl
ZddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z  ddl!m"Z"m#Z#m$Z$m%Z%m&Z& ddl'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0 ddl1m2Z2 	 ddl3Z3ddl4m5Z5 d	Z6d Z9 G d de      Z: G d de      Z; G d de      Z< G d de      Z= G d de      Z> G d de      Z?d Z@eAdk(  r e@        yy# e7$ r d
Z6 e8d       Y gw xY w)u]   
图像AOI编辑器
支持打开图片、缩放、创建AOI区域、编辑AOI属性等功能
    N)ListDictOptionalTuple)QApplicationQMainWindowQLabelQFileDialogQMessageBoxQColorDialogQTreeWidgetItemQGraphicsViewQGraphicsSceneQGraphicsPixmapItemQGraphicsRectItemQWidgetQGraphicsItemQDialogQVBoxLayoutQHBoxLayoutQPushButton	QComboBoxQSliderQSpinBox)Qt
pyqtSignalQRectFQPointFQObject)	QPixmapQImageQPenQBrushQColorQPainterQWheelEventQMouseEventQCursor)uic)QVTKRenderWindowInteractorTFz6VTK not available. Please install vtk: pip install vtkc                 P   	 |j                         j                  d      d   }|dv r-t        j                  dg}t        j                  d| |      \  }}n|dk(  r-t        j
                  dg}t        j                  d| |      \  }}nh|d	v rt        j                  d
|       \  }}nJ|dv rt        j                  d|       \  }}n,t        j                  dg}t        j                  d| |      \  }}|r|j                  |       yy# t        $ r}t        d|        Y d}~yd}~ww xY w)u   
    保存图像到中文路径
    
    Args:
        image: OpenCV图像数组
        file_path: 包含中文的文件路径
    
    Returns:
        bool: 是否保存成功
    .)jpgjpeg_   .jpgpng   z.png)bmpz.bmp)tiftiffz.tiffTFu   保存图像失败: N)	lowersplitcv2IMWRITE_JPEG_QUALITYimencodeIMWRITE_PNG_COMPRESSIONtofile	Exceptionprint)image	file_pathextencode_paramsuccessencoded_imges          N   G:\PythonWorkeSpace\program\极耳翻折插件\utilswidget\image_aoi_editor.pysave_image_chinese_pathrH       s   oo%%c*2. /!44b9L#&<<|#L G[E\77;L#&<<|#L G[G^#&<<#> G[O##&<<#? G[  44b9L#&<<|#L G[y) $QC()s   D D 	D%D  D%c                   0     e Zd ZdZd fd	Zd Zd Z xZS )ChannelSelectoru   通道选择对话框c                 `    t         |   |       || _        d| _        | j	                          y )Nr   )super__init__image_shapeselected_channelsetup_ui)selfrN   parent	__class__s      rG   rM   zChannelSelector.__init__N   s)     & !    c                    | j                  d       | j                  d       | j                  dd       t               }t	               }|j                  t        d             t               | _        t        | j                        dk(  r<t        | j                  d         D ]   }| j                  j                  d|        " n| j                  j                  d	       |j                  | j                         |j                  |       t	               }t        d
      | _        t        d      | _        | j                  j"                  j%                  | j&                         | j                   j"                  j%                  | j(                         |j                  | j                         |j                  | j                          |j                  |       | j+                  |       y)   设置UIu   选择通道Ti,     u   选择通道:r3         通道    灰度通道u   确定u   取消N)setWindowTitlesetModalresizer   r   	addWidgetr	   r   channel_combolenrN   rangeaddItem	addLayoutr   btn_ok
btn_cancelclickedconnectacceptreject	setLayout)rQ   layoutchannel_layoutibutton_layouts        rG   rP   zChannelSelector.setup_uiT   sm   N+dC %  !89&[t A%4++A./""**WQC=9 0 &&~6  !3!34( $!(+%h/##DKK0''4,0'vrT   c                 6    | j                   j                         S )u   获取选中的通道)r_   currentIndexrQ   s    rG   get_selected_channelz$ChannelSelector.get_selected_channelz   s    !!..00rT   N)__name__
__module____qualname____doc__rM   rP   rr   __classcell__rS   s   @rG   rJ   rJ   K   s    $L1rT   rJ   c                   N     e Zd ZdZd
 fd	Zd Zd Zd Zd Zd Z	d Z
d	 Z xZS )VTKDepthVieweru   VTK 3D深度图查看器c                 `    t         |   |       || _        || _        | j	                          y rs   )rL   rM   
depth_datachannel_namerP   )rQ   r}   r~   rR   rS   s       rG   rM   zVTKDepthViewer.__init__   s(     $(rT   c                 Z   | j                  d| j                          | j                  dd       t               }t        sMt        d      }|j                  t        j                         |j                  |       | j                  |       yt        |       | _        |j                  | j                         t               }|j                  t        d             t        t        j                        | _        | j                   j#                  dd       | j                   j%                  d	       | j                   j&                  j)                  | j*                         |j                  | j                          t        d
      | _        |j                  | j,                         |j                  t        d             t/               | _        g d}| j0                  j3                  |       | j0                  j4                  j)                  | j6                         |j                  | j0                         t9        d      }|j:                  j)                  | j<                         |j                  |       |j?                  |       | j                  |       | jA                          y)rV   u   3D深度视图 - i   iX  u*   VTK未安装！
请运行: pip install vtkNu   高度缩放:   d   
   10xu   颜色映射:)JetHotCoolRainbowViridisGrayu   重置视角)!r[   r~   r]   r   VTK_AVAILABLEr	   setAlignmentr   AlignCenterr^   rj   r*   
vtk_widgetr   r   
Horizontalheight_slidersetRangesetValuevalueChangedrg   update_height_scaleheight_labelr   colormap_comboaddItemscurrentTextChangedupdate_colormapr   rf   reset_camerarc   create_3d_scene)rQ   rk   error_labelcontrol_layout	colormaps	reset_btns         rG   rP   zVTKDepthViewer.setup_ui   s   /0A0A/BCDC !NOK$$R^^4[)NN6" 5T:) % 	  !89$R]]3##As+##B'''//0H0HI  !3!34"5M  !2!23 	  !89'kH	$$Y/..66t7K7KL  !4!45  /	!!$"3"34  +(v 	rT   c                    t         syt        j                         | _        | j                  j                         j                  | j                         | j                  j                         j                         | _        | j                          | j                  j                  ddd       | j                          | j                          | j                  j                          y)u   创建3D场景Ng?皙?g?)r   vtkvtkRendererrendererr   GetRenderWindowAddRendererGetInteractor
interactorcreate_depth_surfaceSetBackgroundadd_axesr   
Initializerq   s    rG   r   zVTKDepthViewer.create_3d_scene   s     )'')55dmmD//99;IIK 	!!# 	##Cc2 	 	 	""$rT   c                 8   | j                   j                  \  }}t        j                         }t	        j
                  | j                   dddt        j                  t        j                        }t        j                         }|j                  d       t        |      D ]O  }t        |      D ]?  }|||f   dz  }|j                  |||       |j                  | j                   ||f          A Q t        j                         | _        | j                  j                  ||d       | j                  j!                  |       | j                  j#                         j%                  |       t        j&                         }	|	j)                  | j                         t        j*                         | _        | j,                  j/                  |	j1                                | j,                  j3                  | j                   j5                         | j                   j7                                | j9                  d       t        j:                         | _        | j<                  j?                  | j,                         | j@                  jC                  | j<                         y)u   创建深度表面Nr   r   Depthr   r   )"r}   shaper   	vtkPointsr9   	normalizeNORM_MINMAXCV_32FvtkFloatArraySetNamera   InsertNextPointInsertNextValuevtkStructuredGridstructured_gridSetDimensions	SetPointsGetPointData
SetScalarsvtkStructuredGridGeometryFilterSetInputDatavtkPolyDataMappermapperSetInputConnectionGetOutputPortSetScalarRangeminmaxr   vtkActoractor	SetMapperr   AddActor)
rQ   hwpointsdepth_normalizedscalarsyxzgeometry_filters
             rG   r   z#VTKDepthViewer.create_depth_surface   s   $$1  ==$1cooWZWaWab ##% qA1X$QT*R/&&q!Q/''1(=>    #446**1a3&&v.))+66w? ==?$$T%9%9: ++-&&'D'D'FG""4??#6#6#8$//:M:M:OP 	U# \\^


T[[) 	tzz*rT   c                 P   | j                   j                  | d       | j                  j                  \  }}t	        j
                  | j                  dddt        j                  t        j                        }| j                  j                         }t        |      D ]O  }t        |      D ]?  }||z  |z   }|j                  |      }	|||f   |z  }
|j                  ||	d   |	d   |
       A Q |j                          | j                  j                         j!                          y)u   更新高度缩放r   Nr   r   )r   setTextr}   r   r9   r   r   r   r   	GetPointsra   GetPointSetPointModifiedr   r   Render)rQ   valuer   r   r   r   r   r   point_idcurrent_pointr   s              rG   r   z"VTKDepthViewer.update_height_scale  s    !!UG1+. $$1==$1cooWZWaWab%%//1qA1Xq519 & 9$QT*U2-*:M!<LaP	   	'')002rT   c                    t        j                         }|j                  d       |dk(  r|j                  dd       n|dk(  r|j                  dd       nq|dk(  r|j                  dd       nY|d	k(  r|j                  dd       nA|d
k(  r|j                  dd       n)|dk(  r$|j                  dd       |j	                  dd       |j                  | j                  j                         | j                  j                                |j                          | j                  j                  |       | j                  j                         j                          y)u   更新颜色映射   r   gMbX?        r   gK7A`?r         ?r   r   g      ?g      ?r   N)r   vtkLookupTableSetNumberOfColorsSetHueRangeSetSaturationRangeSetRanger}   r   r   Buildr   SetLookupTabler   r   r   )rQ   colormap_nameluts      rG   r   zVTKDepthViewer.update_colormap  s     "c"E!OOE3'e#OOC'f$OOE3'i'OOC'i'OOD$'f$OOC%""3,T__((*DOO,?,?,AB		""3''')002rT   c                    t        j                         }|j                  ddd       t        j                         | _        | j                  j                  |       | j                  j                  | j                         | j                  j                  dddd       | j                  j                  d       | j                  j                          y)u   添加坐标轴2   r   r   r   N)r   vtkAxesActorSetTotalLengthvtkOrientationMarkerWidgetaxes_widgetSetOrientationMarkerSetInteractorr   SetViewport
SetEnabledInteractiveOn)rQ   axess     rG   r   zVTKDepthViewer.add_axes-  s    !BB' 99;--d3&&t7$$S#sC8##A&&&(rT   c                    | j                   j                          | j                   j                         }|j                  ddd       |j	                  | j
                  j                  d   dz  | j
                  j                  d   dz  d       |j                  ddd       | j                   j                  |       | j                  j                         j                          y)u   重置相机视角r   r   r   rX   r-   N)r   ResetCameraGetActiveCameraSetPositionSetFocalPointr}   r   	SetViewUpSetActiveCamerar   r   r   )rQ   cameras     rG   r   zVTKDepthViewer.reset_camera:  s    !!#..01a%T__2215a79N9Nq9QRS9SUVWB"%%f-'')002rT   )u	   深度图N)rt   ru   rv   rw   rM   rP   r   r   r   r   r   r   rx   ry   s   @rG   r{   r{      s0    "1f%2++Z3&32)3rT   r{   c                   F     e Zd ZdZ fdZd Z fdZ fdZ fdZ xZ	S )ResizeHandleu   缩放句柄类c                     t        |   |i | || _        || _        | j	                  t
        j                  t
        j                  z         | j                  | j                                y rs   )
rL   rM   parent_itemhandle_typesetFlagsr   ItemIsMovableItemSendsGeometryChanges	setCursorget_cursor_for_handle)rQ   r  r  argskwargsrS   s        rG   rM   zResizeHandle.__init__H  sW    $)&)&&m11M4Z4ZZ[t1134rT   c           	      L   t         j                  t         j                  t         j                  t         j                  t         j                  t         j                  t         j                  t         j                  d}|j                  | j                  t         j                        S )u-   根据句柄类型返回相应的鼠标光标)tltrblbrtblr)r   SizeFDiagCursorSizeBDiagCursorSizeVerCursorSizeHorCursorgetr  ArrowCursor)rQ   
cursor_maps     rG   r  z"ResizeHandle.get_cursor_for_handleO  sp     $$$$$$$$!!!!!!!!	

 ~~d..??rT   c                     |j                         t        j                  k(  r;| j                  j	                  | |j                                |j                          yt        | !  |       yu   鼠标按下事件N)	buttonr   
LeftButtonr  start_resizescenePosrh   rL   mousePressEventrQ   eventrS   s     rG   r   zResizeHandle.mousePressEvent]  sH    <<>R]]*))$0@ALLNG#E*rT   c                     | j                   j                  rS| j                   j                  | k(  r:| j                   j                  |j	                                |j                          yt        |   |       y)   鼠标移动事件N)r  resizingresize_handle	resize_tor  rh   rL   mouseMoveEventr!  s     rG   r(  zResizeHandle.mouseMoveEvente  sV    $$)9)9)G)G4)O&&u~~'78LLNG"5)rT   c                     |j                         t        j                  k(  rA| j                  j                  r+| j                  j                          |j                          yt        | !  |       y)   鼠标释放事件N)	r  r   r  r  r%  
end_resizerh   rL   mouseReleaseEventr!  s     rG   r,  zResizeHandle.mouseReleaseEventm  sK    <<>R]]*t/?/?/H/H'')LLNG%e,rT   )
rt   ru   rv   rw   rM   r  r   r(  r,  rx   ry   s   @rG   r   r   E  s%    5@+*- -rT   r   c                   p     e Zd ZdZd fd	Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Z fdZd Z xZS )ResizableRectItemu!   可拖拽、缩放的矩形AOI项c           
         t         |   |       || _        || _        || _        | j                  t        j                  t        j                  z  t        j                  z         g | _
        d| _        d| _        d | _        d | _        d | _        | j!                          | j#                  t%        t'        |j)                  dd            t*        j,                               | j/                          y )N   Fcolorred)rL   rM   aoi_datascale_factorparent_viewerr  r   r  ItemIsSelectabler  handleshandle_sizer%  r&  resize_start_posoriginal_rectupdate_pen_widthsetBrushr#   r$   r  r   NoBrushcreate_handles)rQ   rectr3  r4  r5  rS   s        rG   rM   zResizableRectItem.__init__y  s     (*m11#445#<<= 	>
 ! $! 	fVHLL%$@A2::NO 	rT   c                 `   d}t        d|| j                  z        }t        t        | j                  j                  dd            |      }| j                  |       t        dd| j                  z        }| j                  D ]+  }|j                  t        t        j                  |             - y)u$   根据缩放比例更新线条宽度       @r   r1  r2        ?N)
r   r4  r"   r$   r3  r  setPenr7  r   black)rQ   
base_width	pen_widthpenhandle_pen_widthhandles         rG   r;  z"ResizableRectItem.update_pen_width  s     
Z$*;*;;<	6$--++GU;<iHC sC$*;*;$;<llFMM$rxx)9:; #rT   c                 B    || j                   d<   | j                          y)u   更新AOI颜色r1  N)r3  r;  )rQ   
color_names     rG   update_colorzResizableRectItem.update_color  s    !+grT   c                 R    || _         | j                          | j                          y)u!   更新缩放比例并调整显示N)r4  r;  update_handle_size)rQ   r4  s     rG   update_scale_factorz%ResizableRectItem.update_scale_factor  s"    (!rT   c           
      2   | j                         }| j                         }t        dd| j                  z        }|j	                         |j                         df|j                         |j                         df|j	                         |j                         df|j                         |j                         df|j                         j                         |j                         df|j                         j                         |j                         df|j	                         |j                         j                         d	f|j                         |j                         j                         d
fg}|D ]  \  }}}t        | |||dz  z
  ||dz  z
  ||      }|j                  |        |j                  t        t        j                                |j#                  t%        t        j&                  |             | j(                  j+                  |        y)u   创建调整大小的句柄rB  r   r  r  r  r  r  r  r  r  rX   N)r?  get_scaled_handle_sizer   r4  lefttoprightbottomcenterr   r   r   setParentItemr<  r#   r   whiterC  r"   rD  r7  append)	rQ   r?  r8  rH  handle_datar   r   r  rI  s	            rG   r>  z ResizableRectItem.create_handles  s   yy{113sC$*;*;$;< YY[$((*d+ZZ\488:t,YY[$++-.ZZ\4;;=$/[[]__
C0[[]__s3YY[$++-//+S1ZZ\4;;=??,c2	
 "-Aq+!kKM!KM!F   &OOF288,-MM$rxx)9:;LL' "-rT   c           
      0   | j                         }| j                         }|j                         |j                         f|j	                         |j                         f|j                         |j                         f|j	                         |j                         f|j                         j                         |j                         f|j                         j                         |j                         f|j                         |j                         j                         f|j	                         |j                         j                         fg}t        | j                  |      D ]+  \  }}|j                  |d   |dz  z
  |d   |dz  z
  ||       - y)u   更新句柄位置r   rX   r   N)r?  rQ  rR  rS  rT  rU  rV  r   r   zipr7  setRect)rQ   r?  r8  handle_positionsrI  poss         rG   update_handlesz ResizableRectItem.update_handles  s/   yy{113 YY[$((*%ZZ\488:&YY[$++-(ZZ\4;;=)[[]__
+[[]__.YY[$++-//+,ZZ\4;;=??,-	
 t||-=>KFCNNAQ&AQ&	 ?rT   c                 8    d}t        d|| j                  z        S )u'   获取根据缩放调整的句柄大小g       @g      @)r   r4  )rQ   	base_sizes     rG   rQ  z(ResizableRectItem.get_scaled_handle_size  s    	3	D$5$5566rT   c           
      0   | j                         }| j                         }|j                         |j                         f|j	                         |j                         f|j                         |j                         f|j	                         |j                         f|j                         j                         |j                         f|j                         j                         |j                         f|j                         |j                         j                         f|j	                         |j                         j                         fg}t        | j                  |      D ]+  \  }}|j                  |d   |dz  z
  |d   |dz  z
  ||       - y)u   更新句柄大小r   rX   r   N)rQ  r?  rR  rS  rT  rU  rV  r   r   r\  r7  r]  )rQ   r8  r?  r^  rI  r_  s         rG   rN  z$ResizableRectItem.update_handle_size  s-   113yy{YY[$((*%ZZ\488:&YY[$++-(ZZ\4;;=)[[]__
+[[]__.YY[$++-//+,ZZ\4;;=??,-	
 t||-=>KFCNNAQ&AQ&	 ?rT   c                     d| _         || _        || _        | j                         | _        | j                  t        j                  d       y)u   开始缩放操作TFN)r%  r&  r9  r?  r:  setFlagr   r  )rQ   rI  	scene_poss      rG   r  zResizableRectItem.start_resize  s;    # )!YY[]00%8rT   c                    | j                   r| j                  sy| j                  |      }| j                  | j                        }|j	                         |j	                         z
  }|j                         |j                         z
  }| j                  }t        |      }| j                  j                  }|dk(  r.|j                  |j                         t        ||      z          n6|dk(  r.|j                  |j                         t        ||      z          n|dk(  r-|j                  |j                         t        ||      z          n|dk(  r-|j!                  |j#                         t        ||      z          n|dk(  r#|j%                  |j'                         |z          nw|dk(  r#|j)                  |j+                         |z          nO|dk(  r#|j-                  |j/                         |z          n'|d	k(  r"|j1                  |j3                         |z          d
}	|j5                         |	k  rI|dv r#|j-                  |j3                         |	z
         n"|j1                  |j/                         |	z          |j7                         |	k  rI|dv r#|j%                  |j+                         |	z
         n"|j)                  |j'                         |	z          | j9                  |       | j;                          | j=                          y)u   执行缩放Nr  r  r  r  r  r  r  r  r   )r  r  r  )r  r  r  )r%  r&  mapFromScener9  r   r   r:  r   r  
setTopLefttopLeftr   setTopRighttopRightsetBottomLeft
bottomLeftsetBottomRightbottomRightsetToprS  	setBottomrU  setLeftrR  setRightrT  widthheightr]  r`  update_aoi_data)
rQ   rf  	local_posstart_localdxdyr?  new_rectr  min_sizes
             rG   r'  zResizableRectItem.resize_to  su   }}D$6$6 %%i0	''(=(=> [[][]]_,[[][]]_, !!$< ((44$R @AD   72r?!BCD ""4??#4wr2#FGD ##D$4$4$6R$HICOODHHJO,Ct{{}r12CTYY[2-.CdjjlR/0 >>h&//  !1H!<=!!(--/H"<=??x'// 1H <=""8<<>H#<= 	XrT   c                 |    d| _         d| _        d| _        d| _        | j	                  t
        j                  d       y)u   结束缩放操作FNT)r%  r&  r9  r:  re  r   r  rq   s    rG   r+  zResizableRectItem.end_resize@  s5    ! $!]00$7rT   c                 P   |t         j                  k(  r| j                          nr|t         j                  k(  r_| j                  D ]  }|j                  |        |r;| j                  r/| j                  j                  j                  | j                         t        | -  ||      S )u   监听项的变化)r   ItemPositionHasChangedrw  ItemSelectedHasChangedr7  
setVisibler5  aoi_selectedemitr3  rL   
itemChange)rQ   changer   rI  rS   s       rG   r  zResizableRectItem.itemChangeI  s    &===  "(???,,!!%( ' ++""//44T]]Cw!&%00rT   c                    | j                         }| j                         }| j                  j                         }t	        |j                         |j                         z         | j                  d<   t	        |j                         |j                         z         | j                  d<   t	        |j                               | j                  d<   t	        |j                               | j                  d<   |d   | j                  d   k7  s?|d   | j                  d   k7  s*|d   | j                  d   k7  s|d   | j                  d   k7  r=| j                  r0| j                  j                  j                  | j                         yyy)u   更新AOI数据r   r   ru  rv  N)r?  r_  r3  copyintr   r   ru  rv  r5  aoi_data_changedr  )rQ   r?  r_  old_datas       rG   rw  z!ResizableRectItem.update_aoi_dataU  s-   yy{hhj==%%' 4668!34c 4668!34c!$TZZ\!2g"%dkkm"4h SMT]]3//s!33!T]]7%;;"dmmH&==!!""3388G " >rT   )r   N)rt   ru   rv   rw   rM   r;  rL  rO  r>  r`  rQ  rN  r  r'  r+  r  rw  rx   ry   s   @rG   r.  r.  v  sI    +0< 
"(>27
.96p8
1HrT   r.  c                        e Zd ZdZ ee      Z ee      Z ee      Z ee	e	      Z
 ee	      Z fdZd Z fdZdef fdZdef fdZdef fdZd	 Zd
 Zd Zd Zd Z xZS )ImageVieweru3   自定义图像查看器，支持缩放和AOI创建c                 |   t         |           t               | _        | j	                  | j                         d | _        d | _        d| _        d| _        d | _	        d | _
        g | _        d| _        | j                  t        j                         | j!                  t"        j$                         | j'                  t(        j*                         | j-                  t(        j*                         | j/                  t        j0                         | j3                  t        j0                         | j5                  d       y )Nr   Fr   T)rL   rM   r   scenesetScene
image_itemoriginal_pixmapr4  creating_aoistart_pointcurrent_rect_item	aoi_itemsaoi_countersetDragModer   ScrollHandDragsetRenderHintr%   AntialiasingsetVerticalScrollBarPolicyr   ScrollBarAsNeededsetHorizontalScrollBarPolicysetTransformationAnchorAnchorUnderMousesetResizeAnchorsetMouseTracking)rQ   rS   s    rG   rM   zImageViewer.__init__s  s    #%
djj! # "!% 	5568001 	''(<(<=))"*>*>? 	$$]%C%CD];;< 	d#rT   c                 H   | j                   j                          | j                  j                          || _        t	        |      | _        | j                   j                  | j
                         | j                   j                  t        |j                                      y)u   设置要显示的图像N)
r  clearr  r  r   r  rb   setSceneRectr   r?  )rQ   pixmaps     rG   	set_imagezImageViewer.set_image  si    

%-f5

4??+

v{{} 56rT   c                    | j                   rt        |d      r|j                         j                         }|dkD  rd}nd}| j                  |z  }d|cxk  rdk  r]n nZ| j                  ||       || _        | j                          | j                  j                  t        | j                  dz               |j                          yt        | 1  |       y)	u   鼠标滚轮缩放
angleDeltar   gffffff?gףp=
?g{Gz?g      I@r   N)r  hasattrr  r   r4  scaleupdate_aoi_displayscale_changedr  r  rh   rL   
wheelEvent)rQ   r"  deltafactor	new_scalerS   s        rG   r  zImageViewer.wheelEvent  s     GE<$@$$&((*E qy ))F2Iy(D(

66*$-! '') ""''D,=,=,C(DELLNGu%rT   r"  c                     |j                         t        j                  k(  rC| j                  r7| j	                  |j                               }|| _        |j                          yt        | %  |       yr  )
r  r   r  r  
mapToScener_  r  rh   rL   r   )rQ   r"  rf  rS   s      rG   r   zImageViewer.mousePressEvent  sO    <<>R]]*t/@/@		4I(DLLNG#E*rT   c                    | j                  |j                               }| j                  re| j                  j                  |      rJ| j                  j                  t        |j                               t        |j                                      | j                  r| j                  r| j                  r%| j                  j                  | j                         t        | j                  |      j                         }| j                  j!                  |t#        t$        j&                  dt$        j(                              | _        |j+                          yt,        | ]  |       y)r$  rX   N)r  r_  r  containsmouse_movedr  r  r   r   r  r  r  r  
removeItemr   
normalizedaddRectr"   r   r2  DashLinerh   rL   r(  )rQ   r"  rf  r?  rS   s       rG   r(  zImageViewer.mouseMoveEvent  s    OOEIIK0	 ??t77	B!!#ikkm"4c)++-6HI!1!1%%

%%d&<&<=$**I6AACD%)ZZ%7%7d2661bkk2&4D"LLNG"5)rT   c                    |j                         t        j                  k(  r)| j                  r| j                  r| j                  |j                               }t        | j                  |      j                         }|j                         dkD  r$|j                         dkD  r| j                  |       | j                  r,| j                  j                  | j                         d| _        d| _        d| _        | j                  t        j                          | j#                  t$        j&                         |j)                          yt*        | Y  |       y)r*  r   NF)r  r   r  r  r  r  r_  r   r  ru  rv  
create_aoir  r  r  r  r  r  r   r  rh   rL   r,  )rQ   r"  	end_pointr?  rS   s       rG   r,  zImageViewer.mouseReleaseEvent  s    <<>R]]*t/@/@TEUEU		4I$**I6AACDzz|b T[[]R%7% %%

%%d&<&<=)-&#D %DNN2>>*]99:LLNG%e,rT   c           	         | j                   d| j                    t        |j                               t        |j                               t        |j	                               t        |j                               ddd}t        t        dd|j	                         |j                               || j                  |       }|j                  |j                         |j                                |j                  |d          | j                  j                  |       | j                  j                  |       | xj                   dz  c_         | j                  j!                  |       y)	u   创建AOI区域AOI_r2   )idnamer   r   ru  rv  r1  descriptionr   r  r   N)r  r  r   r   ru  rv  r.  r   r4  setPos
setToolTipr  rb   r  rY  aoi_createdr  )rQ   r?  r3  aoi_items       rG   r  zImageViewer.create_aoi  s    ""4++,-TVVXTVVX&$++-(	
 %1at{{}5d''/ 	$&&(+ 	HV,-

8$h'Ah'rT   c                     d| _         | j                  t        j                         | j	                  t
        j                         y)u   开始AOI创建模式TN)r  r  r   CrossCursorr  r   NoDragrq   s    rG   start_aoi_creationzImageViewer.start_aoi_creation  s.     r~~&--.rT   c                 \    | j                   D ]  }|j                  | j                          y)u?   更新所有AOI项的显示（线条宽度、句柄大小等）N)r  rO  r4  )rQ   r  s     rG   r  zImageViewer.update_aoi_display  s$    H(():):; 'rT   c                 B   | j                   r| j                  | j                   t        j                         | j	                         }|j                         }|| _        | j                          | j                  j                  t        | j                  dz               yy)u   缩放以适应窗口r   N)r  	fitInViewr   KeepAspectRatio	transformm11r4  r  r  r  r  )rQ   r  current_scales      rG   zoom_to_fitzImageViewer.zoom_to_fit  sy    ??NN4??B,>,>? (I%MMOM -D ##%##C(9(9C(?$@A rT   c                     | j                   rC| j                          d| _        | j                          | j                  j                  d       yy)u   缩放到实际大小r   r   N)r  resetTransformr4  r  r  r  rq   s    rG   zoom_to_actualzImageViewer.zoom_to_actual+  sD    ??! #D ##%##C( rT   )rt   ru   rv   rw   r   dictr  r  r  r  r  r  rM   r  r  r'   r   r(  r,  r  r  r  r  r  rx   ry   s   @rG   r  r  j  s    =T"Kd#L!$'S#&KsOM$D7&<+[ +*K *(-{ -0(6/<
B"	)rT   r  c                   >    e Zd ZdZ fdZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd1dZd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d  Z"d! Z#d" Z$d# Z%d$ Z&d% Z'd& Z(d' Z)d( Z*d) Z+d* Z,d+ Z-d, Z.d- Z/d.e0e1   fd/Z2d0 Z3 xZ4S )2ImageAOIEditoru   图像AOI编辑器主窗口c                    t         |           t        j                  j	                  t        j                  j                  t              d      }t        j                  ||        d | _	        d | _
        g | _        d | _        d| _        t               | _        | j                   j#                  | j                         | j                   j%                  d       ddlm} ddlm}  | |d      |       | _        | j.                  j0                  j3                  | j4                         | j7                          | j9                          y )Nimage_aoi_editor.uiFTr   )	QShortcut)QKeySequenceF2)rL   rM   ospathjoindirname__file__r)   loadUicurrent_image_pathcurrent_image_arrayaoi_listcurrent_aoiupdating_propertiesr  image_viewer
scrollArea	setWidgetsetWidgetResizablePyQt5.QtWidgetsr  PyQt5.QtGuir  toggle_shortcut	activatedrg   toggle_aoi_panelsetup_connectionsrP   )rQ   ui_pathr  r  rS   s       rG   rM   zImageAOIEditor.__init__:  s     '',,rwwx8:OP

7D! #'#' #(  (M 	!!$"3"34**40 	.,(d);TB&&..t/D/DE 	  	rT   c                 D    | j                          |j                          y)u!   窗口关闭事件，清理内存N)cleanup_resourcesrh   )rQ   r"  s     rG   
closeEventzImageAOIEditor.closeEvent[  s     rT   c                    t        | d      rd| _        t        | d      r| j                  r| j                  j                  rd| j                  _        | j                  j                  rJ| j                  j
                  j                  | j                  j                         d| j                  _        | j                  j                  dd D ]'  }| j                  j
                  j                  |       ) | j                  j                  j                          | j                  j
                  j                          | j                  j                          d| _
        ddl}|j                          y)u   清理资源，释放内存r  Nr  r   )r  r  r  r  r  r  r  r  r  r  r  gccollect)rQ   itemr  s      rG   r  z ImageAOIEditor.cleanup_resources`  s    4./'+D$ 4(T->->  0048!!1  ++!!''2243D3D3O3OP/3!!, ))33A6!!''2248 7''--/ ##))+ 	 	


rT   c           	      l   | j                   t        j                  | dd       y	 | j                   j                  }t	        d| d| j                   j
                          t        j                  | j                   t        j                        | _         t	        d| j                   j                   d| j                   j
                          | j                          | j                  d       y# t        $ r;}t        j                  | dd	t        |              t	        d
|        Y d}~yd}~ww xY w)u   逆时针旋转图像90度N   警告   没有图像可旋转   旋转前: 数据类型=	   , 形状=   旋转后: 数据类型=   错误   图像旋转失败:
   旋转错误: )r  r   warningdtyper?   r   r9   rotateROTATE_90_COUNTERCLOCKWISEupdate_image_displaytransform_aois_for_rotationr>   criticalstrrQ   original_dtyperF   s      rG   rotate_image_leftz ImageAOIEditor.rotate_image_left~  s   ##+h0GH	(!55;;N,^,<IdF^F^FdFdEefg (+zz$2J2JCLjLj'kD$,T-E-E-K-K,LIVZVnVnVtVtUuvw %%' ,,S1 	(  x3HQ1QRN1#&''	(   CC/ /	D381D..D3c           	      l   | j                   t        j                  | dd       y	 | j                   j                  }t	        d| d| j                   j
                          t        j                  | j                   t        j                        | _         t	        d| j                   j                   d| j                   j
                          | j                          | j                  d       y# t        $ r;}t        j                  | dd	t        |              t	        d
|        Y d}~yd}~ww xY w)u   顺时针旋转图像90度Nr  r  r  r   r  Z   r  r  r  )r  r   r  r  r?   r   r9   r  ROTATE_90_CLOCKWISEr
  r  r>   r  r  r  s      rG   rotate_image_rightz!ImageAOIEditor.rotate_image_right  s   ##+h0GH	(!55;;N,^,<IdF^F^FdFdEefg (+zz$2J2JCLcLc'dD$,T-E-E-K-K,LIVZVnVnVtVtUuvw %%' ,,R0 	(  x3HQ1QRN1#&''	(r  c           	      P   | j                   t        j                  | dd       y	 | j                   j                  }t	        d| d| j                   j
                          t        j                  | j                   d      | _         t	        d| j                   j                   d| j                   j
                          | j                          | j                  d       y# t        $ r;}t        j                  | d	d
t        |              t	        d|        Y d}~yd}~ww xY w)u   水平翻转图像Nr     没有图像可翻转   翻转前: 数据类型=r   r      翻转后: 数据类型=
horizontalr     图像翻转失败:
   翻转错误: r  r   r  r  r?   r   r9   flipr
  transform_aois_for_flipr>   r  r  r  s      rG   flip_image_horizontalz$ImageAOIEditor.flip_image_horizontal  s   ##+h0GH	(!55;;N,^,<IdF^F^FdFdEefg (+xx0H0H!'LD$,T-E-E-K-K,LIVZVnVnVtVtUuvw %%' ((6 	(  x3HQ1QRN1#&''	(   B:C! !	D%*1D  D%c           	      P   | j                   t        j                  | dd       y	 | j                   j                  }t	        d| d| j                   j
                          t        j                  | j                   d      | _         t	        d| j                   j                   d| j                   j
                          | j                          | j                  d       y# t        $ r;}t        j                  | d	d
t        |              t	        d|        Y d}~yd}~ww xY w)u   垂直翻转图像Nr  r  r  r   r   r  verticalr  r  r  r  r  s      rG   flip_image_verticalz"ImageAOIEditor.flip_image_vertical  s   ##+h0GH	(!55;;N,^,<IdF^F^FdFdEefg (+xx0H0H!'LD$,T-E-E-K-K,LIVZVnVnVtVtUuvw %%' ((4 	(  x3HQ1QRN1#&''	(r!  c                 ^   | j                   y| j                   j                  dd \  }}||f| _        | j                  | j                         }t	        j
                  |t        j                        }|j                  \  }}}||z  }t        |j                  |||t        j                        }t        j                  |      }| j                  j                  |       | j                          | j                   j                  }	| j                   j!                         }
| j                   j#                         }| j$                  j'                  d| d| d|	 d|
dd|dd| j(                  r)t*        j,                  j/                  | j(                        nd	        | j1                          ~~y)
u   更新图像显示NrX      图像信息: r   , u
   , 范围:[z.2fz], u   未知)r  r   previous_image_sizenormalize_image_for_displayr9   cvtColorCOLOR_BGR2RGBr!   dataFormat_RGB888r    	fromImager  r  recreate_aoi_itemsr  r   r   label_image_infor   r  r  r  basenamefit_to_window)rQ   r   r   display_imageimg_rgbchbytes_per_lineqt_imager  r  min_valmax_vals               rG   r
  z#ImageAOIEditor.update_image_display  s   ##+ ''--bq11$%q6  889Q9QR ,,}c.?.?@==1ba',,1nf>R>RS""8, 	##F+ 	! 1177**..0**..0%%QCq2n%5Z}BwWZm[^<@<S<Srww 7 78Yabd	
 	 XrT   c                    | j                   syt        | d      r| j                  \  }}n3| j                  j                  dd \  }}t        |      dk(  r||}}n||}}| j                   D ]  }|d   |d   |d   |d   f\  }}}	}
|dk(  r||z
  |
z
  }|}|
|	}}n/|d	k(  r|}||z
  |	z
  }|
|	}}n|d
k(  r||z
  |	z
  }||z
  |
z
  }|	|
}}n]t        d|      |d<   t        d|      |d<   ||d<   ||d<    | j                          y)u!   根据旋转角度变换AOI坐标Nr(  rX   r  r   r   ru  rv  r     r   )r  r  r(  r  r   absr   update_aoi_tree)rQ   angleprev_hprev_wcurr_hcurr_waoir   r   r   r   new_xnew_ynew_wnew_hs                  rG   r  z*ImageAOIEditor.transform_aois_for_rotation  sG   }} 4./!55NFF "55;;BQ?NFF5zR!'!'==CS3s8S\3x=HJAq!Q{
Q !u#
Q !u#
Q
Q !u1e}CH1e}CH CL!CM+ !0 	rT   c                 :   | j                   sy| j                  j                  dd \  }}| j                   D ]S  }|d   |d   |d   |d   f\  }}}}|dk(  r||z
  |z
  }	t        d|	      |d<   7|d	k(  s=||z
  |z
  }
t        d|
      |d<   U | j	                          y)
u!   根据翻转类型变换AOI坐标NrX   r   r   ru  rv  r  r   r#  )r  r  r   r   r=  )rQ   	flip_typer   r   rC  r   r   ru  rv  rD  rE  s              rG   r  z&ImageAOIEditor.transform_aois_for_flip8  s    }}''--bq11==C"%c(CHc'lCM"QAq%L(Aq%=Cj(Aq%=C ! 	rT   c                 n   | j                   t        j                  | dd       yt        st        j                  | dd       yt	        | j                   j
                        dk(  r!| j                   }d}| j                  ||       yt        | j                   j
                  |       }|j                         t        j                  k(  ro|j                         }t	        | j                   j
                        dk(  r| j                   dddd|f   }d| }n| j                   }d}| j                  ||       yy)	u   显示3D深度图Nr  u   没有图像可显示u7   VTK未安装！
请运行命令安装：pip install vtkrX   rZ   r3   rY   )r  r   r  r   r`   r   display_depth_viewerrJ   exec_r   Acceptedrr   )rQ   r}   r~   channel_selectorrO   s        rG   show_depth_3dzImageAOIEditor.show_depth_3dN  s%   ##+h0GHhXZ t''--.!311J)L%%j,? +4+C+C+I+I4P!!#w'7'77/DDF 4++112a7!55a<L6LM
!()9(:;!55
-%%j,? 8rT   c           	      *   	 |j                   t        j                  k(  r |j                  t        j                        }n<|j                   t        j
                  k(  r|j                  t        j                        }t        j                  |      }t        |||       }|j                          t        | d      sg | _
        | j                  j                  |       y# t        $ r-}t        j                  | ddt        |              Y d}~yd}~ww xY w)u   显示VTK深度图查看器vtk_viewersr  u   创建3D深度图失败：
N)r  npuint8astypefloat32uint16ascontiguousarrayr{   showr  rQ  rY  r>   r   r  r  )rQ   r}   r~   
vtk_viewerrF   s        rG   rK  z#ImageAOIEditor.display_depth_viewero  s    	Z288+'..rzz:
!!RYY.'..rzz:
 --j9J (
L$GJOO 4/#% ##J/ 	Z  x3OPSTUPVx1XYY	Zs   CC 	D%#DDc                 ~   | j                   j                  j                  | j                         | j                  j                  j                  | j
                         | j                  j                  j                  | j                         | j                  j                  j                  | j                         | j                  j                  j                  | j                         | j                  j                  j                  | j                         | j                  j                  j                  | j                         | j                   j                  j                  | j"                         | j$                  j                  j                  | j&                         | j(                  j                  j                  | j*                         | j,                  j                  j                  | j.                         | j0                  j                  j                  | j2                         | j4                  j                  j                  | j6                         | j8                  j                  j                  | j:                         | j<                  j                  j                  | j>                         | j@                  jB                  j                  | jD                         | j@                  jF                  j                  | jH                         | j@                  jJ                  j                  | jL                         | j@                  jN                  j                  | jP                         | j@                  jR                  j                  | jT                         | jV                  jX                  j                  | jZ                         | jV                  j]                  t^        j`                         | jV                  jb                  j                  | jd                         | jf                  jh                  j                  | jj                         | jl                  jn                  j                  | jj                         | jp                  jn                  j                  | jj                         | jr                  jn                  j                  | jj                         | jt                  jn                  j                  | jj                         | jv                  jh                  j                  | jj                         | jx                  jz                  j                  | j                         | j|                  jz                  j                  | j                         | j~                  jz                  j                  | j                         | j                  jz                  j                  | j
                         | j                  jz                  j                  | j                         | j                  jz                  j                  | j                         | j                  jz                  j                  | j                         | j                  jz                  j                  | j"                         | j                  jz                  j                  | j&                         | j                  jz                  j                  | j*                         | j                  jz                  j                  | j.                         | j                  jz                  j                  | j2                         | j                  jz                  j                  | j6                         | j                  jz                  j                  | j                         | j                  jz                  j                  | j                         | j                  jz                  j                  | j                         y)u   设置信号和槽连接N)Pbtn_open_imagerf   rg   
open_imagebtn_add_aoiadd_aoibtn_delete_aoi
delete_aoibtn_clear_allclear_all_aoibtn_save_aoisave_aoi_databtn_load_aoiload_aoi_databtn_fit_to_windowr2  btn_actual_sizeactual_sizebtn_rotate_leftr  btn_rotate_rightr  btn_flip_horizontalr   btn_flip_verticalr$  btn_show_depthrO  	btn_colorchoose_colorbtn_apply_changesapply_changesr  r  on_aoi_createdr  on_aoi_selected_from_imager  on_aoi_data_changedr  on_mouse_movedr  on_scale_changedtree_aoi_listitemClickedon_aoi_selectedsetContextMenuPolicyr   CustomContextMenucustomContextMenuRequestedshow_aoi_context_menulineEdit_nametextChangedon_property_changed	spinBox_xr   	spinBox_yspinBox_widthspinBox_heighttextEdit_descriptionaction_open_image	triggeredaction_save_projectaction_load_projectaction_add_aoiaction_delete_aoiaction_clear_allaction_fit_to_windowaction_actual_sizeaction_rotate_leftaction_rotate_rightaction_flip_horizontalaction_flip_verticalaction_show_depthaction_about
show_aboutaction_exitcloseaction_save_image
save_imagerq   s    rG   r  z ImageAOIEditor.setup_connections  s    	##++DOO<  ((6##++DOO<""**4+=+=>!!))$*<*<=!!))$*<*<=&&..t/A/AB$$,,T-=-=>$$,,T-C-CD%%--d.E.EF  ((001K1KL&&..t/G/GH##++D,>,>?&&t'8'89&&..t/A/AB 	%%--d.A.AB&&..t/N/NO**2243K3KL%%--d.A.AB''//0E0EF 	&&..t/C/CD//0D0DE55==d>X>XY 	&&..t/G/GH##++D,D,DE##++D,D,DE''//0H0HI((001I1IJ!!--55d6N6NO 	((00A  **2243E3EF  **2243E3EF%%--dll;((00A''//0B0BC!!++33D4F4FG))11$2B2BC))11$2H2HI  **2243J3JK##--55d6P6PQ!!++33D4L4LM((001C1CD##++DOO<""**4::6((00ArT   c                     | j                   j                  ddg       | j                   j                  dd       | j                  j	                  d       d| _        | j                          y)u   初始化界面设置u   属性u   值r   x   FTN)rx  setHeaderLabelssetColumnWidthgroupBox_aoi_properties
setEnabledaoi_panel_visiblehide_aoi_panelrq   s    rG   rP   zImageAOIEditor.setup_ui  s_     	**He+<=))!S1 	$$//6 "&rT   c                      j                   syt         d      r j                  j                          g d}|D ]9  }t         |      st	         |      }t        |d      s)|j                           n t         fd|D              s4g d}|D ]+  }t         |      st	         |      }|j                          - g d}|D ]+  }t         |      st	         |      }	|	j                          - d _         y)	u   隐藏右侧AOI管理面板Nframe_aoi_panelwidget_toolbarframe_toolbartoolBarhorizontalLayout_toolbarhidec              3   6   K   | ]  }t        |        y wrs   r  .0r  rQ   s     rG   	<genexpr>z0ImageAOIEditor.hide_aoi_panel.<locals>.<genexpr>       F3E474&3E   r[  r]  r_  ra  rc  re  rg  rh  widget_right_panelframe_right_panelwidget_aoi_managementframe_aoi_managementgroupBox_aoi_listr  F)r  r  r  r  getattrany
rQ   toolbar_componentstoolbar_nametoolbar_widgettoolbar_buttonsbutton_namer  panel_componentscomponent_name	components
   `         rG   r  zImageAOIEditor.hide_aoi_panel  s    %% 4*+  %%'

 /Lt\*!(|!<>62"'') / F3EFFO  /4-$T;7FKKM  /
 /Nt^,#D.9	  /
 "'rT   c                      j                   ryt         d      r j                  j                          g d}|D ]9  }t         |      st	         |      }t        |d      s)|j                           n t         fd|D              s4g d}|D ]+  }t         |      st	         |      }|j                          - g d}|D ]+  }t         |      st	         |      }	|	j                          - d _         y)	u   显示右侧AOI管理面板Nr  r  rX  c              3   6   K   | ]  }t        |        y wrs   r  r  s     rG   r  z0ImageAOIEditor.show_aoi_panel.<locals>.<genexpr>  r  r  r  r  T)r  r  r  rX  r  r  r  s
   `         rG   show_aoi_panelzImageAOIEditor.show_aoi_panel  s    !! 4*+  %%'

 /Lt\*!(|!<>62"'') / F3EFFO  /4-$T;7FKKM  /
 /Nt^,#D.9	  /
 "&rT   c                 ^    | j                   r| j                          y| j                          y)u+   切换AOI管理面板的显示/隐藏状态N)r  r  r  rq   s    rG   r  zImageAOIEditor.toggle_aoi_panel9  s#    !!!!rT   c           	      (   t        j                  | d dd      \  }}|r<	 | j                  t        j                  | dd       yt        | j                  |       yy# t        $ r-}t        j                  | ddt        |              Y d}~yd}~ww xY w)u   保存图像文件r  3Image Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif)Nr     没有图像可保存r     无法打开图像文件:
)	r
   getSaveFileNamer  r   r  rH   r>   r  r  )rQ   rA   _rF   s       rG   r  zImageAOIEditor.save_image@  s    "22&EG	1 ]++3''h8OP'(@(@)L   ]$$T87RSVWXSYRZ5[\\]s   #A A 	B$#BBc           	      2   t        j                  | d dd      \  }}|r@	 | j                          t        j                  |t        j
                        }|j                         j                  d      d   }d}|dv r[t        j                  |t        j                  t        j                  z        }t        d|j                   d	|j                          nIt        j                  |t        j                        }t        d
|j                   d	|j                          |t!        d      | j#                  |t$        j&                  j)                  |             yy# t*        $ r-}t-        j.                  | ddt1        |              Y d}~yd}~ww xY w)   打开图像文件r  r  r  r,   r-   N)exrhdrr6   r5   zLoaded ex image with shape: z	, dtype: zLoaded image with shape:    无法读取图像文件)window_titler  r  )r
   getOpenFileNamecleanup_image_resourcesrR  fromfilerS  r7   r8   r9   imdecodeIMREAD_ANYDEPTHIMREAD_ANYCOLORr?   r   r  IMREAD_COLOR
ValueErroropen_image_cvr  r  r1  r>   r   r  r  )rQ   rA   r  img_datarB   imgrF   s          rG   r\  zImageAOIEditor.open_imageO  se   "22&EG	1 8],,. ;;yA  oo'--c22677,,x1D1DsGZGZ1Z[C89SYYKXY ,,x1A1ABC5cii[	#))UV ;$%?@@""3RWW5E5Ei5P"Q1 p  ]$$T87RSVWXSYRZ5[\\]s   D>E   	F)#FFc           
         	 	 | j                          |}|t        d      || _        | j                  |      }|j                  dd \  }}||f| _        t        j                  |t        j                        }|j                  \  }}}||z  }t        |j                  |||t        j                        }	t        j                  |	      }
~~	| j                  j                  |
       t         | _        | j$                  j'                  d| d| dt(        j*                  j-                  t                       | j/                          y# t0        $ r
}Y d}~yd}~ww xY w)r  Nr  rX   r&  r   r'  )r  r  r  r)  r   r(  r9   r*  r+  r!   r,  r-  r    r.  r  r  rA   r  r0  r   r  r  r1  r2  r>   )rQ   cv_imager  r  r   r   r4  r5  r6  r7  r  rF   s               rG   r  zImageAOIEditor.open_image_cv  sQ    .,,.
 ;$%?@@ ,/(66s; yy!}1,-q6( ,,sC,=,=>"==1b!#a!',,1n!'!5!57 **84 X !!++F3*3' %%--$QCq2bgg.>.>y.I-JKM ""$   s   EE 	EEc                    t        | d      r| j                  d| _        t        | d      r| j                  r| j                  j                  rd| j                  _        | j                  j                  rK| j                  j
                  j                  | j                  j                         d| j                  _        yyyy)u   清理图像相关资源r  Nr  )r  r  r  r  r  r  r  rq   s    rG   r  z&ImageAOIEditor.cleanup_image_resources  s     4./D4L4L4X'+D$ 4(T->->  0048!!1  ++!!''2243D3D3O3OP/3!!, , .?(rT   c                     | j                   st        j                  | dd       y| j                  s| j	                          | j
                  j                          y)u   添加AOI区域r  u   请先打开一张图像N)r  r   r  r  r  r  r  rq   s    rG   r^  zImageAOIEditor.add_aoi  sJ    &&h0JK %%!,,.rT   c                 $   | j                   j                  |       | j                  s| j                          | j	                          t        | j                  j                               D ]  }| j                  j                  |      }|j                  d      |d   k(  s6|j                  d       | j                  j                  |       || _        d| _        | j                  |       d| _        | j                  j!                  d        y y)u   AOI创建完成的处理r   r  TFN)r  rY  r  r  r=  ra   rx  topLevelItemCounttopLevelItemtextsetExpandedsetCurrentItemr  r  load_aoi_propertiesr  r  )rQ   r3  rm   r  s       rG   rs  zImageAOIEditor.on_aoi_created  s    X& %%! t));;=>A%%2215Dyy|x//  &""11$7 $, +/(((2+0(,,77= ?rT   c                     | j                          | j                  rN| j                  j                  d      |j                  d      k(  r d| _        | j	                  |       d| _        yyy)u?   处理AOI数据变化（拖动、调整大小时实时更新）r  TFN)r=  r  r  r  r  )rQ   r3  s     rG   ru  z"ImageAOIEditor.on_aoi_data_changed  sf     	   $$T*hll4.@@'+D$$$X.',D$	 A rT   c           	          t               }t        | j                  j                               D ]N  }| j                  j	                  |      }|j                         s/|j                  |j                  d             P d}| j                  j                         }|rB|j                         r!|j                         }|j                         r!|j                  d      }| j                  j                          | j                  D ]  }t        |d   dg      }t        d|d   g      }t        dd|d    d	|d
    dg      }	t        d|d    d|d    g      }
t        d|d   g      }t        d|d   g      }|j                  ||	|
||g       |j                  dt        j                   |       | j                  j#                  |       |d   |v r|j%                  d       |s|d   |k(  s| j                  j'                  |       	 y)u   更新AOI树形列表r   Nr  r  u   名称u   位置(r   r'  r   )u   大小ru   x rv  u   颜色r1  u   描述r  T)setra   rx  r  r  
isExpandedaddr  currentItemrR   r  r  r   addChildrensetDatar   UserRoleaddTopLevelItemr  r  )rQ   expanded_itemsrm   r  current_selectedcurrent_itemrC  r  	name_itemposition_item	size_item
color_item	desc_items                rG   r=  zImageAOIEditor.update_aoi_tree  s    t));;=>A%%2215D ""499Q<0 ?  ))557%%'+224 %%'+003  "==C&FR'89H (3v;(?@I+X3s8*Bs3xjPQ7R,STM'c'l^3s8}o3V(WXI((CL)ABJ'3}3E(FGI  )]I!+Y"8 9 QS1..x8 6{n,$$T*  CK3C$C""11(;1 !rT   c                 >   t        | j                  j                               D ]  }| j                  j                  |      }|j	                  dt
        j                        }|sA|j                  d      |j                  d      k(  se| j                  j                  d       | j                  j                  |       | j                  j                  d       || _
        d| _        | j                  |       d| _        | j                  j                  d        y y)u$   处理从图像中选中AOI的事件r   r  TFN)ra   rx  r  r  r,  r   r  r  blockSignalsr  r  r  r  r  r  )rQ   r3  rm   r  item_aoi_datas        rG   rt  z)ImageAOIEditor.on_aoi_selected_from_image6  s     t));;=>A%%2215D IIa5M!2!24!8HLL<N!N""//5""11$7""//6 $, +/(((2+0(,,77= ?rT   c                 ,   |j                         r!|j                         }|j                         r!|j                  dt        j                        }|r|| _        d| _        | j                  |       d| _        | j                  j                  d       | j                  j                  D ]f  }|j                  j                  d      |j                  d      k(  s1| j                  j                  j                          |j                  d        y yy)u*   AOI选择事件处理（从树形列表）r   TFr  N)rR   r,  r   r  r  r  r  r  r  r  r  r3  r  r  clearSelectionsetSelected)rQ   r  r3  r  s       rG   rz  zImageAOIEditor.on_aoi_selectedJ  s     kkm;;=D kkm 99Q,'D'+D$$$X.',D$((33D9 !--77$$((.(,,t2DD%%++::<((. 8 rT   c                 j   | j                   j                  |j                  dd             | j                  j	                  |j                  dd             | j
                  j	                  |j                  dd             | j                  j	                  |j                  dd             | j                  j	                  |j                  dd             | j                  j                  |j                  d	d             |j                  d
d      }| j                  j                  d| d       y)u   加载AOI属性到编辑区域r  r  r   r   r   ru  r   rv  r  r1  r2  background-color: ;N)r  r   r  r  r   r  r  r  r  setPlainTextro  setStyleSheet)rQ   r3  r1  s      rG   r  z"ImageAOIEditor.load_aoi_propertiesa  s    ""8<<#;<S! 45S! 45##HLL#$>?$$X\\(C%@A!!..x||M2/NO We,$$'9%%BCrT   c                    | j                   ry| j                         }|| j                  k(  ryt        | d      r| j                  j                          ddlm}  |       | _        | j                  j                  d       | j                  j                  j                  | j                         | j                  j                  d       y)u   属性变化处理Nproperty_update_timerr   )QTimerTi  )r  senderr  r  r  stopPyQt5.QtCorer  setSingleShottimeoutrg   rr  start)rQ   r  r  s      rG   r  z"ImageAOIEditor.on_property_changedn  s     ## T'''401&&++- 	(%+X"""006""**2243E3EF""((-rT   c                    | j                   syd| _        | j                   j                  dd      }| j                  j	                         | j                   d<   | j
                  j                         | j                   d<   | j                  j                         | j                   d<   | j                  j                         | j                   d<   | j                  j                         | j                   d<   | j                  j                         }|| j                   d	<   | j                  j                  D ]V  }|j                  j                  d
      | j                   j                  d
      k(  s<|j                  | j                   d   | j                   d          | j                   d   }| j                   d   }|j!                  dd||       t#        | j                   j                  dd            }t%        dd|j&                  z        }|j)                  t+        ||             |j-                  t/        |t0        j2                               |j5                  | j                   j                  dd             |j7                           n | j9                          || j                   j                  dd      k7  r*| j;                  | j                   j                  d
             d| _        y)u   应用属性更改NTr  r  r   r   ru  rv  r  r  r   r1  r2  r   rA  F)r  r  r  r  r  r  r   r  r  r  r  toPlainTextr  r  r3  r  r]  r$   r   r4  rC  r"   r<  r#   r   r=  r  r`  r=  select_aoi_by_id)rQ   old_namer  r  ru  rv  r1  rF  s           rG   rr  zImageAOIEditor.apply_changes  ss    $(  ##''3 $(#5#5#:#:#<  $ 4 4 6 $ 4 4 6$($6$6$<$<$>!%)%8%8%>%>%@"//;;=*5' ))33H  $$T*d.>.>.B.B4.HH 0 0 5t7G7G7LM((1))(3  Auf5 t//33GUCDS8+@+@%@A	UI 67!!&

";< ##D$4$4$8$8$DE '')' 4, 	 t''++FB77!!$"2"2"6"6t"<=
 $) rT   c                 2   t        | j                  j                               D ]q  }| j                  j                  |      }|j	                  dt
        j                        }|sA|j                  d      |k(  sV| j                  j                  |        y y)u-   根据AOI ID选中树形列表中对应的项r   r  N)	ra   rx  r  r  r,  r   r  r  r  )rQ   aoi_idrm   r  r3  s        rG   r  zImageAOIEditor.select_aoi_by_id  st    t));;=>A%%2215DyyBKK0HHLL.&8""11$7 ?rT   c                    | j                   syt        | j                   j                  dd            }t        j                  || d      }|j                         r|j                         }|| j                   d<   | j                  j                  d| d       | j                  j                  D ]L  }|j                  j                  d      | j                   j                  d      k(  s;|j                  |        n | j                          yy)u   选择颜色Nr1  r2  u   选择AOI颜色r  r  r  )r  r$   r  r   getColorisValidr  ro  r
  r  r  r3  rL  r=  )rQ   current_colorr1  rK  r  s        rG   rp  zImageAOIEditor.choose_color  s    t//33GUCD%%mT;LM==?J(2DW%NN((+=j\)KL !--77$$((.$2B2B2F2Ft2LL))*5 8   " rT   c                    | j                   s| j                          | j                  j                         }|st	        j
                  | dd       y|j                         r!|j                         }|j                         r!|j                  dt        j                        }|r(t	        j                  | dd|d    dt        j                  t        j                  z  t        j                        }|t        j                  k(  r| j                  j                  |       | j                  j                   dd D ]]  }|j"                  |k(  s| j                  j$                  j'                  |       | j                  j                   j                  |        n | j)                          | j*                  j-                  d	       d| _        yyy)
u   删除选中的AOIr  u   请先选择一个AOINr   u   确认删除u   确定要删除AOI "r  u   " 吗？F)r  r  rx  r  r   r  rR   r,  r   r  questionYesNor  remover  r  r3  r  r  r=  r  r  r  )rQ   r  r3  replyr  s        rG   r`  zImageAOIEditor.delete_aoi  s}    %%!))557h0GH !!#'..0L !!#  $$Q4((n&x'7&8A+..0	 E '$$X. !--77:D}}0))//::4@))33::4@	 ; $$&,,77>#'  ( rT   c                 Z   | j                   syt        j                  | ddt        j                  t        j                  z  t        j                        }|t        j                  k(  r| j                   j                          | j                  j                  dd D ]'  }| j                  j                  j                  |       ) | j                  j                  j                          | j                          | j                  j                  d       d| _        d| j                  _        yy)u   清空所有AOINu   确认清空u   确定要清空所有AOI吗？Fr   )r  r   r  r   r!  r  r  r  r  r  r=  r  r  r  r  )rQ   r#  r  s      rG   rb  zImageAOIEditor.clear_all_aoi  s    }}$$."BOOknn,NN
 KOO#MM! ))33A6!!''2248 7''--/   "((33E:#D,-D) $rT   c           	         | j                   st        j                  | dd       yt        j                  | ddd      \  }}|r	 t
        j                  j                  t
        j                  j                  |            d   t        d      j                  j                         j                  d	      d
d| j                  t        | j                         | j                   d}t        |dd      5 }t!        j"                  ||dd       ddd       yy# 1 sw Y   yxY w# t$        $ r-}t        j&                  | ddt)        |              Y d}~yd}~ww xY w)u   保存AOI数据到文件r  u   没有AOI数据可保存Nu   保存AOI项目r  JSON Files (*.json)r   datetimez%Y-%m-%d %H:%M:%Sz1.0)r  created_timeversion)project_info
image_path	aoi_countr  r   utf-8encodingFrX   )ensure_asciiindentr  u   保存失败:
)r  r   r  r
   r  r  r  splitextr1  
__import__r'  nowstrftimer  r`   openjsondumpr>   r  r  )rQ   rA   r  project_datafrF   s         rG   rd  zImageAOIEditor.save_aoi_data  s,   }}h0JK"22#%'	1 Q !# 0 01A1A)1L Ma P(2:(>(G(G(K(K(M(01D(E#(	% #'"9"9!$T]]!3 $
  )S7;qIIlAE!L <;  <;  Q$$T8s1vh5OPPQs7   B-D  0D
D  DD  D   	E)#EEc           
         t        j                  | ddd      \  }}|r	 t        |dd      5 }t        j                  |      }ddd       j                  dg       | _        | j                  r0t        d	 | j                  D              }|d
z   | j                  _	        | j                          | j                  r | j                          | j                          t        | j                        }t        j                   | dd| dt"        j$                  j'                  |              yy# 1 sw Y   xY w# t(        $ r-}t        j*                  | ddt-        |              Y d}~yd}~ww xY w)u<   从文件加载AOI数据（仅加载AOI，不加载图像）u   加载AOI数据r  r&  r  r-  r.  Nr  c              3   @   K   | ]  }|j                  d d        yw)r  r   N)r  )r  rC  s     rG   r  z/ImageAOIEditor.load_aoi_data.<locals>.<genexpr>P  s      K]cq!1]s   r   u   加载成功u
   已加载 u    个AOI区域
文件: r  u   加载AOI数据失败:
)r
   r  r6  r7  loadr  r  r   r  r  r=  r  r/  r2  r`   r   informationr  r  r1  r>   r  r  )rQ   rA   r  r:  r9  max_idr,  rF   s           rG   rf  zImageAOIEditor.load_aoi_data@  sP   "22#%'	1 Z)S7;q#'99Q<L < !- 0 0R @ ==  KT]] KKF4:QJD%%1 $$& **++-&&(  .	''n&0 <//1ww/?/?	/J.K%MN1 ;;4  Z$$T87OPSTUPVx5XYYZs/   D8 D,C&D8 ,D51D8 8	E.#E))E.c                 z   | j                   j                  dd D ]'  }| j                   j                  j                  |       ) | j                   j                  j	                          | j
                  D ]  }t        dd|d   |d         }t        ||| j                   j                  | j                         }|j                  |d   |d          |j                  |j                  dd             | j                   j                  j                  |       | j                   j                  j                  |        y)	u   重新创建AOI图形项Nr   ru  rv  r   r   r  r  )r  r  r  r  r  r  r   r.  r4  r  r  r  rb   rY  )rQ   r  r3  r?  r  s        rG   r/  z!ImageAOIEditor.recreate_aoi_itemse  s    %%//2D##..t4 3##))+ H!Q 18H3EFD(h 1 1 > >!!#H OOHSM8C=9 VR 89##++H5''..x8 &rT   c                 8    | j                   j                          y)u   适应窗口大小N)r  r  rq   s    rG   r2  zImageAOIEditor.fit_to_windowz  s    %%'rT   c                 8    | j                   j                          y)u   实际大小显示N)r  r  rq   s    rG   ri  zImageAOIEditor.actual_size~  s    ((*rT   c                    d| d| d}t        | d      r| j                  	 | j                  j                  dd \  }}d|cxk  r|k  rpn nmd|cxk  r|k  rbn n_t        | j                  j                        dk(  r"| j                  ||f   \  }}}d	| d| d| d}	n| j                  ||f   }
d
|
 }	||	z  }| j                  j                  |       y# t        t
        f$ r Y -w xY w)u   鼠标移动处理u   鼠标位置: (r'  r  r  NrX   r   r3   z	 | RGB: (u    | 灰度: )r  r  r   r`   
IndexErrorr  label_mouse_posr   )rQ   r   r   position_textr   r   r  gr  
pixel_text
gray_values              rG   rv  zImageAOIEditor.on_mouse_moved  s   )!Bqc3 D/0((4//55bq91:A:!q*1*43399:a?"&":":1a4"@1a'02aS1#Q%?
 &*%=%=ad%C
'2:,%?
!Z/M 	$$]3 
+ s   BC C('C(c                 Z    t        | d      r| j                  j                  | d       yy)u   缩放变化处理label_zoom_value%N)r  rK  r   )rQ   scale_percents     rG   rw  zImageAOIEditor.on_scale_changed  s-    4+,!!))]O1*=> -rT   c                      j                   j                  |      }|y|j                         r!|j                         }|j                         r!|j                  dt        j
                        syddlm}  |       }|j                  d      }|j                  j                   fd       |j                   j                   j                  |             y)u   显示AOI右键菜单Nr   )QMenuu   保存AOI区域图片c                  &    j                         S rs   )save_aoi_image)r3  rQ   s   rG   <lambda>z6ImageAOIEditor.show_aoi_context_menu.<locals>.<lambda>  s    8K8KH8UrT   )rx  itemAtrR   r,  r   r  r  rO  	addActionr  rg   rL  mapToGlobal)rQ   positionr  rO  context_menusave_aoi_image_actionr3  s   `     @rG   r~  z$ImageAOIEditor.show_aoi_context_menu  s    !!((2< kkm;;=D kkm 99Q, 	*T{ !- 6 67N O''//0UV 	4--99(CDrT   c                    | j                   t        j                  | dd       y|d   }|d   }|d   }|d   }|d   }| j                   j                  dd	 \  }}|d
k  s|d
k  s||z   |kD  s||z   |kD  r*t        j                  | dd| d| d| d| d| d|        y	 | j                   |||z   |||z   f   }	|	j                  d
k(  rt        j                  | dd       y| j
                  r?t        j                  j                  | j
                        d   j                         }
|
sd}
nd}
| d|
 }t        j                  | d| |d      \  }}|rAt        |	|      }|rt        j                  | dd|        yt        j                  | dd       yy# t        $ r-}t        j                  | ddt!        |              Y d}~yd}~ww xY w)u   保存AOI区域的图片Nr  r  r   r   ru  rv  r  rX   r   u"   AOI区域超出图像边界
AOI: (r'  u   )
图像尺寸: r  u   AOI区域为空r   r1   _AOIu   保存AOI区域图片 - zImage Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif);;PNG Files (*.png);;JPEG Files (*.jpg *.jpeg);;BMP Files (*.bmp);;TIFF Files (*.tiff *.tif)u   成功u   AOI区域图片已保存到:
r  u   保存AOI区域图片失败u   保存AOI区域图片失败:
)r  r   r  r   sizer  r  r  r2  r7   r
   r  rH   r>  r  r>   r  )rQ   r3  r   r   ru  rv  aoi_name
img_height	img_width	aoi_imageoriginal_extdefault_filenamerA   selected_filterrD   rF   s                   rG   rQ  zImageAOIEditor.save_aoi_image  s3   ##+h0GH SMSM!(#F# !% 8 8 > >r B
IEQUa%i)3q6zJ7Nh!''(cA3br& B//8kZLJK '	\001V8QqwY1FGI~~"##D(4EF &&!ww//0G0GHKQQS##)L% #+4~> *5)D)D0
; ,*-&I 1)YG++D(,J9+*VX  ((x9VW   	\  x3QRUVWRXQY1Z[[	\s&   AF !BF >F 	G #GGc                 2    t        j                  | dd       y)u   显示关于对话框u   关于u   图像AOI编辑器 v1.0

功能特点:
• 支持多种图像格式
• 可缩放查看图像
• 创建和编辑AOI区域
• 拖拽和调整AOI大小
• 保存和加载项目文件

使用OpenCV和PyQt5开发N)r   aboutrq   s    rG   r  zImageAOIEditor.show_about  s    ()		*rT   returnc                 
   g }t        | j                  j                               D ]Z  }| j                  j                  |      }|j	                  dt
        j                        }|sA|j                  t        |             \ |S )u   
        从AOI树中提取所有AOI数据，返回List[Dict]格式
        
        Returns:
            List[Dict]: AOI数据列表
        r   )	ra   rx  r  r  r,  r   r  rY  r  )rQ   r  rm   top_itemr3  s        rG   get_aoi_list_from_treez%ImageAOIEditor.get_aoi_list_from_tree  sm      t));;=>A))66q9H}}Q4HX/ ? rT   c                    |y|j                   }|t        j                  k(  r|j                         S t	        |j
                        dk(  rt        j                  |d      }t        j                  |d      }||kD  rat        j                  |j                  t        j                        ||      }||z
  ||z
  z  dz  j                  t        j                        }|S t        j                  |t        j                        }|S t	        |j
                        dk(  rg }|j
                  \  }}	}
t        |
      D ]  }|dddd|f   }t        j                  |d      }t        j                  |d      }||kD  r`t        j                  |j                  t        j                        ||      }||z
  ||z
  z  dz  j                  t        j                        }n%t        j                  |t        j                        }|j                  |        t        j                  |d      }|S t        j                  |d	      }t        j                  |d
      }||kD  rat        j                  |j                  t        j                        ||      }||z
  ||z
  z  dz  j                  t        j                        }|S t        j                  |t        j                        }|S )u   
        将图像标准化为适合显示的格式
        
        Args:
            image: 输入图像，任意数据类型
            
        Returns:
            numpy.ndarray: uint8格式的图像，像素值范围0-255
        NrX   g?gX@g     o@r  r3   )axisr   c   )r  rR  rS  r  r`   r   
percentilecliprT  float64
zeros_likera   rY  stack)rQ   r@   r  p1p99clipped_imager  channelsrv  ru  num_channelscchannelclipped_channelnormalized_channels                  rG   r)  z*ImageAOIEditor.normalize_image_for_display  sv    =  BHH::< u{{q ud+B--u-C Rx "RZZ(@"c J,r1cBh?%GOOPRPXPXY
h c  ]]5A
b [ "H*/++'FE< <(1a. ]]7D1mmGU3 8&(gggnnRZZ.H"c&RO+:R+?C"H*MPU*U)])]^`^f^f)g& *,wbhh)O&  23% )* (3J"  ua(B--r*CRx "RZZ(@"c J,r1cBh?%GOOPRPXPXY

   ]]5A
 rT   )u   图像显示)5rt   ru   rv   rw   rM   r  r  r  r  r   r$  r
  r  r  rO  rK  r  rP   r  r  r  r  r\  r  r  r^  rs  ru  r=  rt  rz  r  r  rr  r  rp  r`  rb  rd  rf  r/  r2  ri  rv  rw  r~  rQ  r  r   r   rh  r)  rx   ry   s   @rG   r  r  7  s   %B
<(4(4(4(4&P(T,@BZ48Br 0'f0&h"]?]B3j4
/6-,<\(.D..4)l#.%(R.4 QD#ZJ9*(+46?
E2>\@*T
 (SrT   r  c            	         t        t        j                        } t        j                  j                  t        j                  j                  t              d      }t        j                  j                  |      st        j                  ddd| d       y	 t               }|j                          t        d       t        d       t        d       t        d	       t        d
       t        d       t        d       t        d       t        d       t        j                  | j                                y# t         $ r-}t        j                  dddt#        |              Y d}~yd}~ww xY w)u	   主函数r  Nr  u   找不到UI文件: u5   
请确保image_aoi_editor.ui文件在同一目录下u!   图像AOI编辑器启动成功！u   功能说明:u#   1. 点击'打开图片'加载图像u&   2. 点击'添加AOI'进入创建模式u$   3. 在图像上拖拽创建AOI区域u$   4. 在右侧树形列表中管理AOIu!   5. 可以拖拽、缩放AOI区域u0   6. 按F2键切换AOI管理面板的显示/隐藏u*   7. AOI操作时会自动显示管理面板u   启动错误u   程序启动失败:
)r   sysargvr  r  r  r  r  existsr   r  r  rX  r?   exitrL  r>   r  )appr  windowrF   s       rG   mainr  p  s   
sxx
 C ggll277??846KLG77>>'"T80	 :R R	S 	U!12o3467454512@A:; UT>5J3q6(3STTUs   B D8 8	E.#E))E.__main__)Brw   r{  r  r7  typingr   r   r   r   r9   numpyrR  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!   r"   r#   r$   r%   r&   r'   r(   PyQt5r)   r   !vtk.qt.QVTKRenderWindowInteractorr*   r   ImportErrorr?   rH   rJ   r{   r   r.  r  r  r  rt    rT   rG   <module>r     s	  
  	  . . 
 0 0 0 0 0 0 B A< < < DLM(V11g 11hC3W C3L.-$ .-bqH) qHhJ)- J)Zw[ wr)U@ zF gC  DM	
BCDs   :C C.-C.