我有以下影像:

我想過濾掉一種顏色(RGB 風格)
r, g, b = 119, 226, 108
img = cv2.imread('img.png', cv2.IMREAD_UNCHANGED)
idx = np.where(np.all(img == [b, g, r], axis=-1))
img[idx[0], idx[1], :] = [255, 255, 255]
cv2.imshow('img', img)
cv2.waitKey(0)
輸出如下所示:

但是,我想做相反的事情,只顯示顏色。我寫的
img = cv2.imread('img.png', cv2.IMREAD_UNCHANGED)
idx = np.where(np.all(img != [b, g, r], axis=-1))
img[idx[0], idx[1], :] = [255, 255, 255]
cv2.imshow('img', img)
cv2.waitKey(0)
輸出現在顯示兩種顏色?

綠色輪廓也不相同。我做錯了什么,正確的輸出是什么?
uj5u.com熱心網友回復:
為了索引顏色不匹配的所有單元格,您只需要檢查其中一種顏色不匹配,而不是全部匹配。我相信這是您正在尋找的代碼:
img = cv2.imread('img.png', cv2.IMREAD_UNCHANGED)
idx = np.where(np.any(img != [b, g, r], axis=-1)) # any instead of all
img[idx[0], idx[1], :] = [255, 255, 255]
cv2.imshow('img', img)
cv2.waitKey(0)
uj5u.com熱心網友回復:
邏輯錯誤。
你說:
idx = np.where(np.all(img == [b, g, r], axis=-1))idx = np.where(np.all(img != [b, g, r], axis=-1))
...這是錯誤地反轉。正確的布爾邏輯(好的一階邏輯,但你明白了):
not (all (equal)) <=> any (not (equal))
因此,您需要將“全部”切換為any.
np.where有雙重操作。對于單個引數,它的作用類似于np.nonzero,給出索引串列。對于多個引數,它從第二個或第三個陣列中進行選擇,具體取決于第一個陣列中的真值。如果你想使用索引,你應該更喜歡使用np.nonzero它自己。
但是,我建議您不要使用索引,而是計算一次掩碼,然后反轉:
mask = (img == [b, g, r]).all(axis=-1) # np.all() exists but I find this nice too
inverted = ~mask
# then
img[mask] = [255, 255, 255]
# or
img[~mask] = [255, 255, 255]
事實上,你為什么不直接使用cv.inRange()?它能夠選擇值的范圍。真實圖片很少包含準確的顏色值。任何被壓縮為 JPEG 的東西肯定會包含一點壓縮噪音。
您的圖片看起來您實際上可能對地圖上的一種峰/脊感興趣......如果它不是均勻的綠色(例如,高度變化),您將需要一些邏輯來處理漸變。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/497787.html
