numpy/scipy 中的平方差总和 (SSD)

Posted

技术标签:

【中文标题】numpy/scipy 中的平方差总和 (SSD)【英文标题】:Sum of Square Differences (SSD) in numpy/scipy 【发布时间】:2011-01-18 01:58:44 【问题描述】:

我正在尝试使用 Python 和 Numpy/Scipy 来实现图像处理算法。分析器告诉我很多时间都花在以下函数上(经常调用),它告诉我两张图像之间的平方差之和

def ssd(A,B):
    s = 0
    for i in range(3):
        s += sum(pow(A[:,:,i] - B[:,:,i],2))
    return s

如何加快速度?谢谢。

【问题讨论】:

【参考方案1】:

只是

s = numpy.sum((A[:,:,0:3]-B[:,:,0:3])**2)

(如果形状始终为 (,,3),我预计可能只是 sum((A-B)**2)

也可以使用求和法:((A-B)**2).sum()

对吗?

【讨论】:

砰。我过得很慢。我的跑步时间减半。 值得注意的是,为此您必须使用numpy.sum,而不是内置的sum,它将在第一个维度上找到总和并返回一个新的一维数组. ((A-B)**2).sum(-1) 如果只想在最后一个轴上添加,则需要指定轴参数。只需使用 sum() 添加数组的所有条目(首先解开)【参考方案2】:

顺便提一下,也可以使用np.dot

def ssd(A,B):
  dif = A.ravel() - B.ravel()
  return np.dot( dif, dif )

这可能比使用np.sum**2 的替代方法更快并且可能更准确,但如果您想沿指定轴计算ssd,则不起作用。在这种情况下,可能会有一个神奇的下标公式使用np.einsum

【讨论】:

【参考方案3】:

我很困惑你为什么选择i in range(3)。那应该是整个阵列,还是只是一部分?

总的来说,您可以用 numpy 中定义的操作替换其中的大部分内容:

def ssd(A,B):
    squares = (A[:,:,:3] - B[:,:,:3]) ** 2
    return numpy.sum(squares)

这样你可以做一个操作而不是三个,使用numpy.sum可能比内置的sum更好地优化加法。

【讨论】:

+1 scipy.stats.stats.ss(平方和)就是这样做的。【参考方案4】:

不知道 power 2 的 pow() 函数会不会很快。试试:

def ssd(A,B):
    s = 0
    for i in  range(3):
        s += sum((A[:,:,i] - B[:,:,i])*A[:,:,i] - B[:,:,i])
    return s

【讨论】:

A-B 乘法中缺少括号。【参考方案5】:

Ritsaert Hornstra 的回答得到了 2 个否定分数(诚然,我没有看到它的原始形式......)

这是真的。

对于大量迭代,使用 '**' 运算符或 pow(x,y) 方法所花费的时间通常是手动将这些对相乘的两倍。如果有必要使用 math.fabs() 方法,如果它抛出 NaN(有时尤其是在使用 int16s 等时会这样做),它仍然只需要给定两个函数的大约一半时间。

对于我知道的原始问题并不重要,但绝对值得知道。

【讨论】:

【参考方案6】:

你可以试试这个:

dist_sq = np.sum((A[:, np.newaxis, :] - B[np.newaxis, :, :]) ** 2, axis=-1)

可以在此处找到更多详细信息(“k-Nearest Neighbors”示例): https://jakevdp.github.io/PythonDataScienceHandbook/02.08-sorting.html

【讨论】:

【参考方案7】:

在 Ruby 语言中,您可以通过这种方式实现此目的

def diff_btw_sum_of_squars_and_squar_of_sum(from=1,to=100) # use default values from 1..100. 
((1..100).inject(:+)**2) -(1..100).map |num| num ** 2.inject(:+)
end

diff_btw_sum_of_squars_and_squar_of_sum #call for above method

【讨论】:

以上是关于numpy/scipy 中的平方差总和 (SSD)的主要内容,如果未能解决你的问题,请参考以下文章

如何检查 NumPy 和 SciPy 中的 BLAS/LAPACK 链接?

N点与numpy/scipy中的参考之间的有效距离计算

Numpy / Scipy中的快速线性插值“沿路径”

Matlab 中的 FFT 和 numpy / scipy 给出不同的结果

使用 numpy/scipy 最小化 Python multiprocessing.Pool 中的开销

使用 numpy/scipy 识别数字信号的斜率变化?