Python numpy.einsum在cv2加载的阵列上的作用是否不同?

Python numpy.einsum在cv2加载的阵列上的作用是否不同?,python,cv2,numpy-einsum,Python,Cv2,Numpy Einsum,einsum的函数表示np.einsum('ij->i',a)函数类似于np.sum(a,axis=1)。下面,示例1证实了这一点,而示例2则反驳了这一点。知道我做错了什么吗 实验一 将numpy导入为np a=np.arange(25)。重塑(5,5) b1=np.einsum('ij->i',a)#数组([10,35,60,85,110]) b2=np.sum(a,axis=1)#数组([10,35,60,85,110]) 实验2 将numpy导入为np 进口cv2 img_path=“p

einsum的函数表示
np.einsum('ij->i',a)
函数类似于
np.sum(a,axis=1)
。下面,示例1证实了这一点,而示例2则反驳了这一点。知道我做错了什么吗

实验一

将numpy导入为np
a=np.arange(25)。重塑(5,5)
b1=np.einsum('ij->i',a)#数组([10,35,60,85,110])
b2=np.sum(a,axis=1)#数组([10,35,60,85,110])
实验2

将numpy导入为np
进口cv2
img_path=“path/to/an/image.png”
im=cv2.imread(img_路径,cv2.imread_灰度)#类型:numpy.ndarray
n1=np.einsum('ij->i',im)
n2=np.和(img,轴=1)
#表明他们是不同的。
打印(np.max(n1),np.max(n2))#输出:255 119630
为什么
n1
n2
不相同(如
max
值所示)?

加载cv2(和PIL)的图像将为
uint8
类型。与其他类型相比,类型内的计算结果可能不相同

>>> np.uint8(255) + np.uint8(1)
0
>>> np.int32(255) + np.int32(1)
256
np.arange
默认情况下创建类型为
int32
的数组,因此不存在任何问题。但是

a = np.arange(64, dtype=np.uint8).reshape(8, 8)
b1 = np.einsum('ij->i', a)
b2 = np.sum(a, axis=1)
print(b1 == b2)
印刷品

[ True  True  True  True False False False False]
请注意,
np.sum
转换引擎盖下的类型,以便可以容纳不受较短类型限制的添加。这并不是说,如果必须处理其支持范围之外的值,则
uint32
不会出现问题,但可能性较小

>>> np.sum(np.uint8([1, 2])).dtype
dtype('uint32')
只要确保您使用的数据类型不会因您的特定问题而遇到任何问题

img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE).astype(np.uint32)  # or np.int32
print(np.all(n1 == n2))   # this should now be true

如前所述,如果不知道
img\u路径
,任何人都无法复制这一点。事实上,看起来您的第二个代码块中有一个输入错误:
im
/
img
。如果你能在你的问题主体中提供一个较小的、可复制的这种效果的例子,那就太好了。即使只是打印
img
的形状也能提供信息。@NicholasM,谢谢。我做了一些改变。它是可复制的;但是,用户需要在其本地计算机中使用映像。形状取决于加载的图像。如果有帮助的话,我的是一个512X512图像,它变成了一个相同形状的2d矩阵。很有趣。谢谢你详细的回答。