#imagemagick
#imagemagick
Вопрос:
Я использую ImageMagick для подготовки набора из ~ 20 000 фотографий для видео с временной задержкой. Распространенной проблемой в видеороликах с временной задержкой является мерцание из-за изменения условий освещения, прохождения облаков, изменения оттенков и т. Д.
Я использовал IM для преобразования каждого изображения в оттенки серого и -auto-gamma
, что является значительным улучшением «стабильности» освещения. Очень хорошо, но еще не идеально. Теперь я хотел бы сделать следующее, но не могу понять, как это сделать.
1. determine ideal auto gamma based only on the lower 30% of the image
2. apply that ideal gamma to the entire image
На каждом из моих изображений вверху небо, а внизу здания. Небо резко меняется по мере прохождения облаков, но освещение зданий довольно стабильное.
Я пытался -region
, но, как и ожидалось, он применяет гамму только к указанному региону. Возможно ли сделать то, на что я надеюсь? Спасибо за любой совет!
Ответ №1:
Да, я так думаю.
Вы можете обрезать нижние 30% изображения следующим образом:
convert image.jpg -gravity south -crop x30% 0 0 bottom.jpg
таким образом, это означает, что вы можете получить среднее значение нижних 30% изображения следующим образом:
convert image.jpg -gravity south -crop x30% 0 0 -format "%[mean]" info:
и вы также можете получить квантовый диапазон за один раз, если добавите это в:
convert image.jpg -gravity south -crop x30% 0 0 -format "%[mean] %[fx:quantumrange]" info:
Теперь гамма определяется как логарифм среднего значения, деленный на логарифм средней точки динамического диапазона, но мы можем нормализовать оба эти числа до диапазона [0-1] следующим образом:
log(mean/quantumrange) / log(0.5)
так что мы позволим bc
решить это для нас следующим образом:
echo "scale=4; l($mean30/$qr)/l(0.5)" | bc -l
и мы можем использовать этот результат, чтобы применить гамма-коррекцию ко всему изображению. Итак, я собрал все это вместе в один скрипт, который я называю b30gamma
. Вы сохраняете его под этим именем, а затем вводите:
chmod x b30gamma
чтобы сделать его исполняемым. Затем вы можете запустить его на подобном изображении, и результат будет сохранен, out.jpg
чтобы не уничтожить входное изображение:
./b30gamma input.jpg
Вот сценарий:
#!/bin/bash
# Pick up image name as parameter
image=$1
# Get mean of bottom 30% of image, and quantum range (65535 for Q16, or 255 for Q8)
read mean30 qr < <(convert "$image" -gravity south -crop x30% 0 0 -format "%[mean] %[fx:quantumrange]" info:)
# Gamma = log(mean)/log(dynamic range centre point)
gcorr=$(echo "scale=4;l($mean30/$qr)/l(0.5)" | bc -l)
# Debug
echo Image: $image, Mean: $mean30, quantum range: $qr, Gamma: $gcorr
# Now apply this gamma to entire image
convert "$image" -gamma $gcorr out.jpg
Комментарии:
1. Это красиво. Спасибо!
2. Я должен добавить, что если у вас есть 20 000 изображений для исправления, вы можете рассмотреть возможность использования GNU Parallel, чтобы заставить все ядра вашего процессора работать параллельно. Сначала вы
mkdir output
должны создать выходной каталог, а затем изменить последнюю строку скрипта, чтобы он записывал в"output$image"
, а неout.jpg
. Затем запуститеls *.jpg | parallel -j 8 b30gamma {}
, чтобы использовать 8 ядер процессора параллельно.3. На данный момент это больше похоже на 40 000, так что это еще более полезно. Еще раз спасибо. Хотел бы я проголосовать за это еще дюжину раз.