Ë
    FêñiÊ5  ã                  óŠ   — d dl mZ d dlZd dlmZ d dlZd dlZd dlm	Z	m
Z
mZ d dlmZ d dlmZ  G d„ d«      Z G d	„ d
e	«      Zy)é    )ÚannotationsN)ÚAny)ÚBaseSolutionÚSolutionAnnotatorÚSolutionResults)ÚLOGGER)Úcheck_imshowc                  óP   — e Zd ZdZdd„Zdd„Zdd„Zdd„Zdd„Zdd„Z	dd„Z
dd	„Zy
)ÚParkingPtsSelectiona>  A class for selecting and managing parking zone points on images using a Tkinter-based UI.

    This class provides functionality to upload an image, select points to define parking zones, and save the selected
    points to a JSON file. It uses Tkinter for the graphical user interface.

    Attributes:
        tk (module): The Tkinter module for GUI operations.
        filedialog (module): Tkinter's filedialog module for file selection operations.
        messagebox (module): Tkinter's messagebox module for displaying message boxes.
        master (tk.Tk): The main Tkinter window.
        canvas (tk.Canvas): The canvas widget for displaying the image and drawing bounding boxes.
        image (PIL.Image.Image): The uploaded image.
        canvas_image (ImageTk.PhotoImage): The image displayed on the canvas.
        rg_data (list[list[tuple[int, int]]]): List of bounding boxes, each defined by 4 points.
        current_box (list[tuple[int, int]]): Temporary storage for the points of the current bounding box.
        imgw (int): Original width of the uploaded image.
        imgh (int): Original height of the uploaded image.
        canvas_max_width (int): Maximum width of the canvas.
        canvas_max_height (int): Maximum height of the canvas.

    Methods:
        initialize_properties: Initialize properties for image, canvas, bounding boxes, and dimensions.
        upload_image: Upload and display an image on the canvas, resizing it to fit within specified dimensions.
        on_canvas_click: Handle mouse clicks to add points for bounding boxes on the canvas.
        draw_box: Draw a bounding box on the canvas using the provided coordinates.
        remove_last_bounding_box: Remove the last bounding box from the list and redraw the canvas.
        redraw_canvas: Redraw the canvas with the image and all bounding boxes.
        save_to_json: Save the selected parking zone points to a JSON file with scaled coordinates.

    Examples:
        >>> parking_selector = ParkingPtsSelection()
        >>> # Use the GUI to upload an image, select parking zones, and save the data
    c                ó¦  — 	 ddl }ddl m}m} t        d
¬«      sy|||c| _
        | _        | _        | j                  j                  «       | _        | j                  j                  d«       | j                  j                  dd«       | j                  j                  | j                  d¬«      | _        | j                   j#                  | j                  j$                  ¬«       d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        | j                  j7                  | j                  «      }|j#                  | j                  j8                  ¬«       d| j:                  fd| j<                  fd| j>                  ffD ]G  \  }}| j                  jA                  |||¬«      j#                  | j                  jB                  ¬«       ŒI | jE                  «        | j                  jG                  «        y# t        $ rC ddl}ddddœj                  |j                  «       d«      }t        j                  d	|› �«       Y yw xY w)zhInitialize the ParkingPtsSelection class, setting up UI and properties for parking zone point selection.r   N)Ú
filedialogÚ
messageboxzrsudo apt install python3-tk (Debian/Ubuntu) | sudo dnf install python3-tkinter (Fedora) | sudo pacman -S tk (Arch)zgreinstall Python and enable the checkbox `tcl/tk and IDLE` on **Optional Features** during installationzYreinstall Python from https://www.python.org/downloads/macos/ or `brew install python-tk`)ÚLinuxÚWindowsÚDarwinz+Unknown OS. Check your Python installation.z8 Tkinter is not configured or supported. Potential fix: T)Úwarnz)Ultralytics Parking Zones Points SelectorFÚwhite)Úbg)ÚsidezUpload ImagezRemove Last Bounding BoxÚSave)ÚtextÚcommand)$Útkinterr   r   ÚImportErrorÚplatformÚgetÚsystemr   Úwarningr	   ÚtkÚTkÚmasterÚtitleÚ	resizableÚCanvasÚcanvasÚpackÚBOTTOMÚimageÚcanvas_imageÚcanvas_max_widthÚcanvas_max_heightÚrg_dataÚcurrent_boxÚimghÚimgwÚFrameÚTOPÚupload_imageÚremove_last_bounding_boxÚsave_to_jsonÚButtonÚLEFTÚinitialize_propertiesÚmainloop)	Úselfr   r   r   r   Úinstall_cmdÚbutton_framer   Úcmds	            új/var/www/pod-logistic/pod-ai/venv/lib/python3.12/site-packages/ultralytics/solutions/parking_management.pyÚ__init__zParkingPtsSelection.__init__3   sû  € ð	Û ß6ô  Õ&Øà46¸
ÀJÐ1ˆŒ�” $¤/Ø—g‘g—j‘j“lˆŒØ�‰×ÑÐEÔFØ�‰×Ñ˜e UÔ+à—g‘g—n‘n T§[¡[°W�nÓ=ˆŒØ�‰×Ñ˜dŸg™gŸn™nÐÔ-àˆŒ
Ø ˆÔØ $ˆÔØ!%ˆÔØˆŒØˆÔØˆŒ	ØˆŒ	ð —w‘w—}‘} T§[¡[Ó1ˆØ×Ñ˜tŸw™wŸ{™{ÐÔ+ð ˜T×.Ñ.Ð/Ø'¨×)FÑ)FÐGØ�T×&Ñ&Ð'ð
ò 	Y‰IˆD�#ð
 �G‰G�N‰N˜<¨d¸CˆNÓ@×EÑEÈ4Ï7É7Ï<É<ÐEÕXð	Yð 	×"Ñ"Ô$Ø�‰×ÑÕøô[ ò 	Ûð+ð EØuñ	÷
 ‰c�(—/‘/Ó#Ð%RÓSð ô �N‰NÐUÐVaÐUbÐcÔdÙð	ús   ‚H ÈA	IÉIc                óx   — dx| _         | _        g g c| _        | _        dx| _        | _        d\  | _        | _        y)zHInitialize properties for image, canvas, bounding boxes, and dimensions.Nr   )i   iÐ  )r(   r)   r,   r-   r/   r.   r*   r+   ©r9   s    r=   r7   z)ParkingPtsSelection.initialize_propertiesg   s@   € à)-Ð-ˆŒ
�TÔ&Ø)+¨RÐ&ˆŒ�dÔ&Ø !Ð!ˆŒ	�D”IØ8AÑ5ˆÔ˜tÕ5ó    c                óÌ  — ddl m}m} | j                  j	                  dg¬«      }|st        j                  d«       y|j                  |«      | _        | j                  j                  \  | _
        | _        | j                  | j                  z  }|dkD  r t        | j                  | j                  «      nt        | j                  |z  «      }|dk  r t        | j                  | j                  «      nt        ||z  «      }| j                   j#                  ||¬«       |j%                  | j                  j'                  ||f«      «      | _        | j                   j+                  dd| j,                  j.                  | j(                  ¬	«       | j                   j1                  d
| j2                  «       | j4                  j7                  «       | j8                  j7                  «       f y)zZUpload and display an image on the canvas, resizing it to fit within specified dimensions.r   )ÚImageÚImageTk)zImage Filesz*.png *.jpg *.jpeg)Ú	filetypeszNo image selected.Né   )ÚwidthÚheight©Úanchorr(   z
<Button-1>)ÚPILrC   rD   r   Úaskopenfilenamer   ÚinfoÚopenr(   Úsizer/   r.   Úminr*   Úintr+   r%   ÚconfigÚ
PhotoImageÚresizer)   Úcreate_imager   ÚNWÚbindÚon_canvas_clickr,   Úclearr-   )r9   rC   rD   ÚfileÚaspect_ratioÚcanvas_widthÚcanvas_heights          r=   r2   z ParkingPtsSelection.upload_imagen   sw  € ç&à�‰×.Ñ.Ð:_Ð9`Ð.ÓaˆÙÜ�K‰KÐ,Ô-Øà—Z‘Z Ó%ˆŒ
Ø#Ÿz™zŸ™ÑˆŒ	�4”9Ø—y‘y 4§9¡9Ñ,ˆà5AÀAÒ5EŒC�×%Ñ% t§y¡yÔ1Ì3Èt×OeÑOeÐhtÑOtÓKuð 	ð 7CÀaÒ6GŒC�×&Ñ&¨¯	©	Ô2ÌSÐQ]Ð`lÑQlÓMmð 	ð 	�‰×Ñ °mÐÔDØ#×.Ñ.¨t¯z©z×/@Ñ/@À,ÐP]ÐA^Ó/_Ó`ˆÔØ�‰× Ñ   A¨d¯g©g¯j©jÀ×@QÑ@QÐ ÔRØ�‰×Ñ˜ t×';Ñ';Ô<à�‰×ÑÓ˜d×.Ñ.×4Ñ4Ó6Ò6rA   c                ó  — | j                   j                  |j                  |j                  f«       | j                  j                  |j                  dz
  |j                  dz
  |j                  dz   |j                  dz   d¬«       t        | j                   «      dk(  ri| j                  j                  | j                   j                  «       «       | j                  | j                   «       | j                   j                  «        yy)zCHandle mouse clicks to add points for bounding boxes on the canvas.é   Úred)Úfillé   N)r-   ÚappendÚxÚyr%   Úcreate_ovalÚlenr,   ÚcopyÚdraw_boxrY   )r9   Úevents     r=   rX   z#ParkingPtsSelection.on_canvas_clickˆ   s¿   € à×Ñ×Ñ §¡¨%¯'©'Ð 2Ô3Ø�‰×Ñ §¡¨!¡¨U¯W©W°q©[¸%¿'¹'ÀA¹+ÀuÇwÁwÐQRÁ{ÐY^ÐÔ_Üˆt×ÑÓ  AÒ%Ø�L‰L×Ñ × 0Ñ 0× 5Ñ 5Ó 7Ô8Ø�M‰M˜$×*Ñ*Ô+Ø×Ñ×"Ñ"Õ$ð &rA   c                óz   — t        d«      D ]-  }| j                  j                  ||   ||dz   dz     dd¬«       Œ/ y)zADraw a bounding box on the canvas using the provided coordinates.rb   rF   Úblueé   )ra   rG   N)Úranger%   Úcreate_line)r9   ÚboxÚis      r=   ri   zParkingPtsSelection.draw_box‘   sD   € ä�q“ò 	TˆAØ�K‰K×#Ñ# C¨¡F¨C°°Q±¸!±Ñ,<À6ÐQRÐ#ÕSñ	TrA   c                óª   — | j                   s| j                  j                  dd«       y| j                   j                  «        | j	                  «        y)zARemove the last bounding box from the list and redraw the canvas.ÚWarningzNo bounding boxes to remove.N)r,   r   ÚshowwarningÚpopÚredraw_canvasr@   s    r=   r3   z,ParkingPtsSelection.remove_last_bounding_box–   s=   € à�|Š|Ø�O‰O×'Ñ'¨	Ð3QÔRØØ�‰×ÑÔØ×ÑÕrA   c                óø   — | j                   j                  d«       | j                   j                  dd| j                  j                  | j
                  ¬«       | j                  D ]  }| j                  |«       Œ y)z8Redraw the canvas with the image and all bounding boxes.Úallr   rI   N)r%   ÚdeleterU   r   rV   r)   r,   ri   )r9   rp   s     r=   rv   z!ParkingPtsSelection.redraw_canvasž   s\   € à�‰×Ñ˜5Ô!Ø�‰× Ñ   A¨d¯g©g¯j©jÀ×@QÑ@QÐ ÔRØ—<‘<ò 	ˆCØ�M‰M˜#Õñ	rA   c                óX  — | j                   | j                  j                  «       z  | j                  | j                  j	                  «       z  }}| j
                  D ���cg c]3  }d|D ��cg c]!  \  }}t        ||z  «      t        ||z  «      f‘Œ# c}}i‘Œ5 }}}}ddlm}  |«       }t        j                  ||d¬«       t        ddd¬	«      5 }	|	j                  |j                  «       «       d
d
d
«       | j                  j                  dd«       y
c c}}w c c}}}w # 1 sw Y   Œ3xY w)zMSave the selected parking zone points to a JSON file with scaled coordinates.Úpointsr   )ÚStringIOrb   )Úindentzbounding_boxes.jsonÚwúutf-8©ÚencodingNÚSuccessz+Bounding boxes saved to bounding_boxes.json)r/   r%   Úwinfo_widthr.   Úwinfo_heightr,   rQ   Úior|   ÚjsonÚdumprN   ÚwriteÚgetvaluer   Úshowinfo)
r9   Úscale_wÚscale_hrp   rd   re   Údatar|   Úwrite_bufferÚfs
             r=   r4   z ParkingPtsSelection.save_to_json¥   sð   € àŸ9™9 t§{¡{×'>Ñ'>Ó'@Ñ@À$Ç)Á)ÈdÏkÉk×NfÑNfÓNhÑBh�ˆØ^b×^jÑ^j×kÐkÐWZ�ÈS×QÁTÀQÈœS  W¡Ó-¬s°1°w±;Ó/?Ò@ÓQÒRÐkˆÒkåá“zˆÜ�	‰	�$˜¨QÕ/ÜÐ'¨°wÔ?ð 	-À1Ø�G‰G�L×)Ñ)Ó+Ô,÷	-à�‰× Ñ  Ð,YÕZùó RùÔk÷	-ð 	-ús$   ÁDÁ*&DÂDÃ D ÄDÄ D)N)ÚreturnÚNone)rp   zlist[tuple[int, int]]r�   r‘   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r>   r7   r2   rX   ri   r3   rv   r4   © rA   r=   r   r      s4   „ ñ óD2óhBó7ó4%óTó
óô[rA   r   c                  ó,   ‡ — e Zd ZdZdˆ fd„Zdd„Zˆ xZS )ÚParkingManagementa#  Manages parking occupancy and availability using YOLO model for real-time monitoring and visualization.

    This class extends BaseSolution to provide functionality for parking lot management, including detection of occupied
    spaces, visualization of parking regions, and display of occupancy statistics.

    Attributes:
        json_file (str): Path to the JSON file containing parking region details.
        json (list[dict]): Loaded JSON data containing parking region information.
        pr_info (dict[str, int]): Dictionary storing parking information (Occupancy and Available spaces).
        arc (tuple[int, int, int]): BGR color tuple for available region visualization.
        occ (tuple[int, int, int]): BGR color tuple for occupied region visualization.
        dc (tuple[int, int, int]): BGR color tuple for centroid visualization of detected objects.

    Methods:
        process: Process the input image for parking lot management and visualization.

    Examples:
        >>> from ultralytics.solutions import ParkingManagement
        >>> parking_manager = ParkingManagement(model="yolo26n.pt", json_file="parking_regions.json")
        >>> print(f"Occupied spaces: {parking_manager.pr_info['Occupancy']}")
        >>> print(f"Available spaces: {parking_manager.pr_info['Available']}")
    c                ón  •— t        ‰| �  di |¤Ž | j                  d   | _        | j                  s t	        j
                  d«       t        d«      ‚t        | j                  d¬«      5 }t        j                  |«      | _        ddd«       dddœ| _
        d	| _        d
| _        d| _        y# 1 sw Y   Œ)xY w)zVInitialize the parking management system with a YOLO model and visualization settings.Ú	json_filezGParkingManagement requires `json_file` with parking region coordinates.u#   â�Œ JSON file path cannot be empty.r   r€   Nr   )Ú	OccupancyÚ	Available)r   r   éÿ   )r   r�   r   )r�   r   é½   r–   )Úsuperr>   ÚCFGrš   r   r   Ú
ValueErrorrN   r†   ÚloadÚpr_infoÚarcÚoccÚdc)r9   Úkwargsr�   Ú	__class__s      €r=   r>   zParkingManagement.__init__Ë   sš   ø€ ä‰ÑÑ"˜6Ò"àŸ™ +Ñ.ˆŒØ�~Š~Ü�N‰NÐdÔeÜÐBÓCÐCä�$—.‘.¨7Ô3ð 	%°qÜŸ	™	 !›ˆDŒI÷	%ð &'°QÑ7ˆŒàˆŒØˆŒØˆ�÷	%ð 	%ús   Á(B+Â+B4c                ó(  — | j                  |«       t        | j                  «      d}}t        || j                  «      }| j                  D �]*  }t        j                  |d   t
        j                  ¬«      j                  d«      }d}t        | j                  | j                  «      D ]Œ  \  }}	t        |d   |d   z   dz  «      t        |d   |d   z   dz  «      }}
t        j                  ||
|fd«      }|dk\  sŒS|j                  || j                   j"                  t        |	«         d	d
|
|d«       d} n |r
|dz  }|dz  }t        j$                  ||gd|r| j&                  n| j(                  d¬«       �Œ- ||c| j*                  d<   | j*                  d<   |j-                  || j*                  d	d
d«       |j/                  «       }| j1                  |«       t3        || j*                  d   | j*                  d   t        | j4                  «      ¬«      S )a�  Process the input image for parking lot management and visualization.

        This function analyzes the input image, extracts tracks, and determines the occupancy status of parking regions
        defined in the JSON file. It annotates the image with occupied and available parking spots, and updates the
        parking information.

        Args:
            im0 (np.ndarray): The input inference image.

        Returns:
            (SolutionResults): Contains processed image `plot_im`, 'filled_slots' (number of occupied parking slots),
                'available_slots' (number of available parking slots), and 'total_tracks' (total number of
                tracked objects).

        Examples:
            >>> parking_manager = ParkingManagement(json_file="parking_regions.json")
            >>> image = cv2.imread("parking_lot.jpg")
            >>> results = parking_manager.process(image)
        r   r{   )Údtype)éÿÿÿÿrF   rm   Frm   rF   r_   )éh   é   é   )r�   r�   r�   é
   T)ÚisClosedÚcolorÚ	thicknessr›   rœ   )Úplot_imÚfilled_slotsÚavailable_slotsÚtotal_tracks)Úextract_tracksrg   r†   r   Ú
line_widthÚnpÚarrayÚint32ÚreshapeÚzipÚboxesÚclssrQ   Úcv2ÚpointPolygonTestÚdisplay_objects_labelsÚmodelÚnamesÚ	polylinesr¥   r¤   r£   Údisplay_analyticsÚresultÚdisplay_outputr   Ú	track_ids)r9   Úim0rµ   Úoccupied_slotsÚ	annotatorÚregionÚregion_polygonÚregion_occupiedrp   ÚclsÚxcÚycÚinside_distancer³   s                 r=   ÚprocesszParkingManagement.processÝ   s÷  € ð( 	×Ñ˜CÔ Ü*-¨d¯i©i«.¸!˜ˆÜ% c¨4¯?©?Ó;ˆ	à—i‘ió 	ˆFäŸX™X f¨XÑ&6¼b¿h¹hÔG×OÑOÐPZÓ[ˆNØ#ˆOÜ §
¡
¨D¯I©IÓ6ò 	‘��SÜ˜c !™f s¨1¡v™o°Ñ2Ó3´S¸#¸a¹&À3ÀqÁ6¹/ÈQÑ9NÓ5O�B�Ü"%×"6Ñ"6°~ÈÈBÀxÐQVÓ"W�Ø" aÓ'à×4Ñ4Ø˜TŸZ™Z×-Ñ-¬c°#«hÑ7¸ÈÐY[Ð]_Ðacôð '+�OÙð	ñ Ø !Ñ#�Ø 1Ñ$�ä�M‰MØ�nÐ%°É¸D¿HºHÐ]a×]eÑ]eÐqr÷ð%	ð, @NÈÐ<ˆ�‰�[Ñ! 4§<¡<°Ñ#<à×#Ñ# C¨¯©°}ÀoÐWYÔZà×"Ñ"Ó$ˆØ×Ñ˜GÔ$ô ØØŸ™ kÑ2Ø ŸL™L¨Ñ5Ü˜TŸ^™^Ó,ô	
ð 	
rA   )r§   r   r�   r‘   )rÊ   z
np.ndarrayr�   r   )r’   r“   r”   r•   r>   rÔ   Ú__classcell__)r¨   s   @r=   r˜   r˜   ³   s   ø„ ñõ. ÷$;
rA   r˜   )Ú
__future__r   r†   Útypingr   rÀ   Únumpyr¹   Úultralytics.solutions.solutionsr   r   r   Úultralytics.utilsr   Úultralytics.utils.checksr	   r   r˜   r–   rA   r=   ú<module>rÜ      s?   ðõ #ã Ý ã 
Û ç \Ñ \Ý $Ý 1÷`[ñ `[ôFe
˜õ e
rA   