Реализация «Глобального фактора контраста» в Python с OpenCV и Numpy - PullRequest
0 голосов
/ 07 января 2019

Я хотел бы реализовать процедуру, подробно описанную в документе Глобальный коэффициент контрастности - новый подход к контрасту изображения Крешимира Матковича, Ласло Неймана, Аттилы Неймана, Томаса Псика и Вернера Пургатофера в Python с использованием Numpy и OpenCV. Однако есть один шаг, с которым я борюсь.

Процедура, по сути, включает в себя некоторое базовое умножение и сложение по пикселям изображения в градациях серого, что может быть сделано довольно легко с помощью векторизованных операций Numpy. Однако эту процедуру необходимо повторить для изображения с меньшим и меньшим разрешением, , где суперпиксели на меньших изображениях объединяются в соответствии с конкретной формулой, приведенной в документе.

Начиная с исходного изображения, каждый раз, когда размеры делятся пополам, и «значение суперпикселя вычисляется как средняя линейная яркость, и затем он преобразуется в воспринимаемую яркость ", заданную формулами:

enter image description here

, где гамма = 2,2, а k - исходное значение пикселя [0, 255]. Я предполагаю, что это означает, что каждый раз, когда я уменьшаю изображение, мне нужно вычислять первую формулу для четырех пикселей за раз (расположенных в квадрате), усреднять их, а затем применять вторую формулу для использования в качестве значения оттенков серого для уменьшенное изображение.

Моя проблема в том, что я не уверен, как эффективно уменьшить изображение, чтобы его значения в пикселях рассчитывались таким образом, чтобы соответствовать этим формулам. OpenCV уже имеет некоторые встроенные алгоритмы изменения размера, но я, честно говоря, не уверен, что, если таковые имеются, даст результат, аналогичный описанному в статье.

Как эффективно изменить размер изображения в градациях серого, когда значения пикселей в меньшем изображении определяются этими формулами?

1 Ответ

0 голосов
/ 08 января 2019

OpenCV resize не выполняет эти операции. Вам придется явно рассчитать линейные значения яркости для каждого пикселя изображения, а затем применить resize с линейной интерполяцией (INTER_LINEAR). Линейная интерполяция рассчитает среднее. Смотрите следующий пример. Он рассчитывает среднее значение неперекрывающихся блоков 2x2.

>>> im = np.random.randint(0, 255, (8, 8)).astype(np.float32)
>>> im
array([[ 74.,  73., 109.,  41., 165.,  24., 165., 189.],
       [143.,  15., 212., 139.,  63., 123., 222., 231.],
       [ 58., 150., 168., 234.,  64., 139., 239., 179.],
       [227.,  11., 142.,  42.,  28., 127., 213.,  52.],
       [187., 232.,  26.,  34.,  63., 104., 197., 155.],
       [ 95., 154.,  69.,  56., 163.,  93.,  37., 136.],
       [ 14., 249., 204.,  15., 182., 226.,  20., 114.],
       [231.,  61., 155., 184., 211., 162.,  62.,  26.]], dtype=float32)
>>> cv2.resize(im, dsize=None, fx=0.5, fy=0.5, interpolation=cv2.INTER_LINEAR)
array([[ 76.25, 125.25,  93.75, 201.75],
       [111.5 , 146.5 ,  89.5 , 170.75],
       [167.  ,  46.25, 105.75, 131.25],
       [138.75, 139.5 , 195.25,  55.5 ]], dtype=float32)
>>> (168+234+142+42)/4
146.5

Как я понял, вы рассчитываете линейную яркость ( l ) только для исходного изображения, а затем последовательно уменьшаете разрешение (пожалуйста, исправьте меня, если я ошибаюсь).

Вы можете ускорить вычисление линейной яркости, используя таблицу соответствия (LUT), поскольку максимум будет иметь 256 различных значений пикселей, если ваше изображение 8-битное (8U).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...