我正在研究以下代码片段来计算两个图像的相似性:
import cv2, sys [5/981]
import numpy as np
def compute_hisgram(path):
hog = cv2.HOGDescriptor()
im = cv2.imread(path)
img_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
h = hog.compute(im)
return h
def histogram_intersection(h1, h2):
# minima = np.minimum(h1, h2)
# intersection = np.true_divide(np.sum(minima), np.sum(h2))
#return intersection
return cv2.compareHist(h1, h2, cv2.HISTCMP_INTERSECT)
h1 = compute_hisgram(sys.argv[1])
h2 = compute_hisgram(sys.argv[2])
h12 = histogram_intersection(h1, h2)
# to normalize, we need to divide by the original image.
print (h12/np.sum(h2))
而当以两张图像作为输入执行上述代码时,它会输出一个接近 1.0 的值,这似乎很正常。
python3 t.py image1.png image2.png
0.9932124283243112
然而,令我非常惊讶的是,当最后一条语句以以下方式编写时:
print (h12/sum(h2))
输出不同,是一个大于 1 的数字!而且代码比以前慢得多。
python3 t.py image1.png image2.png
[1.1126189]
是 Pythonsum
函数的错误吗?还是我在这里错过了什么?谢谢。
======== 更新
这是print (h2)
的输出:
[[0.0924307 ]
[0.05680538]
[0.07150667]
...
[0.10983132]
[0.17328948]
[0.0688285 ]]
h12
:
4517725.058263534
这些函数以不同的方式进行求和。 例:
a = np.full((9000,), 1/9000)
sum(a)
# 0.9999999999998027
np.sum(a)
# 0.9999999999999999
math.fsum(a)
# 1.0
所以 np.sum() 给出的结果比 sum() 更准确。
有关一些解释,请参见 fsum:
math.fsum(可迭代)
返回可迭代对象中值的准确浮点总和。通过跟踪多个中间部分避免精度损失 算法的准确性取决于 IEEE-754 算术保证和舍入模式为半偶的典型情况。在一些 非 Windows 版本,底层 C 库使用扩展精度 加法,偶尔可能使中间和加法双倍,导致 它以最不重要的一点关闭。
有关进一步讨论和两种替代方法,请参阅 ASPN 说明书配方以实现准确的浮点求和。
您可能还想看看 accupy.有一些关于不同求和方法准确性的非常翔实的图表。
下面是一个非常病理的例子(从这里开始),显然准确的结果正好是20000:
a = [1, 1e100, 1, -1e100] * 10000
math.fsum(a), np.sum(a), sum(a)
# (20000.0, 0.0, 0.0)