{"id":22378027,"url":"https://github.com/manuelfay/imagesearcher","last_synced_at":"2025-07-30T23:32:32.474Z","repository":{"id":46328707,"uuid":"383264319","full_name":"ManuelFay/ImageSearcher","owner":"ManuelFay","description":"This repository aims to implement an Image Search engine powered by the CLIP model.","archived":false,"fork":false,"pushed_at":"2022-07-15T14:44:57.000Z","size":2199,"stargazers_count":46,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-22T12:54:03.788Z","etag":null,"topics":["clip","google","google-image-search","image","image-search-engine","neural-image-search","openai","python","search","search-engine"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ManuelFay.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-05T21:05:34.000Z","updated_at":"2025-05-21T07:52:43.000Z","dependencies_parsed_at":"2022-08-29T19:10:49.705Z","dependency_job_id":null,"html_url":"https://github.com/ManuelFay/ImageSearcher","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/ManuelFay/ImageSearcher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ManuelFay%2FImageSearcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ManuelFay%2FImageSearcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ManuelFay%2FImageSearcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ManuelFay%2FImageSearcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ManuelFay","download_url":"https://codeload.github.com/ManuelFay/ImageSearcher/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ManuelFay%2FImageSearcher/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267960714,"owners_count":24172506,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clip","google","google-image-search","image","image-search-engine","neural-image-search","openai","python","search","search-engine"],"created_at":"2024-12-04T22:16:53.562Z","updated_at":"2025-07-30T23:32:32.072Z","avatar_url":"https://github.com/ManuelFay.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ImageSearcher\n### Leveraging CLIP to perform image search on personal pictures\n\nThis repository implements an Image Search engine on local photos powered by the CLIP model.\nIt is surprisingly precise and is able to find images given complex queries. For more information, refer to\nthe Medium blogpost [here](https://medium.com/@manuelfaysse/building-a-powerful-image-search-engine-for-your-pictures-using-deep-learning-16d06df10385?source=friends_link\u0026sk=ca5130cb63a1fcb3a3e3f54ff494e56b).\n\nThe added functionality of classifying pictures depending on the persons portrayed is implemented \nwith the `face_recognition` library. Several filters are also available, enabling you to find your \ngroup pictures, screenshots, etc...\n\n## Setup\n\nIn a Python 3.8+ virtual environment, install either from PIP or from source:\n\n#### Installation from the PIP package:\n```bash\npip install image-searcher\n\npip install face_recognition  # Optional to enable face features\npip install flask flask_cors  # Optional to enable a flask api\n```\n\n#### Installation from source\n```bash\npip install -r dev_requirements.txt\n\npip install face_recognition  # Optional to enable face features\npip install flask flask_cors  # Optional to enable a flask api\n```\n\nTroubleshooting: If problems are encountered building wheels for dlib during the face_recognition installation, make sure to install the `python3.8-dev`\npackage (respectively `python3.x-dev`) and recreate the virtual environment from scratch with the aforementionned command \nonce it is installed.\n\n## Usage\nCurrently, the usage is as follows. The library first computes the embeddings of all images one by one, and stores them in \na picked dictionary for further reference. To compute and store information about the persons in \nthe picture, enable the `include_faces` flag (note that it makes the indexing process up to 10x slower).\n\n```python\nfrom image_searcher import Search\n\nsearcher = Search(image_dir_path=\"/home/manu/perso/ImageSearcher/data/\", \n                  traverse=True, \n                  include_faces=False)\n```\n\nOnce this process has been done once, through Python, the library is used as such:\n```python\nfrom image_searcher import Search\n\nsearcher = Search(image_dir_path=\"/home/manu/perso/ImageSearcher/data/\", \n                  traverse=True, \n                  include_faces=False)\n\n# Option 1: Pythonic API\nfrom PIL import Image\n\nranked_images = searcher.rank_images(\"A photo of a bird.\", n=5)\nfor image in ranked_images:\n    Image.open(image.image_path).convert('RGB').show()\n\n# Option 2: Launch Flask api from code\nfrom image_searcher.api import run\nrun(searcher=searcher)\n```\n\n### Using tags in the query\nAdding tags at the end of the query (example: `A bird singing #photo`) will filter the search based on the tag list.\nSupported tags for the moment are:\n  - \\#{category}: Amongst \"screenshot\", \"drawing\", \"photo\", \"schema\", \"selfie\"\n  - \\#groups: Group pictures (more than 5 people)\n\nTo come is support for:\n  \n  - \\#dates: Filtering based on the time period\n\n\n### Running through the API for efficient use\n\nAfter having indexed the images of interest, a Flask API can be used to load models once and then search efficiently.\n\n#### Specify a Config YAML file:\n  \n```yaml\nimage_dir_path: /home/manu/Downloads/facebook_logs/messages/inbox/\nsave_path: /home/manu/\ntraverse: true\ninclude_faces: true\nreindex: false\nn: 42\n\nport:\nhost:\ndebug:\nthreaded:\n```\n#### Start a server:\n```python\nfrom image_searcher.api import run\n\n# Option 1: Through a config file\nrun(config_path=\"path_to_config_file.yml\")\n\n# Option 2: Through an instanciated Search object\nfrom image_searcher import Search\n\nrun(searcher=Search(image_dir_path=\"/home/manu/perso/ImageSearcher/data/\", \n                    traverse=True, \n                    include_faces=False))\n```\n\nA gunicorn process can also be launched locally with:\n\n```bash\ngunicorn \"api.run_flask_gunicorn:create_app('path_to_config_file.yml')\" \\\n    --name image_searcher \\\n    --bind 0.0.0.0:${GUNICORN_PORT:-5000} \\\n    --worker-tmp-dir /dev/shm \\\n    --workers=${GUNICORN_WORKERS:-2} \\\n    --threads=${GUNICORN_THREADS:-4} \\\n    --worker-class=gthread \\\n    --log-level=info \\\n    --log-file '-' \\\n    --timeout 30\n```\n\nNote: Adapt the timeout parameter (in seconds) if a lot of new images are being indexed/\n\n\n#### Query it:\n\n- By opening in a browser the webpage with the demo search engine `search.html`.\n\n- Through the API endpoint online: `http://127.0.0.1:5000/get_best_images?q=a+photo+of+a+bird`\n\n- In Python:\n```python\nimport requests\nimport json\nimport urllib.parse\n\nquery = \"a photo of a bird\"\nr = requests.get(f\"http://127.0.0.1:5000/get_best_images?q={urllib.parse.quote(query)}\")\nprint(json.loads(r.content)[\"results\"])\n```\n### Tips\n\nUsing this tool with vacation photos, or Messenger and Whatsapp photo archives leads to rediscovering \nold photos and is amazing at locating long lost ones.\n\n## Tests\n\nRun the tests with \n\n```bash\npython -m unittest\n```\n\nand lint with:\n\n```bash\npylint image_searcher\n```\n\n## Contributing\n\nThis repo is a work in progress that has recently been started. As is, it computes about 10 images per second during the initial indexing phase, then is almost instantaneous during the querying phase.\n\nFeature requests and contributions are welcomed. Improvements to the Search Web interface would also\nbe greatly appreciated !\n\n## Todo list\n\nSimplify and robustify the Search class instanciation:\n- Check indexation arguments are compatible with pre-loaded file\n- Store indexation arguments in pre-loaded file and give option to index new pictures with these options\n- Add the option to index for faces on previously CLIP indexed images\n\nSpeed:\n- Parallel indexation / dynamic batching based on image size\n- Data loader before indexation\n- Optimized vector computation with optimized engine (FAISS)\n\nFeatures:\n- Image auto-tagging (screenshot, drawing, photo, nature, group picture, selfie, etc)\n- Image deduplication (perceptual hashing)\n\nEmbedding files:\n- Integrate with local version control (git-lfs ?)\n\nFrontend:\n- Overall UX and design changes\n- Enable Image upload\n\nDeployment:\n- Dockerize and orchestrate containers (image uploader, storage, indexation pipeline, inference)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanuelfay%2Fimagesearcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmanuelfay%2Fimagesearcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanuelfay%2Fimagesearcher/lists"}