用整数替换numpy数组中的RGB值非常慢 [英] Replacing RGB values in numpy array by integer is extremely slow

查看:146
本文介绍了用整数替换numpy数组中的RGB值非常慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将numpy数组的rgb值替换为单个整数表示。我的代码有效,但速度太慢,我正在迭代每个元素。我可以加快速度吗?我是numpy的新手。

I want to replace the rgb values of a numpy array to single integer representations. My code works but it's too slow, I am iterating over every element right now. Can I speed this up? I am new to numpy.

from skimage import io

# dictionary of color codes for my rgb values
_color_codes = {
    (255, 200, 100): 1,
    (223, 219, 212): 2,
    ...
}

# get the corresponding color code for the rgb vector supplied
def replace_rgb_val(rgb_v):
    rgb_triple = (rgb_v[0], rgb_v[1], rgb_v[2])
    if rgb_triple in _color_codes:
        return _color_codes[rgb_triple]
    else:
        return -1

# function to replace, this is where I iterate
def img_array_to_single_val(arr):
    return np.array([[replace_rgb_val(arr[i][j]) for j in range(arr.shape[1])] for i in range(arr.shape[0])])


# my images are square so the shape of the array is (n,n,3)
# I want to change the arrays to (n,n,1)
img_arr = io.imread(filename)
# this takes from ~5-10 seconds, too slow!
result = img_array_to_single_val(img_arr)


推荐答案

替换相反的颜色值。查找每个RGB三元组,并在新数组中设置相应的索引:

Replace the color values the other way round. Look for each RGB-triple, and set the corresponding index in a new array:

def img_array_to_single_val(arr, color_codes):
    result = numpy.ndarray(shape=arr.shape[:2], dtype=int)
    result[:,:] = -1
    for rgb, idx in color_codes.items():
        result[(arr==rgb).all(2)] = idx
    return result

让我们将颜色索引分配分开:首先 arr == rgb 将每个pixel-rgb-values与列表 rgb进行比较,导致anxnx 3 - 布尔数组。只有当所有三个颜色部分都相同时,我们才发现匹配,所以 .all(2)减少最后一个轴,使用<$对于匹配 rgb 的每个像素,c $ c> True 。最后一步是,使用这个掩码设置相应像素的索引。

Let's take the color-index assignment apart: First arr==rgb compares each pixel-rgb-values with the list rgb, leading to a n x n x 3 - boolean array. Only if all three color-parts are the same, we found a match, so .all(2) reduces the last axis, leeding to a n x n - boolean array, with True for every pixel matching rgb. Last step is, to use this mask to set the index of the corresponding pixels.

更快,可能是,首先将RGB数组转换为int32,并且然后做索引翻译:

Even faster, it might be, to first convert the RGB-array to int32, and then do the index translation:

def img_array_to_single_val(image, color_codes):
    image = image.dot(numpy.array([65536, 256, 1], dtype='int32'))
    result = numpy.ndarray(shape=image.shape, dtype=int)
    result[:,:] = -1
    for rgb, idx in color_codes.items():
        rgb = rgb[0] * 65536 + rgb[1] * 256 + rgb[2]
        result[arr==rgb] = idx
    return result

对于真正大或多的图像,首先应创建直接颜色映射:

For really large or many images you should first create a direct color mapping:

color_map = numpy.ndarray(shape=(256*256*256), dtype='int32')
color_map[:] = -1
for rgb, idx in color_codes.items():
    rgb = rgb[0] * 65536 + rgb[1] * 256 + rgb[2]
    color_map[rgb] = idx

def img_array_to_single_val(image, color_map):
    image = image.dot(numpy.array([65536, 256, 1], dtype='int32'))
    return color_map[image]

这篇关于用整数替换numpy数组中的RGB值非常慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆