В ImageMagick возможно ли -авто-гамма на основе региона?

#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, так что это еще более полезно. Еще раз спасибо. Хотел бы я проголосовать за это еще дюжину раз.