
    j%                        d dl mZ d dlZd dlmZ d dlmZ d dlZd dl	m
Z
 d dlmZ d dlmZmZ d dlmZ d d	lmZmZ d
ej        d<    G d d          Z G d d          ZdS )    )annotationsN)Path)Any)Image)IMG_FORMATS)LOGGERTORCH_VERSION)check_requirements)	TORCH_2_4select_deviceTRUEKMP_DUPLICATE_LIB_OKc                  D    e Zd ZdZddZdd
ZddZddZdddZd dZ	dS )!VisualAISearcha  A semantic image search system that leverages OpenCLIP for generating high-quality image and text embeddings and
    FAISS for fast similarity-based retrieval.

    This class aligns image and text embeddings in a shared semantic space, enabling users to search large collections
    of images using natural language queries with high accuracy and speed.

    Attributes:
        data (str): Directory containing images.
        device (str): Computation device, e.g., 'cpu' or 'cuda'.
        faiss_index (str): Path to the FAISS index file.
        data_path_npy (str): Path to the numpy file storing image paths.
        data_dir (Path): Path object for the data directory.
        model: Loaded CLIP model.
        index: FAISS index for similarity search.
        image_paths (list[str]): List of image file paths.

    Methods:
        extract_image_feature: Extract CLIP embedding from an image.
        extract_text_feature: Extract CLIP embedding from text.
        load_or_build_index: Load existing FAISS index or build new one.
        search: Perform semantic search for similar images.

    Examples:
        Initialize and search for images
        >>> searcher = VisualAISearch(data="path/to/images", device="cuda")
        >>> results = searcher.search("a cat sitting on a chair", k=10)
    kwargsr   returnNonec                   t           sJ dt           d            ddlm} t	          d           t          d          | _        d| _        d| _        t          |
                    d	d
                    | _        t          |
                    dd                    | _        | j                                        sPddlm} t#          j        | j         d| d           ddlm}  || ddd           t          d
          | _         |d| j                  | _        d| _        g | _        |                                  dS )zDInitialize the VisualAISearch class with FAISS index and CLIP model.z1VisualAISearch requires torch>=2.4 (found torch==)r   )build_text_modelz	faiss-cpufaisszfaiss.indexz	paths.npydataimagesdevicecpu)
ASSETS_URLz( not found. Downloading images.zip from z/images.zip)safe_downloadT   )urlunzipretryzclip:ViT-B/32)r   N)r   r	   ultralytics.nn.text_modelr   r
   
__import__r   faiss_indexdata_path_npyr   getdata_dirr   r   existsultralytics.utilsr   r   warningultralytics.utils.downloadsr   modelindeximage_pathsload_or_build_index)selfr   r   r   r   s        l/home/longshao/multi-rider-rag/.venv/lib/python3.11/site-packages/ultralytics/solutions/similarity_search.py__init__zVisualAISearch.__init__1   se   ^^^m^^^^^y>>>>>>;'''((
((VZZ99::#FJJx$?$?@@}##%% 	+444444NdmllU_lllmmmAAAAAAM888ANNNN NNDM%%odkJJJ

  """""    pathr   
np.ndarrayc                    | j                             t          j        |                                                                                                                    S )z7Extract CLIP image embedding from the given image path.)r,   encode_imager   opendetachr   numpy)r0   r4   s     r1   extract_image_featurez$VisualAISearch.extract_image_featureN   sF    z&&uz$'7'788??AAEEGGMMOOOr3   textstrc                    | j                             | j                             |g                                                                                                                    S )z6Extract CLIP text embedding from the given text query.)r,   encode_texttokenizer9   r   r:   )r0   r<   s     r1   extract_text_featurez#VisualAISearch.extract_text_featureR   sN    z%%dj&9&94&&A&ABBIIKKOOQQWWYYYr3   c                B   t          | j                                                  r~t          | j                                                  rXt	          j        d           | j                            | j                  | _        t          j
        | j                  | _        dS t	          j        d           g }| j                                        D ]}|j                                                            d          t"          vr6	 |                    |                     |                     | j                            |j                   # t*          $ r)}t	          j        d|j         d|            Y d}~d}~ww xY w|st/          d          t          j        |                              d          }| j                            |           | j                            |j        d	                   | _        | j                            |           | j                            | j        | j                   t          j        | j        t          j         | j                             t	          j        d
tC          | j                   d           dS )ae  Load existing FAISS index or build a new one from image features.

        Checks if FAISS index and image paths exist on disk. If found, loads them directly. Otherwise, builds a new
        index by extracting features from all images in the data directory, normalizes the features, and saves both the
        index and image paths for future use.
        zLoading existing FAISS index...Nz#Building FAISS index from images....z	Skipping z: z'No image embeddings could be generated.float32   zIndexed z images.)"r   r$   r(   r%   r   infor   
read_indexr-   nploadr.   r'   iterdirsuffixlowerlstripr   appendr;   name	Exceptionr*   RuntimeErrorvstackastypenormalize_L2IndexFlatIPshapeaddwrite_indexsavearraylen)r0   vectorsfilees       r1   r/   z"VisualAISearch.load_or_build_indexV   sd     !!((** 	tD4F/G/G/N/N/P/P 	K9:::..t/?@@DJ!wt'9::DF 	9::: M))++ 		= 		=D{  ""))#..kAA=t99$??@@@ ''	2222 = = =;49;;;;<<<<<<<<=  	JHIII)G$$++I66
(((Z++GM!,<==

w
tz4+;<<<
"BHT-=$>$>???>s4#344>>>?????s   AE
FFF   皙?querykintsimilarity_threshfloat	list[str]c                   	                       |                              d          } j                            |            j                            ||          \  	}	 fdt          |d                   D             }|                    d d           t          j	        d           |D ] \  }}t          j	        d| d	|d
           !d |D             S )al  Return top-k semantically similar images to the given query.

        Args:
            query (str): Natural language text query to search for.
            k (int, optional): Maximum number of results to return.
            similarity_thresh (float, optional): Minimum similarity threshold for filtering results.

        Returns:
            (list[str]): List of image filenames ranked by similarity score.

        Examples:
            Search for images matching a query
            >>> searcher = VisualAISearch(data="images")
            >>> results = searcher.search("red car", k=5, similarity_thresh=0.2)
        rD   c                    g | ]?\  }}d          |         k    j         |         t          d          |                   f@S r   )r.   re   ).0idxiDr0   rd   s      r1   
<listcomp>z)VisualAISearch.search.<locals>.<listcomp>   sY     
 
 
8>QYZ[\Y]^aYbfwYwYwTa %!S	"2"23YwYwYwr3   r   c                    | d         S )NrE    )xs    r1   <lambda>z'VisualAISearch.search.<locals>.<lambda>   s
    1Q4 r3   T)keyreversez
Ranked Results:z  - z | Similarity: z.4fc                    g | ]
}|d          S ri   rp   )rj   rs     r1   rn   z)VisualAISearch.search.<locals>.<listcomp>   s    &&&!&&&r3   )
rA   rS   r   rT   r-   search	enumeratesortr   rF   )
r0   ra   rb   rd   	text_featr-   resultsrO   scorerm   s
   `  `     @r1   rw   zVisualAISearch.search   s     --e44;;IFF	
	***:$$Y225
 
 
 
 
 
BKERSHBUBU
 
 
 	666'(((" 	A 	AKD%K?t??E???@@@@&&g&&&&r3   c                ,    |                      |          S )z.Direct call interface for the search function.)rw   )r0   ra   s     r1   __call__zVisualAISearch.__call__   s    {{5!!!r3   N)r   r   r   r   )r4   r   r   r5   )r<   r=   r   r5   )r   r   )r_   r`   )ra   r=   rb   rc   rd   re   r   rf   )ra   r=   r   rf   )
__name__
__module____qualname____doc__r2   r;   rA   r/   rw   r~   rp   r3   r1   r   r      s         8# # # #:P P P PZ Z Z Z*@ *@ *@ *@X' ' ' ' '>" " " " " "r3   r   c                  .    e Zd ZdZddd
ZddZdddZdS )	SearchAppa  A Flask-based web interface for semantic image search with natural language queries.

    This class provides a clean, responsive frontend that enables users to input natural language queries and instantly
    view the most relevant images retrieved from the indexed database.

    Attributes:
        render_template: Flask template rendering function.
        request: Flask request object.
        searcher (VisualAISearch): Instance of the VisualAISearch class.
        app (Flask): Flask application instance.

    Methods:
        index: Process user queries and display search results.
        run: Start the Flask web application.

    Examples:
        Start a search application
        >>> app = SearchApp(data="path/to/images", device="cuda")
        >>> app.run(debug=True)
    r   Nr   r=   r   
str | Noner   r   c                8   t          d           ddlm}m}m} || _        || _        t          ||          | _         |t          dt          |          	                                d          | _
        | j
                            d| j        d	d
g           dS )zInitialize the SearchApp with VisualAISearch backend.

        Args:
            data (str, optional): Path to directory containing images to index and search.
            device (str, optional): Device to run inference on (e.g. 'cpu', 'cuda').
        zflask>=3.0.1r   )Flaskrender_templaterequest)r   r   	templatesz/images)template_folderstatic_folderstatic_url_path/GETPOST)	view_funcmethodsN)r
   flaskr   r   r   r   searcherr   r   resolveappadd_url_ruler-   )r0   r   r   r   r   r   s         r1   r2   zSearchApp.__init__   s     	>***9999999999.&D@@@5't**,,..%	
 
 
 	cTZ%QQQQQr3   c                    g }| j         j        dk    rG| j         j                            dd                                          }|                     |          }|                     d|          S )zCProcess user query and display search results in the web interface.r   ra    zsimilarity-search.html)r{   )r   methodformr&   stripr   r   )r0   r{   ra   s      r1   r-   zSearchApp.index   sh    <&((L%))'266<<>>EmmE**G##$<g#NNNr3   Fdebugboolc                <    | j                             |           dS )z'Start the Flask web application server.)r   N)r   run)r0   r   s     r1   r   zSearchApp.run   s    5!!!!!r3   )r   N)r   r=   r   r   r   r   )r   r=   )F)r   r   r   r   )r   r   r   r   r2   r-   r   rp   r3   r1   r   r      sm         *R R R R R*O O O O" " " " " " "r3   r   )
__future__r   ospathlibr   typingr   r:   rH   PILr   ultralytics.data.utilsr   r)   r   r	   ultralytics.utils.checksr
   ultralytics.utils.torch_utilsr   r   environr   r   rp   r3   r1   <module>r      s(   # " " " " " 				                       . . . . . . 3 3 3 3 3 3 3 3 7 7 7 7 7 7 B B B B B B B B%+
! "O" O" O" O" O" O" O" O"d5" 5" 5" 5" 5" 5" 5" 5" 5" 5"r3   