82211


### 前提・実現したいこと

初めて質問します。初心者なので大変初歩的な質問ですがよろしくお願いいたします。Google
Colabで画像処理を行っています。そこで画像の色を変更するプログラムを作成しています。そこで画素値（0,255,0）といった他の色が混ざっていない単色であれば色変更が可能なのですが、私が扱っている画像は例えばBGRのBが100～105といった1つの値だけでは表現できない色となっております。画像中の色は黒線で区切られており、その区切りごとに色を変更したいと考えています。イメージ的には山の標高（例えば100ｍごと）ごとに色が区切られているものを、こちらが任意でその色を並び替えるというイメージです。私としては単色では無い画素値を、例えばBGR形式で（100～105,0,150)という様な形で表現して、その画素値を変更したいと考えております。

### 発生している問題・エラーメッセージ

先述の様に画素値（0,255,0）といった他の色が混ざっていない単色であれば色変更が可能なのですが、私が扱っている画像は例えばBGRのBが100～105といった1つの値だけでは表現できない色となっております。なので画像の色を変更する事が出来ません。エラーメッセージは次の通りです。エラーメッセージが出ている所は後述するソースコードの7行目です。

[code]

    TypeError: 'NoneType' object is not subscriptable
    
[/code]

### 該当のソースコード

[code]

    import sys,cv2
    import numpy as np
    
    args = sys.argv
    img = cv2.imread("sample.jpg")
    
    cond_p = (145　<= img[..., 0] <= 150) & (145 <= img[..., 1] <= 150) & (145 <= img[..., 2] <= 150)
    cond_f = np.logical_not(cond_p)
    img[cond_p] = [0, 255, 0]
    img[cond_f] = [255, 0, 0]
    
    cv2.imwrite("a.jpg", img)
    
[/code]

### 試したこと

上記のソースコードにおいて7行目で変更したい画素値を指定します。上の例であれば(145~150,145~150,145~150)の色となっております。インターネットで調査した結果、「Python
以上
以下」と調べて3.のソースコードの様に＜＝を使って表現すると書いていましたが、エラーメッセージが出て上手くいきませんでした。ダメもとで145~155、145～155、145-155の3通りを試しました。しかし2つ目の例では全角が含まれるのでエラーになり、その他の例でも上手くいきませんでした。  
*追加情報  
⓵print(im.format, im.size, im.mode)  
を実行すると  
「JPEG (256, 256) L」と出力されます。  
⓶print(img.shape)  
を実行するとエラーメッセージが次の様に出ます。  
「'NoneType' object has no attribute 'shape'」  
尚画像は存在する筈なのですが・・・

### 補足情報（FW/ツールのバージョンなど）

言語：Python  
環境：Windows10  
ブラウザ：Google Chrome（Google Colaboratory)  
＊ノートパソコンです。全て最新バージョンです。プログラミング中はcolab以外のタブ、アプリは開いていません。


CC BY-SA 4.0
2021-09-03T09:02:35.343
82209
2021-09-06T22:37:49.473
2021-09-06T22:37:49.473
48040
48040
question
python google-colaboratory 画像処理
単色では無い画素値の範囲指定が出来ない


処理の内容が合ってるかどうかわからないけど,  
とりあえずエラー出ないようにするには …

まず, NumPyでは(たいてい) N-d Array 単位で演算処理を行うので, `(145 <= img[..., 0] <= 150)`
という記述(複数の比較の連結) は受け付けないようです。

質問の条件をそのまま置き換えた形

[code]

    cond_p = ((145 <= img[..., 0]) & (img[..., 0] <= 150)
            & (145 <= img[..., 1]) & (img[..., 1] <= 150)
            & (145 <= img[..., 2]) & (img[..., 2] <= 150))
    
[/code]

(追記)  
RGB (RGBAではなく) 3つの要素で, 実際に(質問のように)値の範囲がすべて同じなら, 次のようにも可能(なはず)

[code]

    cond_p = np.all((145 <= img) & (img <= 150), axis=-1)
    
[/code]

あと注意点として, 何の(何系の)画像処理か不明だけど,  
厳密に値の範囲指定する場合, JPEG形式は向いていないかも？  
(不可逆圧縮であり, また, 読み込むライブラリーによっては値が異なることも)

* * *

### コメント受けての(質問での)エラーの件確認

以下を colabなどで実行すると何が出ますか？  
また, `img = cv2.imread(〜)` 後の, `img.shape` を表示した場合何が出ますか？  
… 以上を, 質問に追記してみて下さい

[code]

    from PIL import Image
    im = Image.open('sample.jpg')
    print(im.format, im.size, im.mode)
    
[/code]


CC BY-SA 4.0
2021-09-03T10:08:44.267
82211
2021-09-06T05:04:30.430
2021-09-06T05:04:30.430
43025
43025
82209
answer