Инструмент для поиска и сравнения похожих изображений с использованием современных алгоритмов компьютерного зрения
Similar Image Finder - это инструмент, который позволяет:
- Находить похожие изображения в больших наборах данных
- Сравнивать изображения по различным метрикам
- Кластеризовать изображения по схожести
- Визуализировать результаты сравнения
# Клонирование репозитория
git clone https://github.com/Mangust212/similar-image.git
# Установка зависимостей
pip install -r requirements.txtfrom similar_image import ImageMatcher
# Инициализация
matcher = ImageMatcher()
# Загрузка изображений
matcher.add_reference_image("path/to/reference.jpg")
# Поиск похожих
results = matcher.find_similar("path/to/query.jpg")Проект использует следующие алгоритмы:
- Перцептивный хэш (pHash)
- SIFT/SURF дескрипторы
- CNN-based features
- Cosine similarity
# Поиск похожих изображений
POST /api/v1/search
Content-Type: multipart/form-data
# Параметры:
- image: файл изображения
- threshold: порог схожести (0-1)
- limit: максимальное количество результатовМы приветствуем ваш вклад в проект!
- Форкните репозиторий
- Создайте ветку для новой функции
- Внесите изменения
- Создайте Pull Request
similar-image/
├── src/
│ ├── core/
│ │ ├── matcher.py
│ │ ├── features.py
│ │ └── utils.py
│ ├── api/
│ │ ├── routes.py
│ │ └── schemas.py
│ └── ui/
│ ├── web/
│ └── desktop/
├── tests/
│ ├── test_matcher.py
│ └── test_api.py
├── docs/
│ ├── API.md
│ └── ALGORITHMS.md
└── examples/
├── basic_usage.py
└── api_example.py
# Базовый пример
from similar_image import ImageMatcher
matcher = ImageMatcher(algorithm='phash')
matcher.index_directory('path/to/images')
similar = matcher.find_similar('query.jpg', threshold=0.8)
# С использованием нейронных сетей
matcher = ImageMatcher(algorithm='cnn')
matcher.set_model('resnet50')
similar = matcher.find_similar('query.jpg', top_k=5)GNU Affero General Public License v3.0
- Python 3.8+
- OpenCV
- PyTorch
- FastAPI (для API)
- NumPy
Предлагаю создать основные файлы проекта:
1. Основной класс для сравнения изображений:
```python name=src/core/matcher.py
from typing import List, Tuple
import numpy as np
import cv2
from pathlib import Path
class ImageMatcher:
"""Класс для поиска похожих изображений."""
def __init__(self, algorithm: str = 'phash'):
"""
Инициализация матчера.
Args:
algorithm (str): Алгоритм сравнения ('phash', 'sift', 'cnn')
"""
self.algorithm = algorithm
self.reference_images = {}
def add_reference_image(self, path: str) -> None:
"""
Добавление эталонного изображения.
Args:
path (str): Путь к изображению
"""
img = cv2.imread(path)
features = self._extract_features(img)
self.reference_images[path] = features
def find_similar(self, query_path: str, threshold: float = 0.8) -> List[Tuple[str, float]]:
"""
Поиск похожих изображений.
Args:
query_path (str): Путь к искомому изображению
threshold (float): Порог схожести
Returns:
List[Tuple[str, float]]: Список путей и степеней схожести
"""
query_img = cv2.imread(query_path)
query_features = self._extract_features(query_img)
results = []
for ref_path, ref_features in self.reference_images.items():
similarity = self._compute_similarity(query_features, ref_features)
if similarity >= threshold:
results.append((ref_path, similarity))
return sorted(results, key=lambda x: x[1], reverse=True)
def _extract_features(self, img: np.ndarray) -> np.ndarray:
"""Извлечение признаков из изображения."""
if self.algorithm == 'phash':
return self._compute_phash(img)
elif self.algorithm == 'sift':
return self._compute_sift(img)
elif self.algorithm == 'cnn':
return self._compute_cnn_features(img)
def _compute_similarity(self, features1: np.ndarray, features2: np.ndarray) -> float:
"""Вычисление степени схожести между наборами признаков."""
return np.dot(features1, features2) / (np.linalg.norm(features1) * np.linalg.norm(features2))
- API интерфейс:
from fastapi import FastAPI, UploadFile, File
from fastapi.responses import JSONResponse
from typing import List
import shutil
import tempfile
from pathlib import Path
from ..core.matcher import ImageMatcher
app = FastAPI(title="Similar Image API")
matcher = ImageMatcher()
@app.post("/api/v1/search")
async def search_similar(
image: UploadFile = File(...),
threshold: float = 0.8,
limit: int = 10
) -> JSONResponse:
"""
Поиск похожих изображений.
Args:
image: Загруженное изображение
threshold: Порог схожести (0-1)
limit: Максимальное количество результатов
Returns:
JSONResponse с результатами поиска
"""
# Сохраняем загруженное изображение
with tempfile.NamedTemporaryFile(delete=False) as tmp:
shutil.copyfileobj(image.file, tmp)
try:
# Ищем похожие изображения
results = matcher.find_similar(
tmp.name,
threshold=threshold
)[:limit]
return JSONResponse({
"status": "success",
"results": [
{
"path": path,
"similarity": float(score)
}
for path, score in results
]
})
finally:
# Удаляем временный файл
Path(tmp.name).unlink()- Конфигурация и требования:
numpy>=1.19.0
opencv-python>=4.5.0
torch>=1.9.0
fastapi>=0.68.0
python-multipart>=0.0.5
uvicorn>=0.15.0
pillow>=8.3.0
scikit-learn>=0.24.0- Пример использования:
from similar_image import ImageMatcher
def main():
# Инициализация матчера
matcher = ImageMatcher(algorithm='phash')
# Добавление эталонных изображений
matcher.add_reference_image('reference1.jpg')
matcher.add_reference_image('reference2.jpg')
# Поиск похожих
results = matcher.find_similar('query.jpg', threshold=0.8)
# Вывод результатов
for path, similarity in results:
print(f"Found similar image: {path} (similarity: {similarity:.2f})")
if __name__ == '__main__':
main()- Добавим GitHub Actions для тестирования:
name: Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.8'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest
- name: Run tests
run: |
pytest tests/Хотите, чтобы я создал pull request с этими изменениями? Также я могу:
- Добавить больше алгоритмов сравнения изображений
- Реализовать веб-интерфейс для удобного использования
- Добавить документацию по API
- Создать примеры использования с различными наборами данных
Что бы вы хотели реализовать в первую очередь?