03/15
15:12
IT OpenCV python

cv2.absdiff(A, B) 和 numpy.abs(A - B) 有什么区别

最近用到 cv2.adsdiff(A, B) 这个函数,功能很简单,就是将两幅图像作差。熟练在 Python 下写 OpenCV 的朋友会知道,我们经常需要用到一些 numpy 的库函数来取代 C++ 下一些矩阵的操作。那么,在处理这个需求的时候,我们很自然而然地想到,我们是不是也可以用 numpy.abs(A - B) 这个函数取代呢。
实际上,如果 OpenCVPython 下有提供和 C++ 下同样的接口,我们最好(或者一定要)选用共同的接口而弃用 numpy 的一些自带的矩阵的运算。原因有两点,第一,方便日后代码向其他平台的移植,第二,保证至少不会出错,因为你调用的 numpy 方法在这里未必是对的。

好的,言归正传,那么这两个函数到底有没有区别呢?答案是肯定的,不然我也不会写这篇博客了。

OpenCV 我们单通道使用的数据类型是 uint8,其实问题就出在这里,两个 uint8 的数相减得不到负数,会得到差的补码

> import numpy as np
> np.uint8(93) - np.uint8(111)
   __main__1: RuntimeWarning: overflow encountered in ubyte_scalars
   238

但是我们在调用 numpy.abs 的时候并没有跳出警告

> np.abs(np.uint8(93) - np.uint8(111))
  238

现在来看下 cv2.absdiff()numpy.abs() 具体输出会有什么区别

> import numpy as np
> import cv2
> A = np.array([122, 115, 110, 110, 106, 101, 92, 85, 85, 91, 97, 96, 93, 93, 91, 93, 92, 84], dtype='uint8')
> B = np.array([146, 144, 138, 134, 128, 118, 116, 122, 124, 122, 120, 115, 118, 111, 105, 98, 91, 84], dtype='uint8')
> cv2.absdiff(A, B)
  array([[24],
         [29],
         [28],
         [24],
         [22],
         [17],
         [24],
         [37],
         [39],
         [31],
         [23],
         [19],
         [25],
         [18],
         [14],
         [ 5],
         [ 1],
         [ 0]], dtype=uint8)
> np.abs(A - B)
  array([232, 227, 228, 232, 234, 239, 232, 219, 217, 225, 233, 237, 231,
         238, 242, 251,   1,   0], dtype=uint8)

综上我们应该使用 cv2.absdiff(A, B) 而不是 numpy.abs(A - B)

发表评论