[英]Numpy filtering using array
我知道以前有人問過這個問題,但對於我的特定用例似乎沒有任何內容。
我有一個 numpy 數組obs
代表彩色圖像並具有形狀(252, 288, 3)
。
我想將不是純黑色的每個像素都轉換為純白色。
我嘗試過的是obs[obs,= [0, 0, 0]] = [255, 255, 255]
但它給出了以下異常:
ValueError: NumPy boolean array indexing assignment cannot assign 3 input values to the 807 output values where the mask is true
結果與obs[obs[:, :],= [0, 0, 0]] = [255, 255, 255]
相同。 另外, (obs[:, :],= [0, 0. 0]).shape
是(252, 288, 3)
我不明白為什么它不是簡單的(252, 288)
(布爾矩陣)。
我考慮過使用obs[obs != 0] = 255
但這不會產生我想要的效果,因為純綠色( [0, 255, 0]
)的像素將被處理組件明智並且仍然是[0, 255, 0]
過濾后,而不是實際上是白色的( [255, 255, 255]
)。
為什么我到目前為止嘗試過的東西都沒有工作,我應該如何處理這個問題?
Boolean 類似obs[obs,= [0, 0, 0]]
的索引返回一個一維數組,其中包含obs
中滿足給定條件的所有元素。 看下面的例子:
obs = np.array([
[[88, 0,99],
[ 0, 0, 0]],
[[ 0, 0, 0],
[88,77,66]]
])
obs,= [0, 0, 0]
返回一個 boolean 數組:
array([[[ True, False, True],
[False, False, False]],
[[False, False, False],
[ True, True, True]]])
然后obs[obs,= [0, 0, 0]]
返回一個一維數組,其中包含掩碼為True
的所有元素: array([88, 99, 88, 77, 66])
。
因此,您需要在where
測試是否有any
顏色分量不等於 0:
np.where(obs.any(axis=-1, keepdims=True), 255, obs)
結果:
array([[[255, 255, 255],
[ 0, 0, 0]],
[[ 0, 0, 0],
[255, 255, 255]]])
請注意,您需要keepdims=True
才能啟用廣播到obs
的原始形狀。 否則,您必須通過np.where(obs.any(-1)[...,np.newaxis], 255, obs)
或np.where(np.atleast_3d(obs.any(-1)), 255, obs)
不太優雅。
根據您實際想要做的事情,有多種可能性。 讓我們先編寫設置代碼(所有可能性都通用),這樣您就可以明白我的意思了。
#!/usr/bin/env python3
import numpy as np
# Make a repeatable random image
np.random.seed(764)
obs = np.random.randint(0,32,(252,288,3), dtype=np.uint8)
出於測試目的,此圖像在以下位置恰好有純黑色像素:
obs[ 21, 267]
obs[ 28, 252]
obs[ 69, 127]
obs[ 98, 0]
obs[124, 210]
obs[133, 98]
obs[160, 81]
obs[167, 48]
obs[217, 237]
現在,假設您想要一個新的純 True/False boolean 黑色像素掩碼,您可以使用:
mask = obs.any(axis=-1)
該解決方案具有以下特點:
time: 876 µs
mask.shape: (252,288)
mask.nbytes: 72576
mask.dtype: 'bool'
您隨后可以像這樣使用和重復使用該掩碼:
# Make masked pixels red
obs[mask,:] = [255,0,0]
# Make unmasked pixels cyan
obs[~mask,:] = [0,255,255]
現在假設您想要一個新的灰度圖像,具有黑白像素,您可以使用:
grey = obs.any(axis=-1) * np.uint8(255)
該解決方案具有以下特點:
time: 887 µs
grey.shape: (252,288)
grey.nbytes: 72576
grey.dtype: np.uint8
現在假設您想要將已經存在的“obs”就地更改為純黑白(但仍然是 RGB):
obs[obs.any(axis=-1),:] = [255,255,255]
該解決方案具有以下特點:
time: 1.98 ms
obs.shape: (252,288,3)
obs.nbytes: 217728
obs.dtype: np.uint8
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.