Каковы некоторые методы анализа яркости изображения с помощью Python?
Мне бы хотелось получить совет по выполнению простого анализа изображений в python. Мне нужно вычислить значение для "яркости" изображения. Я знаю PIL - это библиотека goto для выполнения чего-то подобного. Существует встроенная функция гистограммы.
Что мне нужно - это "воспринимаемая яркость" . Я могу решить, необходимы ли дополнительные корректировки изображения. Итак, что же из основных техник, которые будут работать в этой ситуации? Должен ли я просто работать с значениями RGB, или гистограмма даст мне что-то достаточно близко?
Одним из возможных решений может быть объединение этих двух и получение средних значений R, G и B с использованием гистограммы, затем применение формулы "воспринимаемой яркости".
Ответы
Ответ 1
Используя методы, упомянутые в вопросе, я придумал несколько разных версий.
Каждый метод возвращает значение close, но не то же самое, что и другие. Кроме того, все методы работают с одинаковой скоростью, за исключением последней, которая намного медленнее в зависимости от размера изображения.
-
Преобразовать изображение в оттенки серого, вернуть среднюю яркость пикселей.
def brightness( im_file ):
im = Image.open(im_file).convert('L')
stat = ImageStat.Stat(im)
return stat.mean[0]
-
Преобразовать изображение в оттенки серого, вернуть яркость пикселей RMS.
def brightness( im_file ):
im = Image.open(im_file).convert('L')
stat = ImageStat.Stat(im)
return stat.rms[0]
-
Средние пиксели, затем преобразуются в "воспринимаемую яркость" .
def brightness( im_file ):
im = Image.open(im_file)
stat = ImageStat.Stat(im)
r,g,b = stat.mean
return math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2))
-
RMS пикселей, затем преобразуется в "воспринимаемую яркость" .
def brightness( im_file ):
im = Image.open(im_file)
stat = ImageStat.Stat(im)
r,g,b = stat.rms
return math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2))
-
Рассчитайте "воспринимаемую яркость" пикселей, затем верните средний результат.
def brightness( im_file ):
im = Image.open(im_file)
stat = ImageStat.Stat(im)
gs = (math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2))
for r,g,b in im.getdata())
return sum(gs)/stat.count[0]
Обновить результаты тестирования
Я провел симуляцию против 200 изображений. Я обнаружил, что методы № 2, №4 дали почти одинаковые результаты. Также методы № 3, № 5 были также почти идентичны. Метод № 1 внимательно следил за # 3, # 5 (за некоторыми исключениями).
Ответ 2
Учитывая, что вы просто ищете среднее значение по всему изображению, а не значения яркости пикселя, усреднение гистограммы PIL и применение функции яркости к выходу кажется лучшим подходом для этой библиотеки.
Если вы используете ImageMagick (с PythonMagick bindings), я бы предложил использовать команду identify с установленной опцией "verbose". Это обеспечит вам среднее значение для каждого канала, что позволит вам суммировать и усреднить гистограмму; вы можете просто размножать каждый канал напрямую.
Ответ 3
Я думаю, что ваш лучший результат будет заключаться в преобразовании RGB в оттенки серого с использованием вашей любимой формулы, а затем с гистограммой этого результата. Я не уверен, будет ли среднее или медианное значение гистограммы более подходящим, но на большинстве изображений они, вероятно, похожи.
Я не уверен, как сделать преобразование в оттенки серого в PIL, используя произвольную формулу, но я предполагаю, что это возможно.
Ответ 4
Эй, у меня есть точная проблема.. Я надеюсь, что эта ссылка https://github.com/imneonizer/How-to-find-if-an-image-is-bright-or-dark/blob/master/README.md будет помочь вам достичь того же. В этом блоге я объяснил, как я разделил изображение на более мелкие сегменты и нашел яркость в этих сегментах и, наконец, взял среднее значение всех этих рассчитанных яркостей, чтобы получить уровень яркости изображения. Он может легко определить, какие изображения являются более яркими, а какие - темными. Надеюсь, это может вам чем-то помочь.
Ответ 5
код ниже даст вам уровень яркости изображения от 0 до 10
1 вычислите среднюю яркость изображения после преобразования изображения в формат HSV с помощью opencv.
2 найти, где это значение лежит в списке диапазона яркости.
import numpy as np
import cv2
import sys
from collections import namedtuple
#brange brightness range
#bval brightness value
BLevel = namedtuple("BLevel", ['brange', 'bval'])
#all possible levels
_blevels = [
BLevel(brange=range(0, 24), bval=0),
BLevel(brange=range(23, 47), bval=1),
BLevel(brange=range(46, 70), bval=2),
BLevel(brange=range(69, 93), bval=3),
BLevel(brange=range(92, 116), bval=4),
BLevel(brange=range(115, 140), bval=5),
BLevel(brange=range(139, 163), bval=6),
BLevel(brange=range(162, 186), bval=7),
BLevel(brange=range(185, 209), bval=8),
BLevel(brange=range(208, 232), bval=9),
BLevel(brange=range(231, 256), bval=10),
]
def detect_level(h_val):
h_val = int(h_val)
for blevel in _blevels:
if h_val in blevel.brange:
return blevel.bval
raise ValueError("Brightness Level Out of Range")
def get_img_avg_brightness():
if len(sys.argv) < 2:
print("USAGE: python3.7 brightness.py <image_path>")
sys.exit(1)
img = cv2.imread(sys.argv[1])
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
_, _, v = cv2.split(hsv)
return int(np.average(v.flatten()))
if __name__ == '__main__':
print("the image brightness level is:
{0}".format(detect_level(get_img_avg_brightness())))