В чем разница между совместным добавлением к изображениям с использованием » » и метода add() в Opencv в Python?

#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)