15.1_概述

15.1 概述

图像与模板这两幅二维图像通过以下公式来计算相关系数:

γ(s,t)=xy[I(x,y)Iˉ(x,y)][T(xs,yt)Tˉ]xy[I(x,y)Iˉ(x,y)]2xy[T(xs,yt)Tˉ]2\gamma (s, t) = \frac {\sum_ {x} \sum_ {y} [ I (x , y) - \bar {I} (x , y) ] [ T (x - s , y - t) - \bar {T} ]}{\sqrt {\sum_ {x} \sum_ {y} [ I (x , y) - \bar {I} (x , y) ] ^ {2}} \sum_ {x} \sum_ {y} [ T (x - s , y - t) - \bar {T} ] ^ {2}}

其中,I和T分别代表图像和模板, T\overline{T} 为模板像素的平均值, Iˉ\bar{I} 为图像中对应模板范围的像素的平均值。

该系数的值将介于 [1.0,1.0][-1.0, 1.0] 的范围。值1.0意味着一个完美的匹配。归一化互相关的一种优化实现方案,不仅提取出能被预先计算的统计量,而且还使用加和而不是平均值计算,以避免输入数据的多次遍历。若有N个像素进行比较,用 xy[T(x,y)]N\frac{\sum_{x} \sum_{y} [T(x,y)]}{N}xy[T(x,y)]N\frac{\sum_{x} \sum_{y} [T(x,y)]}{N} 分别来代替 T\overline{T}Iˉ\bar{I} [1],并在分子、分母上同时乘以N,即会产生一个完全使用加和来表示的系数。略去坐标,公式可以整理成:

NΣITΣIΣT(NΣI2(ΣI)2)(NΣT2(ΣT)2)=\frac {N \Sigma I T - \Sigma I \Sigma T}{\sqrt {\left(N \Sigma I ^ {2} - (\Sigma I) ^ {2}\right) \left(N \Sigma T ^ {2} - (\Sigma T) ^ {2}\right)}} =

式中的 Σ\Sigma 表示 Σx,y\Sigma_{\mathrm{x,y}} 。——译者注

假设该模板对多个其他的相关计算来说都是相同的,则可以预先计算出模板的统计量 ΣT\Sigma \mathrm{T}ΣT2\Sigma \mathrm{T}^{2} ,同理可以计算分母的子表达( NΣT2(ΣT)2\mathrm{N} \Sigma \mathrm{T}^{2} - (\Sigma \mathrm{T})^{2} )。下表给出上述公式符号的C语言变量表示:

然后可以使用以下函数来计算一个归一化相关值。

float CorrelationValue(float SumI, float SumISq, float SumT, float SumTSq, float SumIT, float N) { float Numerator = N*SumIT - SumI*SumT; float Denominator = (N*SumISq - SumI*SumI)*(N*SumTSq - SumT*SumT); return Numerator / sqrtf(Denominator); }

实际应用中使用这个算法时,该模板在许多调用中都保持不变,只是在图像的不同偏移处进行匹配。所以预先计算模板的统计量和分母子表达式很有意义。

float fDenomExp = N*SumSqT - SumT*SumT;

实际中,建议采用双精度来计算fDenomExp。

float fDenomExp = (float) ((double) N*SumSqT - (double) SumT*SumT);

注意 此计算在CPU上执行,一个模板需要计算一次。

而乘以平方根的倒数比除以平方根运算更快,所以我们有函数CorrelationValue()定义如下:

float CorrelationValue(float SumI, float SumISq, float SumIT, float N, float fDenomExp)
float Numerator  $=$  cPixels\*SumIT-SumI\*SumT; float Denominator  $=$  fDenomExp\*(cPixels\*SumISq-SumI\*SumI); return Numerator \*rsqrtf(Denominator);

因此,这个算法的优化实现只需要三个用来计算给定相关系数的像素的统计量: ΣI\Sigma \mathrm{I}ΣI2\Sigma \mathrm{I}^2ΣIT\Sigma \mathrm{IT} 。流处理器簇中包含了专门支持整数乘加运算(multiply-add)的硬件,所以GPU能够极快的执行此运算。

CUDA提供了如下几种将数据复制至流处理器簇的方法:

·使用全局内存或纹理内存存储图像或者模板

·使用常量内存存储模板或其他可能的特定模板参数(可达64KB)

·使用共享内存来保存图像和/或模板值以备重用

本章假定所有图像都为8位灰度图像。硬件在更高精度的图像中也具有非常好的表现,但这里是为了简化高效利用全局内存和共享内存的问题。

本章中所有的CUDA实现都使用了纹理内存来存储同模板对比的图像,这样做有如下几个原因:

·纹理单元能够更加优雅、高效的处理边界条件。

·在进行相邻的相关值计算时,纹理缓存可以在重用性方面聚集外部的带宽。

·对相关性搜索算法来说,纹理缓存的2D局部性能够很好地适合算法的访存模式。

我们将继续权衡使用纹理内存和常量内存存储模板。

[1]此处修正了原书错误。——译者注

15.1_概述 - CUDA专家手册 | OpenTech