72594


### 問題点

あるRGB画像を読み込み、RGBの値(輝度値)を全て50あげて保存するプログラムを作成しているのですが、  
できあがった画像は一部のピクセルにおいて[0,0,0]になってしまい、結果的に2枚目の画像のような  
虫食いになってしまいます。

各ピクセルのRGB値を出力してみるとやはり以下のとおりいくつかのピクセルのRGB値が[0,0,0]になっていました。どうすれば解決できるでしょうか。

### 環境

Python 3.8.5  
Windows 10

### 結果

**変換前:**

[![画像の説明をここに入力](https://i.stack.imgur.com/rId1m.jpg)](https://i.stack.imgur.com/rId1m.jpg)

**変換後:**

[![画像の説明をここに入力](https://i.stack.imgur.com/z4Nm2.jpg)](https://i.stack.imgur.com/z4Nm2.jpg)

### 出力結果(一部)

[code]

    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [0 0 0]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    [50 50 50]
    
[/code]

### ソースコード

[code]

    def main():
    
        width = 416
        height = 416
        num = int(1)
        os.chdir("d:\\study_data\\get_image\\photo\\thermal_face-PascalVOC-export\\JPEGImages")
    
        while True:
    
            filename = 'img%20('+format(num)+').jpg'
            if os.path.exists(filename):
                image = cv2.imread(filename)
            else:
                print("\nEnd")
                break
    
            for y in range(0,height):
                for x in range(0,width):
    
                    image[y,x,0] = image[y,x,0] + 50
                    if image[y,x,0] > 255:
                        image[y,x,0] = 255
    
                    image[y,x,1] = image[y,x,1] + 50
                    if image[y,x,1] > 255:
                        image[y,x,1] = 255
    
                    image[y,x,2] = image[y,x,2] + 50
                    if image[y,x,2] > 255:
                        image[y,x,2] = 255
    
                    #print(image[x,y])
    
            cv2.imwrite('d:/study_data/get_image/photo/thermal_face-PascalVOC-export/Copy/img%20('+format(num)+').jpg', image)
    
            num += 1
            print("\rNo. %d" %num, end='')
    
    if __name__ == '__main__':
        main()
    
    
[/code]


CC BY-SA 4.0
2020-12-11T10:47:22.813
72593
2020-12-15T09:15:07.440
2020-12-11T11:47:27.800
3060
41740
question
python 画像
画像の画素値をあげようとしたら一部が上手く変換されない


`cv2.imread`で読み込まれた画像データは、8bit幅符号なし整数型(`uint8`)として保持されています。実際に、下記コードで確認してみてください。

[code]

    print(image.dtype)  # uint8
    
[/code]

このデータに対して加算を行うと、結果が値`255`を超える場合には`256`で割った余りとなってしまいます。例：`230 +
50`は`280`ではなく`24`になる。

簡単に解決するなら、中間計算をより広いbit幅を持つ整数型（`uint16`）で行えば解決します。

[code]

    image = image.astype('uint16')
    # image[x,y,c]の計算...
    
[/code]

* * *

質問趣旨からは少し外れますが、Python＋OpenCV＋Numpyによる画像処理では、ピクセル単位処理は非常に重い（＝速度が遅い）処理です。なるべくNumpy関数を利用した方がよいです。

2次元ループ`x`,`y`×ピクセル単位計算の代わりに、下記のように記述すると同じ処理を高効率に実現できます。

[code]

    image = image.astype('int16')
    image = np.clip(image + 50, 0, 255)
    
[/code]


CC BY-SA 4.0
2020-12-11T11:45:10.693
72594
2020-12-11T11:45:10.693
49
72593
answer


yohjp さんの回答により無事問題を解決できました、ありがとうございます。

追加情報として、今回の場合は全ての輝度値を +50 にするということで、取りうる値の範囲は 50 ~ 305 となるため uint16 型を用いました。

逆に全ての輝度値を -50 にする場合、その範囲は -50 ~ 205 となり、負の値が範囲に入ってきます。

この場合は uint16 型だと正の値にしか対応していないので、int16 型に変更すれば負の値にも対応できます。

自分への戒めとして残しておきますね。


CC BY-SA 4.0
2020-12-15T09:15:07.440
72672
2020-12-15T09:15:07.440
41740
72593
answer