OpenCV图像减法与Numpy减法的区别

11
我试图追踪下一张图片与前一张图片的差异,假设场景中发生了一些移动。决定通过对两个jpg图像之间的相应像素值进行减法,然后计算结果矩阵的平均值来检查它是否低于某个阈值水平(以供进一步分析)。
减法是通过cv2.subtract和np.subtract方法完成的。我注意到结果有很大的差异。似乎numpy在某种程度上拉伸了直方图并标准化了结果值,但为什么?
图像是通过cv2.open加载的。我知道这种方法使用BGR通道顺序,但这并不能解释发生了什么。加载的图像是带有np.uint值的numpy nd.array。在Python 3.7的Spyder上工作。
编辑:cv2.imread中的参数0表示以灰度模式加载图像 OpenCV减法结果 Numpy减法结果
#loading images

img_cam0 = cv2.imread(r'C:\Users\Krzysztof\Desktop\1.jpg',0)
img_cam1 = cv2.imread(r'C:\Users\Krzysztof\Desktop\2.jpg', 0)
print('img0 type:',type(img_cam0), 'and shape:', img_cam0.shape)
print('img1 type:',type(img_cam1),'and shape:', np.shape(img_cam1))
print('\n')

#opencv subtraction

cv2_subt = cv2.subtract(img_cam0,img_cam1)
cv2_mean = cv2.mean(cv2_subt)

print('open cv mean is:', cv2_mean)
f.show_im(cv2_subt, 'cv2_subtr')

#np subtraction and mean

np_subtr = np.subtract(img_cam0, img_cam1)
np_mean = np.mean(np_subtr)

print('numpy mean is:', np_mean)
f.show_im(np_subtr, 'np_subtr')

你肯定会很想看看cv2_subt-np_subtr图像的样子。这就泄露了秘密。它不是一张黑色的图像。 - I.Newton
1
简单来说,cv2.subtract执行饱和度减法,而 np.subtract 不会(你会看到下溢的结果——值会被包裹)。 - Dan Mašek
如何避免饱和?需要将像素转换为浮点数,并允许它们变为负数。 - CraigDavid
1个回答

18

区别很简单--饱和与非饱和。

cv2.subtract执行饱和操作。根据文档:

dst(I) = saturate(src1(I) - src2(I))

numpy.subtract只是执行普通的减法运算,因此结果可能会受到整型溢出的影响(即值会被截断)。


饱和是指当输入值v超出目标类型的范围时,结果不仅仅是取输入的低位,而是将其修剪。例如:

uchar a = saturate_cast<uchar>(-100); // a = 0 (UCHAR_MIN)
short b = saturate_cast<short>(33333.33333); // b = 32767 (SHRT_MAX)

当目标类型为unsigned charsigned charunsigned shortsigned short时,进行这样的剪辑。对于32位整数,不进行剪辑。

>>> import cv2
>>> import numpy as np

>>> a = np.arange(9, dtype=np.uint8).reshape(3,3)
>>> a
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]], dtype=uint8)
>>> b = np.full((3,3), 4, np.uint8)
>>> b
array([[4, 4, 4],
       [4, 4, 4],
       [4, 4, 4]], dtype=uint8)

>>> np.subtract(b,a)
array([[  4,   3,   2],
       [  1,   0, 255],
       [254, 253, 252]], dtype=uint8)

>>> cv2.subtract(b,a)
array([[4, 3, 2],
       [1, 0, 0],
       [0, 0, 0]], dtype=uint8)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接