それぞれが1つのエンティティを表す10種類の色を含む600個の注釈付きセマンティックセグメンテーションマスク画像を有するとする。これらの画像は、n = 600、3 = RGBチャンネル、72 =高さ、96 =幅の形状の数字の配列(600,3,72,96)である。画像のコレクション内のピクセル(R、G、B)を別個のピクセルカラー値インデックスにマップする方法はありますか?
numpy配列の各RGBピクセルをカラーインデックス値にマップするにはどうすればよいですか?たとえば、カラーリストは[(128,128,0)、(240,128,0)、... n]であり、numpy配列内のすべての(240,128,0)ピクセルはインデックスに変換されます一意のマッピング(= 1)の値。
これを効率的かつ少ないコードで実行するにはどうすればよいですか?ここで私が思いついた解決策がありますが、それはかなり遅いです。
# Input imgs.shape = (N, 3, H, W), where (N = count, W = width, H = height)
def unique_map_pixels(imgs):
original_shape = imgs.shape
# imgs.shape = (N, H, W, 3)
imgs = imgs.transpose(0, 2, 3, 1)
# tupleview.shape = (N, H, W, 1); contains tuples [(R, G, B), (R, G, B)]
tupleview = imgs.reshape(-1, 3).view(imgs.dtype.descr * imgs.shape[3])
# get unique pixel values in images, [(R, G, B), ...]
uniques = list(np.unique(tupleview))
# map uniques into hashed list ({"RXBXG": 0, "RXBXG": 1}, ...)
uniqmap = {}
idx = 0
for x in uniques:
uniqmap["%sX%sX%s" % (x[0], x[1], x[2])] = idx
idx = idx + 1
if idx >= np.iinfo(np.uint16).max:
raise Exception("Can handle only %s distinct colors" % np.iinfo(np.uint16).max)
# imgs1d.shape = (N), contains RGB tuples
imgs1d = tupleview.reshape(np.prod(tupleview.shape))
# imgsmapped.shape = (N), contains uniques-index values
imgsmapped = np.empty((len(imgs1d))).astype(np.uint16)
# map each pixel into unique-pixel-ID
idx = 0
for x in imgs1d:
str = ("%sX%sX%s" % (x[0], x[1] ,x[2]))
imgsmapped[idx] = uniqmap[str]
idx = idx + 1
imgsmapped.shape = (original_shape[0], original_shape[2], original_shape[3]) # (N, H, W)
return (imgsmapped, uniques)
テストそれ:
import numpy as np
n = 30
pixelvalues = (np.random.rand(10)*255).astype(np.uint8)
images = np.random.choice(pixelvalues, (n, 3, 72, 96))
(mapped, pixelmap) = unique_map_pixels(images)
assert len(pixelmap) == mapped.max()+1
assert mapped.shape == (len(images), images.shape[2], images.shape[3])
assert pixelmap[mapped[int(n*0.5)][60][81]][0] == images[int(n*0.5)][0][60][81]
print("Done: %s" % list(mapped.shape))
うーん。なぜあなたはこれをしたいのですか?それはちょうど理由のないステップを追加しているようだ。これらのカラーインデックスで何かをしたいのであれば、dictを検索してRGBタプルに戻す必要がありますか?編集:気にしない、参照してください。たくさんの画像を格納している場合は、タプルの束の代わりにintを格納する方が効率的です。なぜなら、とにかく特定の数の色を予測しているからです(10)。 – Anonymous
はい、色の数が限られています。一意のインデックスが必要なのは、ピクセルカラーではなくピクセルカテゴリを予測するアルゴリズムにピクセルを供給しているからです。グレースケール画像(例えば、輝度0〜10)も同様であるが、画像は標準ツール(=画像ビューア、エディタなど)によって容易に視覚化できない。最後に、予測の後、RGB値にマップする必要があります。 –