最近在做字体渲染的相关内容,利用FreeType可以提取出ttf文件中具体某个字符的轮廓图,这个轮廓图是二值化的图像,后续的处理需要用到图像上的每个点到字体轮廓线的最近距离,即要求平面上的每个点与轮廓线的最近邻。可以考虑使用KD树,这里介绍一下Felzenszwalb算法,它可以在O(KN)的复杂度内完成所有点的最近邻求解,其中K是点集的维度,N是点的总个数。
一维情形的求解
首先介绍一维点集的最近邻求解,并且不难由一维推广到更高维的情况。首先先看一下核心的计算式:设集合 S S 为一个一维的点集, 表示二值化后的点集的状态,每个点的取值为0或1,每个点的最近邻可以由如下式子得出
Df(p)=min((p−q)2+f(q)),q∈S D f ( p ) = m i n ( ( p − q ) 2 + f ( q ) ) , q ∈ S
对于本文所提到的情形下,其中
f(q)={
0,∞,G(q)=1G(q)=0 f ( q ) = { 0 , G(q)=1 ∞ , G(q)=0
如果是第一次看见这种表达,可能不太好理解,那么来仔细考虑一下这个式子,右侧是一个取最小值的表达,对什么取最小值呢? (x−p)2+f(q),q∈S ( x − p ) 2 + f ( q ) , q ∈ S 是 q q 个函数,更细一点来看它们都是开口向上抛物线,抛物线的极小值点为 自变量为 x x ,那么上面这个式子其实是在对所有的这 个函数在自变量为 x=p x = p 的时候的函数值取最小值,由于当