
Оценка резкости изображения через оператор Лапласа

Оценка резкости изображения через оператор Лапласа
Попробовал решить задачу для автоматической оценки резкости изображения через оператор Лапласа. Зачем это нужно? Я фотографирую каждый кадр по несколько раз, чтобы потом выбрать лучший из серии. Из нескольких похожих файлов надо оставить по одному, а дубли и мусор удалить. Это занимает много времени, да и место на дисках быстро заканчивается, если не чистить. В результате почитал теорию, потестировал код, а потом сделал решение на PHP. Алгоритм можно использовать для автоматической очистки больших массивов фото - например, после поездки или мероприятия. Смазанные кадры удаляются, а резкие остаются.
Немножко теории. В основе алгоритма лежит оператор Лапласа - это штука (другими словами не назвать, слишком мудрено), которая находит на картинке места, где цвет резко меняется, например края предметов. Чем больше таких мест, тем выше число на выходе. Если усреднить это число по всей картинке, получится объективная оценка: чем оно больше, тем фото резче. Однако у этого подхода есть слабое место - зависимость от яркости кадра. Пересвеченное или слишком темное фото дает заниженные значения даже при идеальном фокусе, потому что контраст на границах падает. Поэтому нужна нормировка. В моем коде она есть: алгоритм считает не только резкость, но и среднюю яркость кадра. Итоговая оценка вычисляется как отношение одного к другому с поправкой на максимум. Простыми словами - резкость считается относительно освещенности. Это позволяет сравнивать снимки с разной экспозицией: темные и светлые кадры больше не страдают.
Code (PHP) : Убрать нумерацию
- // Дополнительная функция, получить сумму RGB пикселя
- function get_gray($img, $x, $y) {
- $rgb=imagecolorat($img, $x, $y);
- return (($rgb>>16) & 0xFF)+(($rgb>>8) & 0xFF)+($rgb & 0xFF);
- }
- // Оценка резкости изображения через оператор Лапласа
- // с нормированием по яркости
- function laplacian_sharpness($path) {
- // Загружаем исходное изображение
- $src=imagecreatefromjpeg($path);
- $w=imagesx($src);
- $h=imagesy($src);
- // Ресайз до 1024 пикселей, иначе большие фото считаются долго
- $max_size=1024;
- if ($w>$max_size || $h>$max_size) {
- $ratio=min($max_size / $w, $max_size / $h);
- $new_w=$w*$ratio;
- $new_h=$h*$ratio;
- // Рабочее изображение
- $img=imagecreatetruecolor($new_w, $new_h);
- imagecopyresampled(
- $img, $src, 0,0,0,0, $new_w, $new_h, $w, $h
- );
- // Оригинал больше не нужен
- imagedestroy($src);
- }
- else {
- // Рабочее изображение
- $img=$src;
- $new_w=$w;
- $new_h=$h;
- }
- // Сумма модулей лапласиана
- $score=0;
- // Сумма яркостей всех пикселей
- $brightness_total=0;
- // Количество обработанных пикселей
- $count=0;
- // Проходим по всем пикселям, кроме границ
- for($x=1; $x<($new_w-1); $x++) {
- for($y=1; $y<($new_h-1); $y++) {
- // Яркость текущего пикселя
- $gray=get_gray($img, $x, $y);
- $brightness_total+=$gray;
- // Центр и сумма соседей точек. Чем больше перепад
- // яркости с соседями, тем выше значение
- $lap=-4*$gray +
- get_gray($img, $x+1, $y) +
- get_gray($img, $x-1, $y) +
- get_gray($img, $x, $y+1) +
- get_gray($img, $x, $y-1);
- $score+=abs($lap);
- $count++;
- }
- }
- imagedestroy($img);
- // Средняя резкость на пиксель
- $avg_score=$count?($score/$count) : 0;
- // Средняя яркость на пиксель (0-765)
- $avg_brightness=$count?($brightness_total/$count) : 1;
- // Нормирование. Умножаем на 765 (максимальная яркость)
- // и делим на среднюю яркость, это компенсирует
- // занижение оценки на темных и светлых фото
- return round($avg_score*(765/$avg_brightness), 2);
- }
Code (PHP) : Убрать нумерацию
- // Настройки порогов
- $bad_sharpness=20;
- // Ниже этого - "мыло" (BAD)
- $good_sharpness=70;
- // Выше этого - отличная резкость (GOOD)
- // Путь к папке с фото
- $directory='foto/test';
- // Поиск нужного формата файлов
- $files=glob($directory.'/*.jpg');
- foreach ($files as $file) {
- // Считаем резкость
- $sharpness=laplacian_sharpness($file);
- // Определяем порогов
- if ($sharpness<$bad_sharpness) {
- // Мусор
- $res='<b style="color:#FF0000;">BAD</b>';
- }
- elseif ($sharpness>$good_sharpness) {
- // Отличное качество
- $res='<b style="color:#208F20;">GOOD</b>';
- }
- else {
- // Требуется ручная проверка
- $res='<b>CHECK</b>';
- }
- echo '<div>'.basename($file).' : '.$sharpness.' : '.$res. '</div>';
- }
Просмотров: 111 | Комментариев: 0
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария

