§
    Šõ¬j™=  ã                  óò   — d Z ddlmZ ddlZddlmZmZmZ ddlZ		 ddl
mZmZ n# e$ r dZY nw xY w	 ddlZn# e$ r dZY nw xY wddlmZmZmZmZmZ d&d„Z	 	 d'd(d„Zd)d„Z	 d*d+d„Zd,d„Z	 	 d-d.d#„Zd/d%„ZdS )0u7  AutoPOE2 - Bá»™ Lá»�c Quang Há»�c & Nháº­n Diá»‡n NÃ¢ng Cao (Vision Filters & Robust Matching).

Cung cáº¥p cÃ¡c thuáº­t toÃ¡n xá»­ lÃ½ áº£nh nÃ¢ng cao khÃ¡ng nhiá»…u Ã¡nh sÃ¡ng vÃ  Ä‘á»™ phÃ¢n giáº£i:
- Dual-Pass CLAHE (Contrast Limited Adaptive Histogram Equalization) thuáº§n NumPy.
- Sobel Gradient & Edge Magnitude cho trÃ­ch xuáº¥t biÃªn Ä‘áº·c trÆ°ng.
- Multi-Scale Normalized Cross-Correlation (NCC) Template Matching cho nÃºt TRAVERSE.
- Nháº­n diá»‡n tráº¡ng thÃ¡i Atlas UI vÃ  nÃºt TRAVERSE vá»›i Ä‘á»™ chÃ­nh xÃ¡c tuyá»‡t Ä‘á»‘i, khÃ¡ng bloom Ã¡nh sÃ¡ng.
é    )ÚannotationsN)ÚOptionalÚTupleÚUnion)ÚImageÚImageOps)ÚCoordinateScalerÚ
ResolutionÚScalingModeÚ	RES_1440PÚget_traverse_button_posÚ	img_inputúUnion[str, Image.Image]ÚreturnúOptional[Image.Image]c                ó8  — | €dS t          | t          ¦  «        rZt          j                             | ¦  «        sdS 	 t          j        | ¦  «                             d¦  «        S # t          $ r Y dS w xY w	 |                      d¦  «        S # t          $ r | cY S w xY w)uB   Chuyá»ƒn Ä‘á»•i Ä‘Æ°á»�ng dáº«n hoáº·c PIL Image thÃ nh RGB Image.NÚRGB)	Ú
isinstanceÚstrÚosÚpathÚexistsr   ÚopenÚconvertÚ	Exception)r   s    ú1C:\Projects\AutoPOE2\src\common\vision_filters.pyÚ	_load_pilr   $   s¿   € àÐØˆtÝ�)�SÑ!Ô!ð ÝŒw�~Š~˜iÑ(Ô(ð 	Ø�4ð	Ý”:˜iÑ(Ô(×0Ò0°Ñ7Ô7Ð7øÝð 	ð 	ð 	Ø�4�4ð	øøøðØ× Ò  Ñ'Ô'Ð'øÝð ð ð ØÐÐÐðøøøs#   ¼&A# Á#
A1Á0A1Á5B
 Â
BÂB©é   r   ç      @Úimg_grayú
np.ndarrayÚ	grid_sizeúTuple[int, int]Ú
clip_limitÚfloatc                óN	  — | j         \  }}|\  }}t          d||z  ¦  «        }t          d||z  ¦  «        }|dk     s|dk     rôt          j        |                      ¦   «         dddg¦  «        \  }	}
|||z  dz  z  }t          j        t          j        |	|z
  d¦  «        ¦  «        }t          j        |	|¦  «        |dz  z   }|                     ¦   «         }| 	                    ¦   «         }|                     ¦   «         }||k    r3||z
  dz  ||z
  z   
                    t          j        ¦  «        }||          S | S t          j        ||dft          j        ¬¦  «        }|||z  dz  z  }t          |¦  «        D �]9}t          |¦  «        D �]%}||z  }||dz
  k     r|dz   |z  n|}||z  }||dz
  k     r|dz   |z  n|}| ||…||…f         }t          j        |                     ¦   «         dddg¦  «        \  }	}
t          j        t          j        |	|z
  d¦  «        ¦  «        }t          j        |	|¦  «        |dz  z   }|                     ¦   «         }| 	                    ¦   «         }|                     ¦   «         }||k    r||z
  dz  ||z
  z  |||f<   �Œ
t          j        ddd¦  «        |||f<   �Œ'�Œ;t          j        |¦  «        }t          j        |¦  «        }||d	z  z
  t#          |¦  «        z  }t          j        |¦  «         
                    t&          ¦  «        }|dz   }||z
  d
d
…d
f         } t          j        |d|dz
  ¦  «        }!t          j        |d|dz
  ¦  «        }"||d	z  z
  t#          |¦  «        z  }#t          j        |#¦  «         
                    t&          ¦  «        }$|$dz   }%|#|$z
  d
d
d
…f         }&t          j        |$d|dz
  ¦  «        }'t          j        |%d|dz
  ¦  «        }(t          j        |!|'d¬¦  «        \  })}*t          j        |"|(d¬¦  «        \  }+},||)|*| f         }-||)|,| f         }.||+|*| f         }/||+|,| f         }0d|&z
  |-z  |&|.z  z   }1d|&z
  |/z  |&|0z  z   }2d| z
  |1z  | |2z  z   }3t          j        |3dd¦  «         
                    t          j        ¦  «        S )uý  CÃ¢n báº±ng biá»ƒu Ä‘á»“ táº§n suáº¥t thÃ­ch á»©ng giá»›i háº¡n tÆ°Æ¡ng pháº£n (CLAHE) thuáº§n NumPy.

    Triá»‡t tiÃªu hiá»‡u á»©ng bloom Ã¡nh sÃ¡ng cam/vÃ ng tá»« lÃ² Map Device vÃ  tÄƒng cÆ°á»�ng Ä‘á»™ tÆ°Æ¡ng pháº£n chá»¯.
    @param img_gray: Máº£ng 2D uint8 (H, W).
    @param grid_size: Sá»‘ Ã´ lÆ°á»›i chia áº£nh (tiles_y, tiles_x).
    @param clip_limit: Há»‡ sá»‘ giá»›i háº¡n Ä‘á»‰nh histogram chá»‘ng khuáº¿ch Ä‘áº¡i nhiá»…u.
    @return: Máº£ng 2D uint8 Ä‘Ã£ cÃ¢n báº±ng sÃ¡ng thÃ­ch á»©ng.
    é   é   é   r   g      p@ç     ào@)Údtypeéÿ   g      à?NÚij)Úindexingg      ð?)ÚshapeÚmaxÚnpÚ	histogramÚflattenÚsumÚmaximumÚminimumÚcumsumÚminÚastypeÚuint8ÚzerosÚfloat32ÚrangeÚlinspaceÚaranger&   ÚfloorÚintÚclipÚmeshgrid)4r!   r#   r%   ÚhÚwÚtiles_yÚtiles_xÚtile_hÚtile_wÚhistÚ_Úclip_valÚexcessÚclipped_histÚcdfÚcdf_minÚcdf_maxÚcdf_normÚcdfsÚtyÚtxÚy_startÚy_endÚx_startÚx_endÚtileÚclippedÚy_coordsÚx_coordsÚty_fÚty0Úty1ÚayÚty0_cÚty1_cÚtx_fÚtx0Útx1ÚaxÚtx0_cÚtx1_cÚTY0ÚTX0ÚTY1ÚTX1Úc00Úc01Úc10Úc11ÚtopÚbotÚouts4                                                       r   Úapply_clahe_fastrv   5   sÈ  € ð Œ>�D€A€qØ Ñ€GˆWÝ��A˜‘LÑ!Ô!€FÝ��A˜‘LÑ!Ô!€Fà�‚z€z�V˜a’Z�Zå”,˜x×/Ò/Ñ1Ô1°3¸¸C¸ÑAÔA‰ˆˆaØ  Q¡¨¡Ñ/ˆÝ”�œ
 4¨(¡?°AÑ6Ô6Ñ7Ô7ˆÝ”z $¨Ñ1Ô1°V¸e±^ÑDˆØ×!Ò!Ñ#Ô#ˆØ—'’'‘)”)ˆØ—'’'‘)”)ˆØ�WÒÐØ˜w™¨%Ñ/°7¸WÑ3DÑE×MÒMÍbÌhÑWÔWˆHØ˜HÔ%Ð%ØˆåŒ8�W˜g sÐ+µ2´:Ð>Ñ>Ô>€DØ˜V f™_¨uÑ4Ñ5€Hå�G‰nŒnð 8ñ 8ˆÝ˜‘.”.ð 	8ñ 	8ˆBØ˜6‘kˆGØ)+¨g¸©kÒ)9Ð)9�R˜!‘V˜vÑ%Ð%¸qˆEØ˜6‘kˆGØ)+¨g¸©kÒ)9Ð)9�R˜!‘V˜vÑ%Ð%¸qˆEà˜G E˜M¨7°5¨=Ð8Ô9ˆDÝ”l 4§<¢<¡>¤>°3¸¸C¸ÑAÔA‰GˆD�!å”V�BœJ t¨h¡¸Ñ:Ô:Ñ;Ô;ˆFÝ”j  xÑ0Ô0°F¸U±NÑCˆGà—.’.Ñ"Ô"ˆCØ—g’g‘i”iˆGØ—g’g‘i”iˆGØ˜Ò Ð Ø # g¡°Ñ6¸'ÀGÑ:KÑL��R˜�V‘‘å!œ{¨1¨c°3Ñ7Ô7��R˜�V‘‘ñ%	8õ* Œy˜‰|Œ|€HÝŒy˜‰|Œ|€Hà�v ‘|Ñ#¥u¨V¡}¤}Ñ4€DÝ
Œ(�4‰.Œ.×
Ò
¥Ñ
$Ô
$€CØ
�‰'€CØ
�‰*�a�a�a˜�gÔ	€BåŒG�C˜˜G a™KÑ(Ô(€EÝŒG�C˜˜G a™KÑ(Ô(€Eà�v ‘|Ñ#¥u¨V¡}¤}Ñ4€DÝ
Œ(�4‰.Œ.×
Ò
¥Ñ
$Ô
$€CØ
�‰'€CØ
�‰*�d˜A˜A˜A�gÔ	€BåŒG�C˜˜G a™KÑ(Ô(€EÝŒG�C˜˜G a™KÑ(Ô(€EåŒ{˜5 %°$Ð7Ñ7Ô7�H€CˆÝŒ{˜5 %°$Ð7Ñ7Ô7�H€Cˆà
ˆs�C˜Ð!Ô
"€CØ
ˆs�C˜Ð!Ô
"€CØ
ˆs�C˜Ð!Ô
"€CØ
ˆs�C˜Ð!Ô
"€Cà�‰8�sÑ
˜R #™XÑ
%€CØ�‰8�sÑ
˜R #™XÑ
%€CØ�‰8�sÑ
˜R #™XÑ
%€CåŒ7�3˜˜3ÑÔ×&Ò&¥r¤xÑ0Ô0Ð0ó    c                óä  — |                       t          j        ¦  «        }|dd…dd…f          |dd…dd…f         z   d|dd…dd…f         z  z
  d|dd…dd…f         z  z   |dd…dd…f         z
  |dd…dd…f         z   }|dd…dd…f          d|dd…dd…f         z  z
  |dd…dd…f         z
  |dd…dd…f         z   d|dd…dd…f         z  z   |dd…dd…f         z   }t          j        ||¦  «        }t          j        |¦  «        }||dd…dd…f<   |                     ¦   «         }|dk    r%|dz  |z                        t          j        ¦  «        n|                      t          j        ¦  «        S )	uP   TÃ­nh toÃ¡n biÃªn Ä‘á»™ gradient Sobel theo cáº£ 2 trá»¥c x vÃ  y thuáº§n NumPy.Néþÿÿÿé   ç       @r(   éÿÿÿÿr   r+   )r:   r2   r=   ÚhypotÚ
zeros_liker1   r;   )r!   ÚfÚgxÚgyÚmagru   Úmxs          r   Úsobel_edge_magnituder„   �   sÄ  € à�Š�œ
Ñ#Ô#€Aà	
ˆ3ˆBˆ3���ˆ8Œˆ�q˜˜"˜˜a˜b˜b˜”zÑ!Ø
��!�B�$˜˜˜�)”Ñ
ñ	Ø" Q q¨ t¨Q¨R¨R x¤[Ñ0ñ	1à
ˆAˆBˆB���ˆGŒ*ñ	à˜˜˜˜Q˜R˜R˜”yñ	!ð ð 
ˆ3ˆBˆ3���ˆ8Œˆ�s˜Q˜s ˜s A b D˜yœ\Ñ)Ñ)¨A¨c¨r¨c°1°2°2¨g¬JÑ6Ø
ˆAˆBˆB���ˆGŒ*ñ	Ø˜Q˜q˜r˜r 1 R 4˜xœ[Ñ(ñ	)Ø+,¨Q¨R¨R°°°¨V¬9ñ	5ð õ Œ(�2�rÑ
Ô
€CÝ
Œ-˜Ñ
Ô
€CØ€Cˆˆ"ˆˆa�ˆdˆ
�OØ	�Š‰Œ€BØ24°q²&°&ˆC�%‰K˜"Ñ×$Ò$¥R¤XÑ.Ô.Ð.¸c¿jºjÍÌÑ>RÔ>RÐRrw   ÚimgúUnion[Image.Image, np.ndarray]úImage.Imagec                óŽ  — t          | t          j        ¦  «        r(t          j        |                      d¦  «        ¦  «        }nK| j        dk    r| n=t          j        | ddd…f         g d¢¦  «                             t          j        ¦  «        }t          |d|¬¦  «        }t          j
        |¦  «                             d	¦  «        S )
uO   Ã�p dá»¥ng Dual-Pass CLAHE trÃªn áº£nh Ä‘á»ƒ táº¡o áº£nh PIL tá»‘i Æ°u cho OCR.ÚLrz   .Né   )g‰A`åÐ"Ó?gbX9´Èâ?gÉv¾Ÿ/½?r   )r#   r%   r   )r   r   r2   Úarrayr   ÚndimÚdotr:   r;   rv   Ú	fromarray)r…   r%   ÚgrayÚenhanceds       r   Údual_pass_enhance_imager‘   £   s¬   € õ
 �#•u”{Ñ#Ô#ð fÝŒx˜Ÿš CÑ(Ô(Ñ)Ô)ˆˆà”h !’m�mˆsˆs­¬°°C¸¸!¸°G´Ð>SÐ>SÐ>SÑ)TÔ)T×)[Ò)[Õ\^Ô\dÑ)eÔ)eˆå °À:ÐNÑNÔN€HÝŒ?˜8Ñ$Ô$×,Ò,¨UÑ3Ô3Ð3rw   Úfull_imgÚtemplate_imgú'Tuple[Optional[Tuple[int, int]], float]c           	     óÈ	  — | j         \  }}t          ||¦  «        }t          t          |¬¦  «        }t	          dt          t          |j        |j        z  ¦  «        ¦  «        ¦  «        }t	          dt          t          |j	        |j
        z  ¦  «        ¦  «        ¦  «        }|                     ||ft          j        j        ¦  «        }|j        rt           j        nt           j        }	|                     dddd|	¬¦  «        \  }
}}}t          |dz  ¦  «        }t	          d	t)          |d
z
  |
¦  «        ¦  «        }t	          d	t)          |d
z
  |¦  «        ¦  «        }t	          |d
z   t)          ||¦  «        ¦  «        }t	          |d
z   t)          ||¦  «        ¦  «        }|                      ||||f¦  «                             d¦  «        }t/          t1          j        |¦  «        ¦  «                             t0          j        ¦  «        }t/          t1          j        |                     d¦  «        ¦  «        ¦  «                             t0          j        ¦  «        }|j        \  }}||k     s||k     rdS ||                     ¦   «         z
  }t0          j                             |¦  «        }|dk     rdS d}d}tA          d	||z
  d
z   d¦  «        D ]¢}tA          d	||z
  d
z   d¦  «        D ]ˆ}||||z   …|||z   …f         }||                     ¦   «         z
  }t0          j                             |¦  «        } | dk    r6tC          t1          j"        ||z  ¦  «        | |z  z  ¦  «        }!|!|k    r|!}||f}Œ‰Œ£|\  }"}#t	          d	|"dz
  ¦  «        }$t)          ||z
  |"dz   ¦  «        }%t	          d	|#dz
  ¦  «        }&t)          ||z
  |#dz   ¦  «        }'tA          |&|'d
z   ¦  «        D ]ž}tA          |$|%d
z   ¦  «        D ]ˆ}||||z   …|||z   …f         }||                     ¦   «         z
  }t0          j                             |¦  «        } | dk    r6tC          t1          j"        ||z  ¦  «        | |z  z  ¦  «        }!|!|k    r|!}||f}Œ‰ŒŸ||d	         z   }(||d
         z   })t          t          |(d|j        z  z   ¦  «        ¦  «        }*t          t          |)d|j
        z  z   ¦  «        ¦  «        }+|*|k    rdS |*|+f|fS )uë   So khá»›p máº«u nÃºt TRAVERSE dá»±a trÃªn Ä‘áº·c trÆ°ng cáº¡nh (Sobel Edge NCC).

    KhÃ¡ng hoÃ n toÃ n biáº¿n Ä‘á»™ng mÃ u sáº¯c, lá»­a lÃ² Map Device vÃ  chÃ³i sÃ¡ng bloom.
    @return: ((center_x, center_y), correlation_score)
    ©Ú
source_resÚ
target_resé   çš™™™™™‰@çfffffæ‚@ç333333—@ç     @�@©Úmodeçš™™™™™á?r   r(   r‰   )Ng        gñhãˆµøä>g      ð¿)r   r   rz   rŠ   g     °a@g     €G@)#Úsizer
   r	   r   r1   rB   ÚroundÚwidthÚscale_xÚheightÚscale_yÚresizer   Ú
ResamplingÚBICUBICÚis_windowed_aspectr   ÚCENTER_ANCHOREDÚSTRETCHÚtransform_bboxr9   Úcropr   r„   r2   r‹   r:   r=   r0   ÚmeanÚlinalgÚnormr>   r&   r5   ),r’   r“   rF   rE   ÚresÚscalerÚtwÚthÚ
tpl_scaledrŸ   Úrx1Úry1Úrx2Úry2Úmax_traverse_xÚroi_x1Úroi_y1Úroi_x2Úroi_y2Úroi_imgÚroi_edgeÚtpl_edgeÚrhÚrwÚtpl_meanÚtpl_normÚ	best_corrÚbest_locÚyÚxÚpatchÚp_meanÚp_normÚcÚbxÚbyÚ	refine_x1Ú	refine_x2Ú	refine_y1Ú	refine_y2Útl_xÚtl_yÚtext_cxÚtext_cys,                                               r   Úmatch_traverse_template_edgerÙ   ±   sÁ  € ð Œ=�D€A€qÝ
�Q˜Ñ
Ô
€CÝ­¸sÐCÑCÔC€Få	ˆR••U˜<Ô-°´Ñ>Ñ?Ô?Ñ@Ô@Ñ	AÔ	A€BÝ	ˆR••U˜<Ô.°´Ñ?Ñ@Ô@ÑAÔAÑ	BÔ	B€BØ×$Ò$ b¨" X­uÔ/?Ô/GÑHÔH€Jð +.Ô*@ÐY�;Ô&Ð&ÅkÔFY€DØ×.Ò.¨u°e¸VÀUÐQUÐ.ÑVÔVÑ€Cˆˆc�3Ý˜˜T™‘]”]€NÝ�•C˜˜A™˜s‘O”OÑ$Ô$€FÝ�•C˜˜A™˜s‘O”OÑ$Ô$€FÝ�˜!‘�S °Ñ5Ô5Ñ6Ô6€FÝ�˜!‘�S  C™[œ[Ñ)Ô)€Fà�mŠm˜V V¨V°VÐ<Ñ=Ô=×EÒEÀcÑJÔJ€Gå#¥B¤H¨WÑ$5Ô$5Ñ6Ô6×=Ò=½b¼jÑIÔI€HÝ#¥B¤H¨Z×-?Ò-?ÀÑ-DÔ-DÑ$EÔ$EÑFÔF×MÒMÍbÌjÑYÔY€HàŒ^�F€BˆØ	ˆB‚w€w�"�r’'�'Øˆyà˜(Ÿ-š-™/œ/Ñ)€HÝŒy�~Š~˜hÑ'Ô'€HØ�$‚€Øˆyà€IØ€Hõ �1�b˜2‘g ‘k 1Ñ%Ô%ð 	&ð 	&ˆÝ�q˜"˜r™' A™+ qÑ)Ô)ð 	&ð 	&ˆAØ˜Q˜q 2™v˜X q¨¨R© xÐ/Ô0ˆEØ˜UŸZšZ™\œ\Ñ)ˆFÝ”Y—^’^ FÑ+Ô+ˆFØ˜Š}ˆ}Ý�"œ& ¨(Ñ!2Ñ3Ô3°vÀÑ7HÑIÑJÔJ�Ø�y’=�=Ø !�IØ ! 1˜v�Høð	&ð �F€BˆÝ�A�r˜A‘v‘”€IÝ�B˜‘G˜R !™VÑ$Ô$€IÝ�A�r˜A‘v‘”€IÝ�B˜‘G˜R !™VÑ$Ô$€Iå�9˜i¨!™mÑ,Ô,ð 	&ð 	&ˆÝ�y )¨a¡-Ñ0Ô0ð 	&ð 	&ˆAØ˜Q˜q 2™v˜X q¨¨R© xÐ/Ô0ˆEØ˜UŸZšZ™\œ\Ñ)ˆFÝ”Y—^’^ FÑ+Ô+ˆFØ˜Š}ˆ}Ý�"œ& ¨(Ñ!2Ñ3Ô3°vÀÑ7HÑIÑJÔJ�Ø�y’=�=Ø !�IØ ! 1˜v�Høð	&ð �H˜Q”KÑ€DØ�H˜Q”KÑ€Dõ •%˜˜u v¤~Ñ5Ñ5Ñ6Ô6Ñ7Ô7€GÝ•%˜˜t f¤nÑ4Ñ4Ñ5Ô5Ñ6Ô6€Gà�ÒÐØˆyà�WÐ˜yÐ(Ð(rw   r    Útemplate_pathúOptional[str]Ú	min_scoreúOptional[Tuple[int, int]]c           
     ó 	  — t          | ¦  «        }|€dS |j        \  }}t          ||¦  «        }t          t          |¬¦  «        }|j        rt          j        nt          j        }| 	                    dddd|¬¦  «        \  }	}
}}t          |dz  ¦  «        }t          ||¦  «        }t          d	t          |d
z
  |	¦  «        ¦  «        t          d	t          |d
z
  |
¦  «        ¦  «        t          |	d
z   t          ||¦  «        ¦  «        t          |
d
z   t          ||¦  «        ¦  «        f}t          ��Ì	 d	dlm} |                     |¦  «        } ||¦  «        }|                     dg ¦  «        D �]$}|                     dd¦  «                             ¦   «         }d|v rd|v rŒ4d|v sd|v rèd„ |                     dg ¦  «        D ¦   «         }|r|n|                     dg ¦  «        }|r¬t          d„ |D ¦   «         ¦  «        }t          d„ |D ¦   «         ¦  «        }t          d„ |D ¦   «         ¦  «        }t          d„ |D ¦   «         ¦  «        }t          |d	         ||z   dz  z   ¦  «        }t          |d
         ||z   dz  z   ¦  «        }||k    r||fc S �Œ&t'          |d¬¦  «        } ||¦  «        }|                     dg ¦  «        D �]$}|                     dd¦  «                             ¦   «         }d|v rd|v rŒ4d|v sd|v rèd„ |                     dg ¦  «        D ¦   «         }|r|n|                     dg ¦  «        }|r¬t          d„ |D ¦   «         ¦  «        }t          d„ |D ¦   «         ¦  «        }t          d„ |D ¦   «         ¦  «        }t          d „ |D ¦   «         ¦  «        }t          |d	         ||z   dz  z   ¦  «        }t          |d
         ||z   dz  z   ¦  «        }||k    r||fc S �Œ&n# t(          $ r Y nw xY w|€dt*          j                             t*          j                             t2          ¦  «        d!d!d"d#¦  «        }t*          j                             |¦  «        }t*          j                             |¦  «        rO	 t9          j        |¦  «        }t=          ||¦  «        \  } }!| r|!|k    r| d	         |k    r| S n# t(          $ r Y nw xY wdS )$uÒ  Ä�á»‹nh vá»‹ nÃºt TRAVERSE báº±ng kiáº¿n trÃºc Dual-Pass CLAHE + Canny Edge Template Matching.

    Pass 1: Thá»­ nháº­n diá»‡n báº±ng WinOCR trá»±c tiáº¿p trÃªn áº£nh gá»‘c.
    Pass 2: Khi Pass 1 tháº¥t báº¡i do Ã¡nh sÃ¡ng/bloom, kÃ­ch hoáº¡t CLAHE enhancement vÃ 
            Edge-based Normalized Cross-Correlation vá»›i template chuáº©n.
    @param img_input: Ä�Æ°á»�ng dáº«n tá»‡p hoáº·c Ä‘á»‘i tÆ°á»£ng PIL Image.
    @param template_path: TÃ¹y chá»�n Ä‘Æ°á»�ng dáº«n template; máº·c Ä‘á»‹nh láº¥y `captures/traverse_button_crop.png`.
    @param min_score: NgÆ°á»¡ng tÆ°Æ¡ng quan tá»‘i thiá»ƒu Ä‘á»ƒ xÃ¡c thá»±c (chá»‘ng False-Positive).
    @return: (center_x, center_y) hoáº·c None náº¿u khÃ´ng phÃ¡t hiá»‡n.
    Nr–   rš   r›   rœ   r�   rž   r    r   r(   ©Úsafe_recognize_pil_syncÚlinesÚtextÚ ÚENTERÚMAPÚTRAVERSEÚTRAVERSc                óf   — g | ].}d |                      dd¦  «                             ¦   «         v ¯,|‘Œ/S ©ÚTRAVrâ   rã   ©ÚgetÚupper©Ú.0Úwds     r   ú
<listcomp>z2find_traverse_button_dual_pass.<locals>.<listcomp>8  ó>   € ÐhÐhÐh BÀ6ÈRÏVÊVÐTZÐ\^ÑM_ÔM_×MeÒMeÑMgÔMgÐCgÐCg˜RÐCgÐCgÐCgrw   Úwordsc              3  ó2   K  — | ]}|d          d         V — ŒdS ©Úbounding_rectrÊ   N© rî   s     r   ú	<genexpr>z1find_traverse_button_dual_pass.<locals>.<genexpr>;  ó,   è è € Ð#NÐ#NÀ B Ô$7¸Ô$<Ð#NÐ#NÐ#NÐ#NÐ#NÐ#Nrw   c              3  óP   K  — | ]!}|d          d         |d          d         z   V — Œ"dS ©rö   rÊ   r£   Nr÷   rî   s     r   rø   z1find_traverse_button_dual_pass.<locals>.<genexpr><  ó=   è è € Ð#mÐ#mÐ`b B Ô$7¸Ô$<¸rÀ/Ô?RÐSZÔ?[Ñ$[Ð#mÐ#mÐ#mÐ#mÐ#mÐ#mrw   c              3  ó2   K  — | ]}|d          d         V — ŒdS ©rö   rÉ   Nr÷   rî   s     r   rø   z1find_traverse_button_dual_pass.<locals>.<genexpr>=  rù   rw   c              3  óP   K  — | ]!}|d          d         |d          d         z   V — Œ"dS ©rö   rÉ   r¥   Nr÷   rî   s     r   rø   z1find_traverse_button_dual_pass.<locals>.<genexpr>>  ó=   è è € Ð#nÐ#nÐac B Ô$7¸Ô$<¸rÀ/Ô?RÐS[Ô?\Ñ$\Ð#nÐ#nÐ#nÐ#nÐ#nÐ#nrw   r{   g      @)r%   c                óf   — g | ].}d |                      dd¦  «                             ¦   «         v ¯,|‘Œ/S ré   rë   rî   s     r   rñ   z2find_traverse_button_dual_pass.<locals>.<listcomp>L  rò   rw   c              3  ó2   K  — | ]}|d          d         V — ŒdS rõ   r÷   rî   s     r   rø   z1find_traverse_button_dual_pass.<locals>.<genexpr>O  rù   rw   c              3  óP   K  — | ]!}|d          d         |d          d         z   V — Œ"dS rû   r÷   rî   s     r   rø   z1find_traverse_button_dual_pass.<locals>.<genexpr>P  rü   rw   c              3  ó2   K  — | ]}|d          d         V — ŒdS rþ   r÷   rî   s     r   rø   z1find_traverse_button_dual_pass.<locals>.<genexpr>Q  rù   rw   c              3  óP   K  — | ]!}|d          d         |d          d         z   V — Œ"dS r   r÷   rî   s     r   rø   z1find_traverse_button_dual_pass.<locals>.<genexpr>R  r  rw   z..Úcapturesztraverse_button_crop.png)r   r¡   r
   r	   r   rª   r   r«   r¬   r­   rB   r9   r1   ÚwinocrÚsrc.common.vision_ocrrà   r®   rì   rí   r‘   r   r   r   ÚjoinÚdirnameÚ__file__Úabspathr   r   r   rÙ   )"r   rÚ   rÜ   r…   rF   rE   r²   r³   rŸ   r·   r¸   r¹   rº   r»   Úrx2_clampedÚroi_boxrà   Úcrop_roiÚlineÚtró   ÚtargetÚmin_xÚmax_xÚmin_yÚmax_yÚcxÚcyÚenhanced_roiÚres_enhÚdefault_tplÚtpl_imgÚcoordsÚscores"                                     r   Úfind_traverse_button_dual_passr     sL  € õ �IÑ
Ô
€CØ
€{ØˆtàŒ8�D€A€qÝ
�Q˜Ñ
Ô
€CÝ­¸sÐCÑCÔC€FØ*-Ô*@ÐY�;Ô&Ð&ÅkÔFY€DØ×.Ò.¨u°e¸VÀUÐQUÐ.ÑVÔVÑ€Cˆˆc�3õ ˜˜T™‘]”]€NÝ�c˜>Ñ*Ô*€KåˆA�s�1�q‘5˜#‰ŒÑÔÝˆA�s�1�q‘5˜#‰ŒÑÔÝˆC�!‰G•S˜¨Ñ5Ô5Ñ6Ô6ÝˆC�!‰G•S˜˜C‘[”[Ñ!Ô!ð	€Gõ Ñð+	ØEÐEÐEÐEÐEÐEà—x’x Ñ(Ô(ˆHØ)Ð)¨(Ñ3Ô3ˆCØŸš ¨Ñ,Ô,ð *ñ *�Ø—H’H˜V RÑ(Ô(×.Ò.Ñ0Ô0�à˜a�<�< E¨Q J JØØ �?�? i°1 n nØhÐh¨$¯(ª(°7¸BÑ*?Ô*?ÐhÑhÔh�EØ&+ÐF˜U˜U°·²¸'À2Ñ1FÔ1F�FØð *Ý #Ð#NÐ#NÀvÐ#NÑ#NÔ#NÑ NÔ N˜Ý #Ð#mÐ#mÐflÐ#mÑ#mÔ#mÑ mÔ m˜Ý #Ð#NÐ#NÀvÐ#NÑ#NÔ#NÑ NÔ N˜Ý #Ð#nÐ#nÐgmÐ#nÑ#nÔ#nÑ nÔ n˜Ý  ¨¤¨u°u©}ÀÑ.CÑ!CÑDÔD˜Ý  ¨¤¨u°u©}ÀÑ.CÑ!CÑDÔD˜Ø Ò/Ð/Ø#% r 6˜M˜M˜Mùõ 3°8ÈÐLÑLÔLˆLØ-Ð-¨lÑ;Ô;ˆGØŸš G¨RÑ0Ô0ð *ñ *�Ø—H’H˜V RÑ(Ô(×.Ò.Ñ0Ô0�Ø˜a�<�< E¨Q J JØØ �?�? i°1 n nØhÐh¨$¯(ª(°7¸BÑ*?Ô*?ÐhÑhÔh�EØ&+ÐF˜U˜U°·²¸'À2Ñ1FÔ1F�FØð *Ý #Ð#NÐ#NÀvÐ#NÑ#NÔ#NÑ NÔ N˜Ý #Ð#mÐ#mÐflÐ#mÑ#mÔ#mÑ mÔ m˜Ý #Ð#NÐ#NÀvÐ#NÑ#NÔ#NÑ NÔ N˜Ý #Ð#nÐ#nÐgmÐ#nÑ#nÔ#nÑ nÔ n˜Ý  ¨¤¨u°u©}ÀÑ.CÑ!CÑDÔD˜Ý  ¨¤¨u°u©}ÀÑ.CÑ!CÑDÔD˜Ø Ò/Ð/Ø#% r 6˜M˜M˜Mùð*øõ  ð 	ð 	ð 	ØˆDð	øøøð ÐÝ”g—l’l¥2¤7§?¢?µ8Ñ#<Ô#<¸dÀDÈ*ÐVpÑqÔqˆÝœŸš¨Ñ4Ô4ˆå	„w‡~‚~�mÑ$Ô$ð ð	Ý”j Ñ/Ô/ˆGÝ8¸¸gÑFÔF‰MˆF�EØð ˜% 9Ò,Ð,°¸´¸nÒ1LÐ1LØ�øøÝð 	ð 	ð 	ØˆDð	øøøð ˆ4s2   Ä/EO* ÊEO* Ï'O* Ï*
O7Ï6O7Ò <R> Ò>
SÓ
SÚboolc           	     ó  ‡— t          | ¦  «        }|€dS |j        \  }}t          |¦  «        }|�dS t          �Ë	 ddlm} |                     dd|t          |dz  ¦  «        f¦  «        } ||¦  «        }d                     d„ | 	                    d	g ¦  «        D ¦   «         ¦  «         
                    ¦   «         Št          ˆfd
„dD ¦   «         ¦  «        rdS t          ˆfd„dD ¦   «         ¦  «        rdS n# t          $ r Y nw xY wdS )u-  Kiá»ƒm tra tráº¡ng thÃ¡i má»Ÿ cá»§a giao diá»‡n Atlas/Map Device khÃ¡ng nhiá»…u vÃ  khÃ¡ng click mÃ¹.

    YÃªu cáº§u:
    1. PhÃ¡t hiá»‡n cÃ¡c token trÃªn banner Ä‘á»‰nh ("SEARCH", "ENDGAME", "ACT 1-4", "ATLAS") HOáº¶C
    2. Ä�á»‹nh vá»‹ Ä‘Æ°á»£c nÃºt TRAVERSE á»Ÿ trung tÃ¢m qua Dual-Pass Locator.
    3. Cháº·n Ä‘á»©ng False-Positives:
       - Tá»« chá»‘i náº¿u lÃ  há»™p thoáº¡i NPC ("GOODBYE", "BUY OR SELL", "INTRODUCTION").
       - Tá»« chá»‘i náº¿u chá»‰ tháº¥y chá»¯ "MAP DEVICE" Ä‘Æ¡n láº» trÃªn sÃ n 3D Hideout mÃ  khÃ´ng cÃ³ banner/nÃºt.
    NFTr   rß   g{®GázÄ?ú c              3  óB   K  — | ]}|                      d d¦  «        V — ŒdS )râ   rã   N)rì   )rï   r  s     r   rø   z*is_atlas_ui_open_robust.<locals>.<genexpr>‡  s0   è è € ÐYÐY°T˜DŸHšH V¨RÑ0Ô0ÐYÐYÐYÐYÐYÐYrw   rá   c              3  ó    •K  — | ]}|‰v V — Œ	d S ©Nr÷   )rï   ÚbadÚblobs     €r   rø   z*is_atlas_ui_open_robust.<locals>.<genexpr>‰  s'   øè è € ÐUÐU 3�3˜$�;ÐUÐUÐUÐUÐUÐUrw   )ÚGOODBYEzBUY OR SELLÚINTRODUCTIONc              3  ó    •K  — | ]}|‰v V — Œ	d S r&  r÷   )rï   Úkr(  s     €r   rø   z*is_atlas_ui_open_robust.<locals>.<genexpr>Œ  s'   øè è € ÐÐ �1˜�9ÐÐÐÐÐÐrw   )	ÚSEARCHÚENDGAMEÚ	INTERLUDEzACT 1zACT 2zACT 3zACT 4ÚATLASÚWORLD)r   r¡   r   r  r	  rà   r®   rB   r
  rì   rí   Úanyr   )	r   r…   rF   rE   Úbtn_posrà   Úcrop_bannerÚ
res_bannerr(  s	           @r   Úis_atlas_ui_open_robustr6  k  sQ  ø€ õ �IÑ
Ô
€CØ
€{ØˆuàŒ8�D€A€qõ -¨SÑ1Ô1€GØÐØˆtõ Ðð	ØEÐEÐEÐEÐEÐEàŸ(š( A q¨!­S°°T±©]¬]Ð#;Ñ<Ô<ˆKØ0Ð0°Ñ=Ô=ˆJØ—8’8ÐYÐY¸Z¿^º^ÈGÐUWÑ=XÔ=XÐYÑYÔYÑYÔY×_Ò_ÑaÔaˆDåÐUÐUÐUÐUÐ*TÐUÑUÔUÑUÔUð Ø�uåÐÐÐÐÐ&~ÐÑÔÑÔð Ø�tðøåð 	ð 	ð 	ØˆDð	øøøð ˆ5s   ºBC4 ÃC4 Ã4
DÄ D)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”   )Nr    )r   r   rÚ   rÛ   rÜ   r&   r   rÝ   )r   r   r   r!  )Ú__doc__Ú
__future__r   r   Útypingr   r   r   Únumpyr2   ÚPILr   r   ÚImportErrorr  Úsrc.common.coordinate_transformr	   r
   r   r   r   r   rv   r„   r‘   rÙ   r   r6  r÷   rw   r   ú<module>r>     sã  ððð ð #Ð "Ð "Ð "Ð "Ð "à 	€	€	€	Ø )Ð )Ð )Ð )Ð )Ð )Ð )Ð )Ð )Ð )à Ð Ð Ð ðØ#Ð#Ð#Ð#Ð#Ð#Ð#Ð#Ð#øØð ð ð Ø€E€E€EðøøøðØ€M€M€M€MøØð ð ð Ø€F€F€Fðøøøðð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð ð ð& "(ØðX1ð X1ð X1ð X1ð X1ðvSð Sð Sð Sð* ð4ð 4ð 4ð 4ð 4ðT)ð T)ð T)ð T)ðr $(Øð`ð `ð `ð `ð `ðF&ð &ð &ð &ð &ð &s   œ% ¥/®/³8 ¸AÁA