Python 快速找到像素区域质心的方法

Python 快速找到像素区域质心的方法,python,numpy,optimization,centroid,Python,Numpy,Optimization,Centroid,对于一个游戏,我制作了一个区域地图,由像素组成,每个区域都有不同的颜色。从那以后,我想在每个地区加上名字 出于视觉目的,我想把名字放在区域的质心上。因此,我使用PIL将图像转换为单个大矩阵。我构建了一个类来记录每个区域的质心数据,这些数据收集在字典中。然后,我迭代像素以处理质心。此方法非常慢,对于2400 x 1100地图,大约需要一分钟 territory\u map=numpy.array([ [0, 0, 0, 1, 0, 0, 0], [0, 2, 2, 1, 0, 0, 0], [2,

对于一个游戏,我制作了一个区域地图,由像素组成,每个区域都有不同的颜色。从那以后,我想在每个地区加上名字

出于视觉目的,我想把名字放在区域的质心上。因此,我使用PIL将图像转换为单个大矩阵。我构建了一个类来记录每个区域的质心数据,这些数据收集在字典中。然后,我迭代像素以处理质心。此方法非常慢,对于2400 x 1100地图,大约需要一分钟

territory\u map=numpy.array([
[0, 0, 0, 1, 0, 0, 0],
[0, 2, 2, 1, 0, 0, 0],
[2, 2, 1, 1, 3, 3, 3],
[2, 0, 0, 1, 3, 0, 0],
])
质心_数据={}
类质心记录(对象):
定义初始化(self,x,y):
超级(质心记录,自我)。\uuuuu init\uuuuuu()
self.x=浮动(x)
self.y=浮动(y)
self.volume=1
def附加质量(自身、x、y):
#新卷=(旧卷*旧卷+x)/(旧卷+1),
#因此,new_x=old_x+(x-old_x)/v,
#对于v=体积+1。
自卷+=1
self.x+=(x-self.x)/self.volume
self.y+=(y-self.y)/self.volume
对于范围内的y(区域映射形状[0]):
对于范围内的x(区域地图形状[1]):
单元格=区域\地图[y][x]
如果单元格==0:
持续
如果单元格不在质心_数据中:
质心_数据[单元]=质心记录(x,y)
其他:
质心数据[单元]。添加质量(x,y)
对于质心_数据中的区域:
数据=质心_数据[面积]
打印(f“{area}:({data.x},{data.y})”)
应打印以下内容:

1: (2.8, 1.6)
2: (0.8, 1.8)
3: (4.75, 2.25)

有什么更快的方法可以做到这一点吗?

颜色质心的每个坐标只是该颜色点的所有坐标的平均值。因此,我们可以使用
dict
理解:

import numpy as np

n_colours = territory_map.max()

{i: tuple(c.mean() for c in np.where(territory_map.T == i)) 
 for i in range(1, n_colours + 1)}
输出:

{1: (2.8, 1.6), 
 2: (0.8, 1.8), 
 3: (4.75, 2.25)}
注意,我们需要进行转置,因为在
numpy
中,行(y坐标)位于列(x坐标)之前

随机生成的数据所花费的时间:

81.6 ms ± 5.36 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

颜色质心的每个坐标只是该颜色点的所有坐标的平均值。因此,我们可以使用
dict
理解:

import numpy as np

n_colours = territory_map.max()

{i: tuple(c.mean() for c in np.where(territory_map.T == i)) 
 for i in range(1, n_colours + 1)}
输出:

{1: (2.8, 1.6), 
 2: (0.8, 1.8), 
 3: (4.75, 2.25)}
注意,我们需要进行转置,因为在
numpy
中,行(y坐标)位于列(x坐标)之前

随机生成的数据所花费的时间:

81.6 ms ± 5.36 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)