比较数组时为什么"in1d"比"a == b"慢得多

Sne*_*cle 3 python arrays opencv numpy

我需要能够比较两个图像并提取任何独特的像素来创建第三个图像.为此,我做了以下事情:

import cv2
import numpy as np

img = cv2.imread("old.jpg")
img2 = cv2.imread("new.jpg")

image2 = cv2.cvtColor(img2, cv2.COLOR_RGB2RGBA)

for (x,y,z), value in np.ndenumerate(img):
    dif = img[x,y,0] == img2[x,y,0] #only checking one color for speed
    diff = str(dif)
    if "True" in diff:
        image2[x,y,3] = 0
cv2.imwrite("result.png", image2)        
Run Code Online (Sandbox Code Playgroud)

这个效果相当不错,但640 x 480的图片花了大约10秒钟,我希望能让它接近大约一半的时间.所以我改变了这一行:

dif = img[x,y,0] == img2[x,y,0]
Run Code Online (Sandbox Code Playgroud)

dif = np.in1d(img[x,y,0], img2[x,y,0])
Run Code Online (Sandbox Code Playgroud)

结果是相同的,但现在大约需要3分钟,而不是加快速度.我完全失去了原因.

我意识到迭代大型数组中的元素在python中会很费时但是为什么in1d这么慢?

(作为旁注,我只会使用" 调色板方法 ",但由于我对numpy数组的了解有限,我无法看到为此目的实现它的方法.)

inn*_*SPG 5

np.in1d在最坏的情况下,检查其第一个参数的每个元素对其第二个元素的每个元素.对于每个元素i,jimg它检查是否有一个元素k,limg2具有相同值.这意味着对于您的640x480图像,您最终可以进行(640x480)^2比较.

在另一方面,==只检查的elementwise,它会检查是否元素i,jimg就是等于元素i,jimg2.它总是会有640x480比较.

np.in1d如果您有不同尺寸的图像,==它将起作用,仅适用于相同尺寸的图像.

  • 实际上并非如此.`in1d`的源代码是纯python,相对容易理解,参见[here](https://github.com/numpy/numpy/blob/maintenance/1.10.x/numpy/lib/arraysetops.py#L305 ).numpy中的算法使用排序,虽然它不是最优的(但在纯Python中可能是最好的),如果你的两个数组的大小为`m`和`n`,`in1d`的复杂度为'O((n + m) )*log(n + m))`,这比二次性能要好得多. (2认同)