什么是计算重心或质心(cog)的好算法和框架?

计算科学 算法 计算几何 计算物理学 图像处理 模式识别
2021-12-14 04:40:01

我想拍张照片,将其细分为正方形或(理想情况下)六边形的镶嵌,然后找到镶嵌的每个单元的重心(或者,如果您愿意,质心) .

对于任何图像,输出都是点矩阵。对于附图,类似这样的东西(在极坐标中 -):(r,θ)

(5,5Π/4) (0,0) (1,7Π/4) (1,5Π/4)
     (5,3Π/4) (0,0) (5,Π/2) 
(0.0) (0,0) (0.0) (0,0)  

我附上了一张图片,显示了我的意思。 六边形镶嵌。 黑色圆圈是每个单元格的重心 - 在透明或单色单元格中,它位于单元格的中心。 在带有绿色齿轮的齿轮中,齿轮被拉向齿轮

简而言之,我的问题是在此镶嵌中用于计算 cog 的最佳方法...对于正方形,很容易计算每行的加权平均值,但这太粗略了. 迭代一般镶嵌(理想)或六边形镶嵌的好方法是什么?

我在“计算机图形”组中问过这个问题,但没有得到任何答复。我认为它可能更适合这里的技能。

1个回答

有几种选择:

备选方案#1:您需要为镶嵌的每个单元格查找单元格中包含的像素列表。为此,您可以使用光栅化算法。您可以使用我的开源实现 [1]。如果性能是一个问题,您也可以使用 GPU 来做到这一点。

备选方案#2(最简单的):(如果您有许多不同的图像要处理并且有一个固定的镶嵌):首先生成一个“图像”,其中每个像素都包含包含该像素的单元格的索引。您只需执行一次(它完全独立于输入图像)。然后您可以使用以下算法计算像素质量和质心(其中 cell(i,j) 表示预先计算的“图像”):

for each i,j
   k = cell(i,j)
   mass[k] = mass[k] + image(i,j)
   centroid[k] = centroid[k] + image(i,j)*(i,j)

for each k
   centroid[k] = centroid[k] / mass[k]
   convert centroid[k] in polar coordinates (if needed)

其中 mass[] 是一个标量数组,centroid[] 是一个二维点数组(维度 = 两者的单元数)。

备选方案#3:如果您的细分是 Voronoi 图(即,如果单元格是与列表的所有其他“站点”(xj,yj)相比更接近“站点”(xi,yi)的点集网站:

for each i,j
   k = nearest_site(i,j)
   mass[k] = mass[k] + image(i,j)
   centroid[k] = centroid[k] + image(i,j)*(i,j)

for each k
   centroid[k] = centroid[k] / mass[k]
   convert centroid[k] in polar coordinates (if needed)

要实现最近站点(),您可以将所有站点放在 Kd 树中,或者利用细分的结构(例如,在您的特定情况下,您可以通过比较与几个站点的距离来找到最近的站点,基于(i,j))

[1] http://alice.loria.fr/publications/papers/2006/EGSR_Ardeco//supplemental/sources.html