Программа для поиска фотографий с совпадающими лицами

В современном мире, где фотографии играют ключевую роль в нашей жизни, найти определенное изображение среди сотен или тысяч файлов может быть настоящим испытанием. Особенно, если речь идет о фотографиях с похожими лицами. Для решения этой задачи была создана простая и удобная программа на Python с графическим интерфейсом, которая автоматически находит фотографии, соответствующие заданному эталону лица.

Как работает программа?

Эта программа использует библиотеку OpenCV, одну из самых популярных библиотек для обработки изображений и распознавания лиц. С ее помощью программа анализирует изображения и сравнивает лица на них с эталонным изображением. Если уровень совпадения превышает заданный пользователем порог, фотография сохраняется в указанной папке.

import cv2
import os
import shutil
import tkinter as tk
from tkinter import filedialog, messagebox

def find_matching_faces(face_image_path, photos_folder, output_folder, similarity_threshold):
    reference_image = cv2.imread(face_image_path)
    if reference_image is None:
        messagebox.showerror("Ошибка", "Не удалось загрузить эталонное изображение.")
        return

    gray_reference = cv2.cvtColor(reference_image, cv2.COLOR_BGR2GRAY)
    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

    reference_faces = face_cascade.detectMultiScale(gray_reference, scaleFactor=1.1, minNeighbors=5)
    if len(reference_faces) == 0:
        messagebox.showerror("Ошибка", "Лицо на эталонном изображении не найдено.")
        return

    x, y, w, h = reference_faces[0]
    reference_face = gray_reference[y:y+h, x:x+w]

    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    matches_found = 0
    for filename in os.listdir(photos_folder):
        file_path = os.path.join(photos_folder, filename)
        if not filename.lower().endswith(('.png', '.jpg', '.jpeg')):
            continue

        image = cv2.imread(file_path)
        gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        detected_faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.1, minNeighbors=5)

        for (x, y, w, h) in detected_faces:
            detected_face = gray_image[y:y+h, x:x+w]
            res = cv2.matchTemplate(reference_face, detected_face, cv2.TM_CCOEFF_NORMED)
            similarity = res.max()

            if similarity >= similarity_threshold:
                shutil.copy(file_path, os.path.join(output_folder, filename))
                matches_found += 1
                break

    messagebox.showinfo("Результат", f"Найдено совпадений: {matches_found}. Результаты сохранены в папке {output_folder}.")

def select_face_image():
    file_path = filedialog.askopenfilename(title="Выберите эталонное изображение", filetypes=[("Image Files", "*.jpg *.jpeg *.png")])
    if file_path:
        face_image_path.set(file_path)

def select_photos_folder():
    folder_path = filedialog.askdirectory(title="Выберите папку с фотографиями")
    if folder_path:
        photos_folder_path.set(folder_path)

def select_output_folder():
    folder_path = filedialog.askdirectory(title="Выберите папку для сохранения совпадений")
    if folder_path:
        output_folder_path.set(folder_path)

def run_matching():
    if not face_image_path.get() or not photos_folder_path.get() or not output_folder_path.get():
        messagebox.showerror("Ошибка", "Укажите все пути.")
        return

    similarity_threshold = similarity_slider.get() / 100  # Преобразование значения из ползунка в диапазон [0, 1]
    find_matching_faces(face_image_path.get(), photos_folder_path.get(), output_folder_path.get(), similarity_threshold)

# Создание графического интерфейса
root = tk.Tk()
root.title("Поиск фотографий с совпадающими лицами")

face_image_path = tk.StringVar()
photos_folder_path = tk.StringVar()
output_folder_path = tk.StringVar()

tk.Label(root, text="Эталонное изображение:").grid(row=0, column=0, padx=10, pady=5, sticky="w")
tk.Entry(root, textvariable=face_image_path, width=40).grid(row=0, column=1, padx=10, pady=5)
tk.Button(root, text="Выбрать", command=select_face_image).grid(row=0, column=2, padx=10, pady=5)

tk.Label(root, text="Папка с фотографиями:").grid(row=1, column=0, padx=10, pady=5, sticky="w")
tk.Entry(root, textvariable=photos_folder_path, width=40).grid(row=1, column=1, padx=10, pady=5)
tk.Button(root, text="Выбрать", command=select_photos_folder).grid(row=1, column=2, padx=10, pady=5)

tk.Label(root, text="Папка для совпадений:").grid(row=2, column=0, padx=10, pady=5, sticky="w")
tk.Entry(root, textvariable=output_folder_path, width=40).grid(row=2, column=1, padx=10, pady=5)
tk.Button(root, text="Выбрать", command=select_output_folder).grid(row=2, column=2, padx=10, pady=5)

tk.Label(root, text="Коэффициент совпадения:").grid(row=3, column=0, padx=10, pady=5, sticky="w")
similarity_slider = tk.Scale(root, from_=50, to=100, orient="horizontal", length=300)
similarity_slider.set(80)  # Установить значение по умолчанию (80%)
similarity_slider.grid(row=3, column=1, columnspan=2, padx=10, pady=5)

tk.Button(root, text="Запустить", command=run_matching, bg="lightblue").grid(row=4, column=0, columnspan=3, pady=20)

root.mainloop()

Программа оснащена графическим интерфейсом, что делает ее удобной даже для тех, кто не знаком с программированием.

Основные возможности:

  1. Простой интерфейс
    Пользователь может легко указать:
    • Эталонное изображение лица.
    • Папку с фотографиями для анализа.
    • Папку для сохранения совпадений.
  2. Настройка коэффициента совпадения
    В программе есть ползунок для выбора минимального порога совпадения. Вы можете настроить уровень чувствительности, чтобы программа находила только те фотографии, которые действительно соответствуют эталону.
  3. Быстрая обработка
    OpenCV позволяет быстро обрабатывать изображения, даже если их много. Программа подходит для работы с большими архивами фотографий.
  4. Автоматическое сохранение результатов
    Все найденные совпадения автоматически копируются в отдельную папку, указанную пользователем.
Как пользоваться программой?
  1. Скачайте и установите Python (если он еще не установлен).
  2. Убедитесь, что у вас установлены необходимые библиотеки
  3. Запустите программу и укажите:
    • Эталонное изображение (фото лица для поиска).
    • Папку с фотографиями, где будет осуществляться поиск.
    • Папку для сохранения совпадений, куда программа запишет найденные файлы.
  4. Настройте ползунок коэффициента совпадения (например, 80% для большей точности).
  5. Нажмите кнопку “Запустить” и дождитесь завершения обработки. Программа сообщит, сколько совпадений найдено, и сохранит их в выбранной папке.
Технические особенности

Программа основана на использовании метода matchTemplate из OpenCV, который сравнивает эталонное лицо с лицами на фотографиях. Для обнаружения лиц используется каскад Хаара – предобученная модель, встроенная в OpenCV.

Программа позволяет устанавливать минимальный коэффициент совпадения, что дает гибкость в работе с разными наборами изображений.

Преимущества
  • Доступность: Подходит для пользователей с любым уровнем подготовки.
  • Универсальность: Работает на Windows и других системах, поддерживающих Python.
  • Точность: Возможность настройки порога совпадения позволяет минимизировать количество ошибок.
  • Простота: Не требует установки сложного ПО, все операции выполняются через понятный интерфейс.
Где это может быть полезно?
  • Управление фотоархивами: Автоматический поиск лиц в больших коллекциях фотографий.
  • Распознавание лиц: Полезно для фотографов, исследователей или просто для домашнего использования.
  • Систематизация данных: Быстрый способ упорядочить фотографии по людям.

Эта программа – отличное решение для тех, кто хочет сэкономить время и автоматизировать поиск фотографий с совпадающими лицами. Простота использования, высокая скорость обработки и возможность настройки делают ее незаменимым инструментом в работе с фотоархивами.