python - numpy.einsum 对 cv2 加载的数组的作用是否不同?
问题描述
numpy 文档中的示例einsum
说np.einsum('ij->i', a)
功能类似于np.sum(a, axis=1)
. 下面,示例 1 证实了这一点,而示例 2 则与之相矛盾。知道我在做什么(期望)错了吗?
经验 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])
经验 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
默认情况下创建一个 type 数组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
推荐阅读
- .net-core - .Net 5 Azure Function App,使用 Startup 类
- php - php xpath 从 Joomla / hikashop 描述中提取标签内容
- tensorflow - 数据集中张量的 ref() 不相等。为什么?
- c# - 如何在反序列化之前从 json 字符串中删除元素?
- javascript - IIS ASP NET Core 上的微调器加载失败
- c# - 每当刷新数据网格时向上移动垂直滚动条
- c# - 在 C# 中对数组进行排序,除了一个数字
- paypal - 如何添加贝宝购物篮?
- drupal - Drupal9 自定义模块
- uwp - UWP - 多语言:在运行时更改语言字符串