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
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.
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]
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…