numpy.einsum 对 cv2 加载的数组有不同的作用吗?
Does numpy.einsum act differently on arrays loaded by cv2?
einsum
的example in numpy's documentation表示np.einsum('ij->i', a)
的功能类似于np.sum(a, axis=1)
。下面的示例 1 证实了这一点,而示例 2 则与之矛盾。知道我在做什么(预期)错了吗?
Exp 1.
import numpy as np
a = np.arange(25).reshape(5,5)
b1 = np.einsum('ij->i', a) # array([ 10, 35, 60, 85, 110])
b2 = np.sum(a, axis=1) # array([ 10, 35, 60, 85, 110])
Exp 2.
import numpy as np
import cv2
img_path = "path/to/an/image.png"
im = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) # type: numpy.ndarray
n1 = np.einsum('ij->i', im)
n2 = np.sum(img, axis=1)
# to show that they are different.
print(np.max(n1), np.max(n2)) # out: 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
einsum
的example in numpy's documentation表示np.einsum('ij->i', a)
的功能类似于np.sum(a, axis=1)
。下面的示例 1 证实了这一点,而示例 2 则与之矛盾。知道我在做什么(预期)错了吗?
Exp 1.
import numpy as np
a = np.arange(25).reshape(5,5)
b1 = np.einsum('ij->i', a) # array([ 10, 35, 60, 85, 110])
b2 = np.sum(a, axis=1) # array([ 10, 35, 60, 85, 110])
Exp 2.
import numpy as np
import cv2
img_path = "path/to/an/image.png"
im = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) # type: numpy.ndarray
n1 = np.einsum('ij->i', im)
n2 = np.sum(img, axis=1)
# to show that they are different.
print(np.max(n1), np.max(n2)) # out: 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