OpenCV图像减法与Numpy减法

Ano*_*eon 4 python opencv numpy image-processing python-3.x

假设在场景中有一些动作,我试图跟踪下一张图片与前一张图片的差异程度.决定在两个jpg图像之间应用相应像素值的减法,然后计算所得矩阵的平均值,以便检查它是否低于或低于某个阈值水平(用于进一步分析).

减法由cv2.subtract和np.subtract方法完成.我注意到结果差异很大.似乎numpy以某种方式拉伸直方图并将结果值归一化,但为什么呢?

图像通过cv2.open加载.我知道这种方法使用频道的BGR顺序,但它没有解释发生了什么.加载的图像是numpy nd.array与np.uint值.使用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')
Run Code Online (Sandbox Code Playgroud)

Dan*_*šek 11

差异很简单 - 饱和度与无饱和度.

cv2.subtract执行饱和.根据文件:

dst(I)=饱和(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)
Run Code Online (Sandbox Code Playgroud)

这种削波完成当目标类型是unsigned char,signed char,unsigned 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)
Run Code Online (Sandbox Code Playgroud)