
    h!%                         d dl Z d dlmZ d dlmZmZ d dlZd dlm	Z	 d dl
mZ d dlmZ d dlmZ d dlmZ d	e j$                  d
<    G d d      Z G d d      Zy)    N)Path)AnyList)Image)IMG_FORMATS)LOGGER)check_requirements)select_deviceTRUEKMP_DUPLICATE_LIB_OKc            
           e Zd ZdZdeddfdZdedej                  fdZ	de
dej                  fd	Zdd
Zdde
dededee
   fdZde
dee
   fdZy)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)
    kwargsreturnNc                 "   ddl m} t        d       t        d      | _        d| _        d| _        t        |j                  dd            | _	        t        |j                  d	d
            | _        | j                  j                         sOddlm} t        j                   | j                   d| d       ddlm}  || ddd       t        d      | _	         |d| j                        | _        d| _        g | _        | j-                          y)zDInitialize the VisualAISearch class with FAISS index and CLIP model.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)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        e/var/www/html/eduruby.in/venv/lib/python3.12/site-packages/ultralytics/solutions/similarity_search.py__init__zVisualAISearch.__init__0   s    >;'(
((VZZ9:#FJJx$?@}}##%4NNdmm_,TU_T``klmAK8AN NDM%odkkJ

  "    pathc                     | j                   j                  t        j                  |            j	                         j                         S )z7Extract CLIP image embedding from the given image path.)r(   encode_imager   openr   numpy)r,   r0   s     r-   extract_image_featurez$VisualAISearch.extract_image_featureL   s2    zz&&uzz$'78<<>DDFFr/   textc                     | j                   j                  | j                   j                  |g            j                         j	                         S )z6Extract CLIP text embedding from the given text query.)r(   encode_texttokenizer   r4   )r,   r6   s     r-   extract_text_featurez#VisualAISearch.extract_text_featureP   s:    zz%%djj&9&94&&ABFFHNNPPr/   c                    t        | j                        j                         rt        | j                        j                         rdt	        j
                  d       | j                  j                  | j                        | _        t        j                  | j                        | _        yt	        j
                  d       g }| j                  j                         D ]x  }|j                  j                         j!                  d      t"        vr3	 |j%                  | j'                  |             | j                  j%                  |j(                         z |st/        d      t        j0                  |      j3                  d      }| j                  j5                  |       | j                  j7                  |j8                  d	         | _        | j                  j;                  |       | j                  j=                  | j                  | j                         t        j>                  | j                  t        j@                  | j                               t	        j
                  d
tC        | j                         d       y# t*        $ r0}t	        j,                  d|j(                   d|        Y d}~d}~ww xY w)an  
        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   appendr5   name	Exceptionr&   RuntimeErrorvstackastypenormalize_L2IndexFlatIPshapeaddwrite_indexsavearraylen)r,   vectorsfilees       r-   r+   z"VisualAISearch.load_or_build_indexT   s      !((*tD4F4F/G/N/N/PKK9:..t/?/?@DJ!wwt'9'9:D 	9: MM))+ 		=D{{  "))#.kA=t99$?@  ''		2		= HII))G$++I6

(ZZ++GMM!,<=


w

tzz4+;+;<
""BHHT-=-=$>?hs4#3#345X>?  =499+Rs;<<=s   AJ	J>%J99J>queryksimilarity_threshc           	      $   | j                  |      j                  d      }| j                  j                  |       | j                  j                  ||      \  }}t        |d         D cg c]1  \  }}|d   |   |k\  s| j                  |   t        |d   |         f3 }	}}|	j                  d d       t        j                  d       |	D ]!  \  }
}t        j                  d|
 d|d	       # |	D cg c]  }|d   	 c}S c c}}w c c}w )
au  
        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)
        r=   r   c                     | d   S )Nr>    )xs    r-   <lambda>z'VisualAISearch.search.<locals>.<lambda>   s
    1Q4 r/   T)keyreversez
Ranked Results:z  - z | Similarity: z.4f)r:   rL   r   rM   r)   search	enumerater*   floatsortr   r?   )r,   rX   rY   rZ   	text_featDr)   idxiresultsrH   scorers                r-   rb   zVisualAISearch.search   s   " --e4;;IF	

	*::$$Y25BKERSHBU
8>QYZ[\Y]^aYbfwYwTa %!S	"23
 
 	6'(" 	AKD%KK$tfOE#;?@	A &&!&&
 's   ,D "D8Dc                 $    | j                  |      S )z.Direct call interface for the search function.)rb   )r,   rX   s     r-   __call__zVisualAISearch.__call__   s    {{5!!r/   )r   N)   g?)__name__
__module____qualname____doc__r   r.   r   rA   ndarrayr5   strr:   r+   intrd   r   rb   rn   r]   r/   r-   r   r      s    :# # #8G$ G2:: GQ Q Q+@Z'C 'C ' 'QUVYQZ '@"c "d3i "r/   r   c                   D    e Zd ZdZd
dededdfdZdefdZddeddfd	Zy)	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)
    Nr   r   r   c                    t        d       ddlm}m}m} || _        || _        t        ||      | _         |t        dt        |      j                         d      | _
        | j                  j                  d| j                  d	d
g       y)a  
        Initialize 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	   flaskrz   r{   r|   r   searcherrp   r   resolveappadd_url_ruler)   )r,   r   r   rz   r{   r|   s         r-   r.   zSearchApp.__init__   sw     	>*99.&D@'t*,,.%	
 	cTZZ%Qr/   c                     g }| j                   j                  dk(  rE| j                   j                  j                  dd      j	                         }| j                  |      }| j                  d|      S )zCProcess user query and display search results in the web interface.r   rX    zsimilarity-search.html)rj   )r|   methodformr"   stripr   r{   )r,   rj   rX   s      r-   r)   zSearchApp.index   sc    <<&(LL%%))'26<<>EmmE*G##$<g#NNr/   debugc                 <    | j                   j                  |       y)z'Start the Flask web application server.)r   N)r   run)r,   r   s     r-   r   zSearchApp.run   s    5!r/   )r   N)F)	rp   rq   rr   rs   ru   r.   r)   boolr   r]   r/   r-   rx   rx      sF    ,RS RS RD R,Os O" "$ "r/   rx   )ospathlibr   typingr   r   r4   rA   PILr   ultralytics.data.utilsr   r%   r   ultralytics.utils.checksr	   ultralytics.utils.torch_utilsr
   environr   rx   r]   r/   r-   <module>r      sH    
     . $ 7 7%+

! "Q" Q"h7" 7"r/   