两个uint8阵列的快速绝对差异

时间:2016-03-03 16:34:57

标签: python numpy

我有两个带有class A class B < A end end 的numpy数组 - 就像这样:

dtype=np.uint8

我想构建这些数组的 正面差异

这是我的前两个approches(以及第三个用于参考):

img1=np.uint8(np.random.randint(0, 255, (480, 640)))
img2=np.uint8(np.random.randint(0, 255, (480, 640)))

我得到了这些执行时间(以及要检查的总和,如果它们相等):

def differenceImageV1(img1, img2):
  diff=np.empty_like(img1)
  h, w=img1.shape
  for y in range(h):
    for x in range(w):
      if img1[y, x]<img2[y, x]: diff[y, x]=img2[y, x]-img1[y, x]
      else:                     diff[y, x]=img1[y, x]-img2[y, x]
  return(diff)

def differenceImageV2(img1, img2):
  return(np.uint8(np.absolute(np.int16(img1)-np.int16(img2))))

def differenceImageV3(img1, img2):  # fast - but wrong result
  return(img1-img2)

有没有办法像V2那样更快地获得正确的结果?

2 个答案:

答案 0 :(得分:8)

这是一种明显快于 @IBOutlet var top: UIImageView! override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) let openTop = CABasicAnimation(keyPath: "position.y") openTop.fromValue = self.top.frame.origin.y openTop.toValue = -self.view.bounds.size.height openTop.duration = 1.0 openTop.beginTime = CACurrentMediaTime() + 4 self.top.layer.addAnimation(openTop, forKey: nil) self.top.layer.position.y = -self.view.bounds.size.height } 的方法:取V2,并根据img1-img2乘以1或-1。以下是它的实现方式:

img1>img2

用于测试性能的测试工具:

def differenceImageV6(img1, img2):
  a = img1-img2
  b = np.uint8(img1<img2) * 254 + 1
  return a * b

以及由此产生的绩效数字:

import numpy as np

img1=np.uint8(np.random.randint(0, 255, (480, 640)))
img2=np.uint8(np.random.randint(0, 255, (480, 640)))

def differenceImageV1(img1, img2):
  diff=np.empty_like(img1)
  h, w=img1.shape
  for y in range(h):
    for x in range(w):
      if img1[y, x]<img2[y, x]: diff[y, x]=img2[y, x]-img1[y, x]
      else:                     diff[y, x]=img1[y, x]-img2[y, x]
  return(diff)

def differenceImageV2(img1, img2):
  return(np.uint8(np.abs(np.int16(img1)-img2)))

def differenceImageV3(img1, img2):  # fast - but wrong result
  return(img1-img2)

def differenceImageV4(img1, img2):
  return np.where(img1>img2, img1-img2, img2-img1)

def differenceImageV5(img1, img2):
  a = img1-img2
  b = img2-img1
  c = img1>img2
  return a*c + b*(~c)

def differenceImageV6(img1, img2):
  a = img1-img2
  b = np.uint8(img1<img2) * 254 + 1
  return a * b

import timeit
def testit():
  for fn in [differenceImageV2, differenceImageV3, differenceImageV4, differenceImageV5, differenceImageV6]:
    print fn.__name__, np.sum(fn(img1, img2).astype('int64')),
    print timeit.timeit("%s(img1, img2)" % fn.__name__, "from test import img1, img2, %s" % fn.__name__, number=1000)

if __name__ == '__main__':
    testit()

differenceImageV2 26071358 0.982538938522 differenceImageV3 39207702 0.0261280536652 differenceImageV4 26071358 1.36270809174 differenceImageV5 26071358 0.220561981201 differenceImageV6 26071358 0.154536962509 比不正确的differenceImageV6慢约6倍,但仍比之前的最佳differenceImageV3快6倍。 differenceImageV2未经过测试,因为它比其他部分慢了几个数量级。

注意:我添加了differenceImageV1方法进行比较;我认为它可能有很好的表现但事实证明它相当差。似乎在NumPy中通过布尔数组执行切片非常慢。

答案 1 :(得分:3)

如果有opencv可用,还可以使用:

def differenceImageV4(img1, img2):
  return cv2.absdiff(img1, img2)

几乎与differenceImageV3相同。