マシュマロンのブログ

おはようございます。こんにちは。こんばんは。

【追記アリ】PILで画像処理~ネガポジ反転・ポスタリゼーション(posterization,8階調化)~

以前pythonでネガポジ反転、ポスタリゼーションを行うコードを書いたのでご紹介。
必要に応じてpip install Pillow、またはpip install numpy!!
解説とかもないです。

[2/14追記]このコードで一定以上の大きさの画像を使うとなぜか点対称な感じになります。
本当に原因がわからないので有識者の方、いらっしゃいましたら教えていただけると幸いです。


※ここでは画像がデータとしてどのように扱われているかについて基本的なことを学んだ上で(画素値とかRGBとか)、学習のために基本的な関数のみを使用しています。PILに画像をネガポジ反転させるための関数が存在するのかもしれませんが、今回は扱いません。


※そして1つ1つのピクセルに対して処理を行うので出力までに時間がかかりますが、それは仕様です。しょうがないね。

ネガポジ反転 <アプローチ1>

ワンクッション置いてリスト内包表記を使っているので、なんか賢そうな書き方です。

from PIL import Image
import numpy as np

img = Image.open('XXX.jpg') #対象のファイル名を入れる
width, height = img.size

img2 = Image.new('RGB', (width, height))

img_pixels = np.array([[img.getpixel((x,y)) for x in range(width)] for y in range(height)]) #リスト内包表記

reverse_color_pixels = 255 - img_pixels

for y in range(height):
    for x in range(width):
        r,g,b = reverse_color_pixels[y][x]
        img2.putpixel((x,y), (r,g,b))

img2.show()
img2.save('hanten.jpg') #お好きなファイル名で

ネガポジ反転 <アプローチ2>

多分一番単純でダイレクトな方法です(主観)。

from PIL import Image
import numpy as np

img = Image.open('XXX.jpg') #対象のファイル名を入れる
width, height = img.size

img2 = Image.new('RGB', (width, height))

for y in range(height):
    for x in range(width):
        r, g, b = img.getpixel((x, y))
        img2.putpixel((x,y), (255-r, 255-g, 255-b))

img2.show()
img2.save('hanten.jpg') 

ポスタリゼーション

from PIL import Image
import numpy as np

img = Image.open('XXX.jpg')#ファイル名
width, height = img.size
img2 = Image.new('RGB', (width, height))
img_pixels = np.array([[img.getpixel((x,y)) for x in range(width)] for y in range(height)])

for y in range(height):
    for x in range(width):
        for i in range(3):
            if(img_pixels[y][x][i] > 256 - 32):
                img_pixels[y][x][i] = 255
            elif(img_pixels[y][x][i] > 256 - 32*2 and img_pixels[y][x][i] <= 256 - 32 ):
                img_pixels[y][x][i] = 219
            elif(img_pixels[y][x][i] > 256-32*3 and img_pixels[y][x][i] <= 256-32*2 ):
                img_pixels[y][x][i] = 183
            elif(img_pixels[y][x][i] > 256-32*4 and img_pixels[y][x][i] <= 256-32*3):
                img_pixels[y][x][i] = 146
            elif(img_pixels[y][x][i] > 256-32*5 and img_pixels[y][x][i] <= 256-32*4):
                img_pixels[y][x][i] = 110
            elif(img_pixels[y][x][i] > 256-32*6 and img_pixels[y][x][i] <= 256-32*5):
                img_pixels[y][x][i] = 73
            elif(img_pixels[y][x][i] > 256-32*7 and img_pixels[y][x][i] <= 256-32*6):
                img_pixels[y][x][i] = 37
            else:
                img_pixels[y][x][i] = 0
        img2.putpixel((x,y), (img_pixels[y][x][0],img_pixels[y][x][1],img_pixels[y][x][2]))

img2.show()
img2.save('kaityo.jpg')#お好みで!