Создать алгоритм выбора самого резкого изображения...
作成日: 2026年11月11日
使用モデル GPT-6 Thinking by Chat01
作成日: 2026年11月11日
使用モデル GPT-6 Thinking by Chat01
Создать алгоритм выбора самого резкого изображения из заданного набора изображений одной и той же сцены.
Для выбора самого резкого изображения из набора фотографий одной и той же сцены предлагаю использовать алгоритм на основе дисперсии лапласиана (Variance of Laplacian). Это один из наиболее распространённых методов автоматической оценки резкости изображений.
Резкое изображение содержит выраженные границы объектов и мелкие детали. На размытом изображении границы становятся плавными, а высокочастотные составляющие ослабевают.
Оператор Лапласа позволяет оценить интенсивность изменения яркости.
Для каждого изображения вычисляется показатель:
где:
Чем больше , тем выше предполагаемая резкость.
Начало
Загрузка N изображений одной сцены
Приведение к одинаковому размеру и оттенкам серого
Подавление шума фильтром Гаусса
Вычисление оператора Лапласа для каждого изображения
Расчёт показателей резкости S₁, S₂, …, Sₙ
Выбор изображения с максимальным S
Результат: самое резкое изображение
Используются библиотеки OpenCV и NumPy.
Установка:
bashpip install opencv-python numpy
Программная реализация:
pythonfrom pathlib import Path import cv2 import numpy as np def find_sharpest_image(folder): extensions = {".jpg", ".jpeg", ".png", ".bmp", ".tif", ".tiff"} paths = sorted( p for p in Path(folder).iterdir() if p.is_file() and p.suffix.lower() in extensions ) if not paths: raise ValueError("Изображения не найдены") images = [] # 1. Загрузка изображений for path in paths: img = cv2.imread(str(path), cv2.IMREAD_GRAYSCALE) if img is None: raise ValueError(f"Ошибка чтения: {path}") images.append((path, img)) # 2. Выбор общего размера без увеличения height = min(img.shape[0] for _, img in images) width = min(img.shape[1] for _, img in images) results = [] for path, img in images: # 3. Приведение к общему размеру img = cv2.resize( img, (width, height), interpolation=cv2.INTER_AREA ) # 4. Небольшое подавление шума img = cv2.GaussianBlur(img, (3, 3), 0.7) # 5. Оператор Лапласа laplacian = cv2.Laplacian(img, cv2.CV_64F) # 6. Оценка резкости score = float(np.var(laplacian)) results.append((path, score)) # 7. Сортировка по убыванию резкости results.sort(key=lambda x: x[1], reverse=True) return results # Пример использования results = find_sharpest_image("images") print("Рейтинг изображений:") for path, score in results: print(f"{path.name}: {score:.2f}") print("\nСамое резкое изображение:") print(results[0][0])
Предположим, имеется четыре фотографии одной сцены с разной степенью расфокусировки.
Фото 1
Сильное размытие
Фото 2
Среднее размытие
Фото 3
Высокая резкость
Фото 4
Высокая детализация
Иллюстрации демонстрируют принцип; это не реальные результаты работы алгоритма.
Условные результаты измерения:
| Изображение | Показатель S | Результат |
|---|---|---|
| Фото 1 | 18.4 | Сильное размытие |
| Фото 2 | 76.2 | Средняя резкость |
| Фото 3 | 241.7 | Хорошая резкость |
| Фото 4 | 385.9 | Максимальная резкость |
Алгоритм выбирает фото № 4, поскольку оно имеет наибольший показатель резкости.
Метод Лапласа достаточно эффективен, но имеет ограничения:
Для более сложных условий дополнительно можно использовать метод Tenengrad, основанный на градиентах Собеля, и сравнивать результаты нескольких метрик.
Предложенный алгоритм:
Вычислительная сложность составляет , где — количество изображений, и — их ширина и высота.
Рекомендация: для набора фотографий неподвижной сцены, снятых с одной позиции и различающихся главным образом фокусировкой, дисперсия лапласиана является хорошим базовым решением. Для более надёжного выбора в условиях шума, движения камеры и сложной структуры сцены стоит использовать комбинированную оценку на основе Лапласа и Tenengrad.