OpenCV MergeMertens дает разные результаты в Python Vs. Переполнение стека

Когда я запускаю слияние экспозиции HDR Mertens в Python, я получаю странный артефакт цвета, который я не получаю, когда запускаю точно такую ​​же функцию в c ++. (Я просто запускаю HDR Учебник)

Мне кажется, что некоторые проблемы с типами данных, но я попробовал все варианты, и ничего не работает. Я делаю что-то неправильно?

Я использую Python 3.5 64-bit с OpenCV 3.0.0.

Изображения выдержек были взяты из Википедии: 1/30 сек, 1/4 сек, 2,5 сек, 15 сек.

Код Python:

import cv2
import numpy as np

img_fn = ["640px-StLouisArchMultExpEV+4.09.jpg",
"640px-StLouisArchMultExpEV+1.51.jpg",
"640px-StLouisArchMultExpEV-1.82.jpg",
"640px-StLouisArchMultExpEV-4.72.jpg"]
img_list = [cv2.imread(fn) for fn in img_fn]

# Exposure fusion using Mertens
mergeMertens = cv2.createMergeMertens()
resFusion = mergeMertens.process(img_list)

# Convert datatype to 8-bit and save
resFusion_8bit = np.uint8(resFusion*255)
cv2.imwrite("fusion.png", resFusion_8bit)

Результат, который я получаю в Python:

введите описание изображения здесь

Результат, который я получаю в C ++:

введите описание изображения здесь

2

Решение

То, что здесь происходит, вызвано 8-битным переполнением и понижением для некоторых подпикселей R, G, B. Некоторые из них находятся за пределами интервала [0.0 .. 1.0] после слияния и при умножении на 255 результат будет отрицательным или выше 255.

np.uint8 будет усекать результаты и сохранять только младшие 8 битов, например:

  • значение -2 будет храниться как 254

  • значение 257 будет храниться как 1

Это может быть решено путем отсечения результатов в диапазоне [0 .. 255], заменяя

resFusion_8bit = np.uint8(resFusion*255)

с

np.clip(resFusion*255, 0, 255, out=resFusion)
resFusion_8bit = resFusion.astype('uint8')

Или же можно напрямую передать значения, умноженные на 255, на imwriteбез преобразования их сначала в uint8 и он позаботится об отсечении. Это было бы так же, как это делается в приведенном примере C ++. Итак, скрипт можно переписать так:

import cv2

img_fn = ["640px-StLouisArchMultExpEV+4.09.JPG",
"640px-StLouisArchMultExpEV+1.51.JPG",
"640px-StLouisArchMultExpEV-1.82.JPG",
"640px-StLouisArchMultExpEV-4.72.JPG"]
img_list = [cv2.imread(fn) for fn in img_fn]

# Exposure fusion using Mertens
mergeMertens = cv2.createMergeMertens()
resFusion = mergeMertens.process(img_list)

# Save
cv2.imwrite("fusion.png", resFusion*255)

(Обратите внимание, что я заменил расширения файлов на .JPG — в верхнем регистре, так как это оригинальное имя в Википедии, и я запускал его в Linux, где имена файлов чувствительны к регистру.)

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]