Python (scikit-image):确定遮罩区域中最常见的颜色的最高性能方法

Python (scikit-image): Most performant way to determine most common color in a masked area

提问人:Thomas Slade 提问时间:9/11/2023 更新时间:9/11/2023 访问量:32

问:

我正在修改一个策略游戏,有两个RGB图像。一个在地图上定义省份区域,每个省份都是唯一的颜色。另一张图像定义了地图的地形。enter image description here

我有一个 python 脚本,它通过检查每个省份最常见的地形颜色来比较这两个图像以确定每个省份的地形类型。

例如,我可能会检查颜色省份 (0, 0, 255),发现其区域在地形图上完全充满了草原像素。

我目前这样做的具体方式是这样的:

from skimage import io
import numpy

# Takes an RGB map of shape x, y, and colour channels, and converts it to a 2D array of shape x, y, where each item in the 2D array is an int referring to the colour
# it represents, as indexed in the returned unique colours list.
def get_inverse_map(map, to_tuples = True):
    original_map_shape = (map.shape[0], map.shape[1])
    flattened_map = map.reshape(-1, map.shape[2])
    unique_map_cols, first_occurances, map_inverses, index_counts = numpy.unique(flattened_map, return_index = True, return_inverse = True, return_counts = True, axis = 0)
    unflattened_inverse_map = map_inverses.reshape(original_map_shape)

    if to_tuples:
        unique_map_tuples = [tuple(col) for col in unique_map_cols]
        return unflattened_inverse_map, unique_map_tuples, index_counts
    else:
        return unflattened_inverse_map, unique_map_cols, index_counts


province_map = io.imread(self.province_map_dir)
terrain_map = io.imread(self.terrain_map_dir)

inverse_province_map, unique_province_cols = get_inverse_map(province_map)[ : 2]
inverse_terrain_map, unique_terrain_cols = get_inverse_map(terrain_map)[ : 2]

for p in unique_province_cols:
    province_mask = inverse_province_map == p
    province_terrain_pixels = inverse_terrain_map[province_mask]

    occurances = numpy.bincount(province_terrain_pixels)
    mode_index = numpy.argmax(occurances) # This is the most common index of the colours in the terrain map that occur within province_mask
  1. 我将图像从 RGB 阵列(形状:x、x、3)转换为索引图(形状:x、x、1),以便更快地进行比较。
  2. 我得到了一个我想评估的省份的面具。
  3. 我获取了地形图中属于该省的像素 地图。
  4. 我使用 bincount 和 argmax 来找到最常见的一个。

因为我不能总是保证一个省份的边界内只有一种地形颜色(有时我会在边缘上绘画),所以我需要找到最常见的颜色,而不仅仅是检查一个像素。

我在非常大的图像上执行此操作,因此尽管我使用索引图来加快速度,但仍然需要时间。大部分时间似乎都浪费了,大概是我不确定。get_inverse_mapnumpy.unique

有没有更快的方法可以解决这个问题?

Python 性能 scikit-图像 区域 重叠

评论


答:

1赞 dankal444 9/11/2023 #1

你的方法的问题是遍历每个省份的整个地图。我的解决方案只做一次。

假设您知道:

  • 省份数 - (如果不是,则假设某个最大省份数)N
  • 可能的地形颜色数量 -C

狐狸

  1. 创建 2d numpy 数组来累积您的统计数据,大小为 ,每列表示province_terrain_statsN x C

  2. 遍历整个地图,在每个像素处读取其省份 IDX 和颜色 IDX。将 1 添加到统计信息的正确位置。 您可能需要创建一些帮助程序映射。 重要提示:使用 package 对整个地图进行此循环编码。如果您想使用此解决方案获得良好的性能,这是必须的。province_terrain_statscolor2idxnumba

  3. 对于每个省份,请使用查找最常见的地形province_terrain_statsnp.argmax

评论

1赞 Thomas Slade 9/11/2023
速度快得令人难以置信!谢谢