#python #opencv
#python #opencv
Вопрос:
Итак, представьте, что у нас есть два изображения: img1 и img2. при добавлении этих двух вместе с помощью или cv2.add() мы получаем разные результаты. Почему это так? Чем они отличаются?
img = img1 img2
img = cv2.add(img1, img2)
Ответ №1:
из документации opencv:
Добавление изображений Вы можете добавить два изображения с помощью функции OpenCV, cv.add() или просто с помощью операции numpy res = img1 img2. Оба изображения должны иметь одинаковую глубину и тип, или второе изображение может быть просто скалярным значением.
Обратите внимание, что существует разница между добавлением OpenCV и добавлением Numpy. Добавление OpenCV — это насыщенная операция, в то время как добавление Numpy — это операция по модулю. Например, рассмотрим приведенный ниже пример:
x = np.uint8([250])
>>> y = np.uint8([10])
>>> print( cv.add(x,y) ) # 250 10 = 260 => 255
[[255]]
>>> print( x y ) # 250 10 = 260 % 256 = 4
[4]
Это будет более заметно, когда
вы добавите два изображения. Придерживайтесь функций OpenCV,
потому что они обеспечат лучший результат.
Комментарии:
1. Почему x y принимает модуль 256? Откуда взялось 256?
2. Не уверен, но я думаю, что это должно быть связано с целочисленной арифметикой в numpy
3. 256 — это количество представимых значений в 8 бит => от 0 до 255
4. Это результат переполнения. Если вы выйдете за пределы 255, это будет сделано по модулю 255. Это ожидаемое поведение для массивов numpy с ограниченной точностью.
Ответ №2:
Учитывая, что ваши img1
img2
переменные и имеют значение dtype == np.uint8
: img1 img2
является numpy
сложением, которое является modulo
операцией, тогда cv2.add(img1 img2)
как является saturated
операцией.
np.uint8
это 8-разрядное целое число без знака (от 0 до 255), поэтому, если результирующее значение выходит за рамки, тогда numpy
и opencv
обрабатывайте это по-другому. Например:
>>> img1 = np.uint8([250])
>>> img2 = np.uint8([50])
# numpy
>>> img1 img2
array([44], dtype=uint8) # (250 50) % 256 = 44
# it takes the modulo of 256
# opencv
>>> cv2.add(img1, img2)
array([[255]], dtype=uint8) # min(max(0, (250 50)), 255) = 255 or np.clip(300, 0, 255)
# it saturates to 255
Для np.uint8
диапазона будет (0, 4294967295)