web-dev-qa-db-ja.com

NumPy配列内のすべての非黒ピクセルを選択する方法は?

NumPyを使用して、特定の色とは異なる画像のピクセルのリストを取得しようとしています。

たとえば、次の画像を処理しています:

enter image description here

私はすべてを使用してすべての黒いピクセルのリストを取得することができました:

np.where(np.all(mask == [0,0,0], axis=-1))

しかし、私がしようとすると:

np.where(np.all(mask != [0,0,0], axis=-1))

私はかなり奇妙な結果を得る:

enter image description here

NumPyは、インデックスがR、G、およびBが0でない場合にのみ返されたようです

ここに私がやろうとしていることの最小限の例があります:

import numpy as np
import cv2

# Read mask
mask = cv2.imread("path/to/img")
excluded_color = [0,0,0]

# Try to get indices of pixel with different colors
indices_list = np.where(np.all(mask != excluded_color, axis=-1))

# For some reason, the list doesn't contain all different colors
print("excluded indices are", indices_list)

# Visualization
mask[indices_list] = [255,255,255]

cv2.imshow(mask)
cv2.waitKey(0)
6
ofir dubi

黒以外のピクセルをすべて選択する2番目のケースでは、 np.any ではなく np.all を使用する必要があります。

np.any(image != [0, 0, 0], axis=-1)

または、ブール配列を ~ で反転することにより、単に黒のピクセルの補数を取得します。

black_pixels_mask = np.all(image == [0, 0, 0], axis=-1)
non_black_pixels_mask = ~black_pixels_mask

作業例:

import numpy as np
import matplotlib.pyplot as plt


image = plt.imread('example.png')
plt.imshow(image)
plt.show()

enter image description here

image_copy = image.copy()

black_pixels_mask = np.all(image == [0, 0, 0], axis=-1)

non_black_pixels_mask = np.any(image != [0, 0, 0], axis=-1)  
# or non_black_pixels_mask = ~black_pixels_mask

image_copy[black_pixels_mask] = [255, 255, 255]
image_copy[non_black_pixels_mask] = [0, 0, 0]

plt.imshow(image_copy)
plt.show()

enter image description here


誰かがmatplotlibを使用して結果をプロットし、完全に黒い画像または警告を取得する場合は、この投稿を参照してください: すべての非黒ピクセルを1色に変換しても期待される出力は生成されません

10
Georgy

必要度:この形状の行列が必要=(any、any、3)

解決策:

COLOR = (255,0,0)
indices = np.where(np.all(mask == COLOR, axis=-1))
indexes = Zip(indices[0], indices[1])
for i in indexes:
    print(i)

解決策2:

特定の色の間隔、たとえばREDを取得します。

COLOR1 = [250,0,0]
COLOR2 = [260,0,0] # doesnt matter its over limit

indices1 = np.where(np.all(mask >= COLOR1, axis=-1))
indexes1 = Zip(indices[0], indices[1])

indices2 = np.where(np.all(mask <= COLOR2, axis=-1))
indexes2 = Zip(indices[0], indices[1])

# You now want indexes that are in both indexes1 and indexes2

解決策3-動作することが確認済み

以前のバージョンが機能しない場合、100%動作するソリューションが1つあります

RGBチャネルからHSVに変換します。 3D画像から2Dマスクを作成します。 2Dマスクには色相値が含まれます。 RGBは3つの値を持つベクトルですが、Hueは1つの値なので、色相の比較はRGBよりも簡単です。 Hue値を含む2Dマトリックスを作成したら、上記のようにします。

HUE1 = 0.5
HUE2 = 0.7 

indices1 = np.where(HUEmask >= HUE1)
indexes1 = Zip(indices[0], indices[1])

indices2 = np.where(HUEmask <= HUE2)
indexes2 = Zip(indices[0], indices[1])

彩度と値についても同じことができます。

0
Martin