python - OpenCV 图像减法 vs Numpy 减法

标签 python python-3.x opencv numpy image-processing

假设场景中有一些移动,我试图跟踪下一张图片与上一张图片有多少不同。决定在两个 jpg 图像之间应用相应像素值的减法,然后计算结果矩阵的平均值,以检查它是否低于或低于某个阈值水平(以供进一步分析)。

减法是通过 cv2.subtract 和 np.subtract 方法完成的。我注意到结果有很大的不同。似乎 numpy 以某种方式拉伸(stretch)了直方图并归一化了结果值,但为什么呢?

图像是通过 cv2.open 加载的。我知道这种方法使用 BGR channel 顺序,但它没有解释发生了什么。加载的图像是带有 np.uint 值的 numpy nd.array。使用 Python 3.7 在 Spyder 上工作。

编辑:cv2.imread 中的参数 0 指示加载灰度图像

OpenCV subtraction result

Numpy subtraction result

#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.subtract执行饱和。根据文档:

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

numpy.subtract只是执行常规减法,所以结果以integer overflow为准(即值环绕)。


Saturation means that when the input value v is out of the range of the target type, the result is not formed just by taking low bits of the input, but instead the value is clipped. For example:

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

Such clipping is done when the target type is unsigned char , signed char , unsigned short or signed short . For 32-bit integers, no clipping is done.


例子

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

关于python - OpenCV 图像减法 vs Numpy 减法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45817037/

相关文章:

python - PySimpleGUI 按下按钮时调用函数

python - 无法为在 Cpanel 上部署 Django 的应用程序生成进程

python - reshape LSTM 自动编码器的输入数据

python - Linux cat 命令在 python 中无法正常工作

python - 在 Python 中用相同的列表减去列表中的列表

python - 在 Python Shell 中打印当前行

python - Python和OpenCV-如何理解该按位运算符?

python - 复杂的排序,使用 cmp 函数很容易完成,但我如何为 Python 3 做计划?

android - 如何使用 onPreviewFrame() 中的 byte[] 数据在肖像中使用 OpenCV 人脸检测?

C++:升级到 GTX970 后 cv::gpu::GpuMat::upload 出现长时间延迟