画像に使われている色(RGB)を取得する
作ったもの
タイトルの通り,入力画像からその画像に使われているRGBを取得するプログラムを作成.ただし,入力画像は 100×100 にリサイズして扱う.
以下は入力画像とリサイズ後の画像
また,取得したRGBについて,各RGBが何ピクセル使われているかをカウントし,それらを降順で出力.
以下は出力結果の例
その後,使用頻度の多いRGBから画像に並べ,color_map.png
として出力.
こんな感じ
ソースコード
from PIL import Image import math def resize_img (filename, size_tuple): # 既存ファイルを readモードで読み込み img = Image.open(filename, 'r') # リサイズ。サイズは幅と高さをtupleで指定 return img.resize(size_tuple) def count_pixel_colors (img): # 集計結果を格納する辞書配列 img_pixel_colors = {} # 指定された座標のピクセルの RGB を取得し,そのRGBのカウンターをインクリメント def increment_color_counter (x, y): # (x,y)座標のピクセルの rgb を取得 r,g,b = img.getpixel((x,y)) # rgbを辞書配列のキーに使うために文字列化 (ex. 238-211-114) rgb = '-'.join([str(n) for n in [r,g,b]]) # 取得した rgb が key になければ 値0 で追加 img_pixel_colors.setdefault(rgb, 0) # 取得した rgb のカウンターをインクリメント img_pixel_colors[rgb] += 1 # 画像の幅と高さを取得 width, height = img.size # 画像に使われている色の数を集計し,辞書配列で img_pixel_colors に格納 [increment_color_counter(x, y) for x in range(width) for y in range(height)] return img_pixel_colors # ピクセル数の多い色順にピクセルを並べた画像を作成 def make_color_map (img_size, rgb_set, filename): img = Image.new('RGB', img_size) x=0 y=0 for rgb, count in sorted(rgb_set.items(), key=lambda x: -x[1]): while count > 0: rgb_tuple = tuple([int(v) for v in rgb.split('-')]) img.putpixel((x, y), rgb_tuple) x+=1 if x == img_size[0]: x=0 y+=1 count-=1 img.save(filename) def main (img_name): # 出力画像のサイズ outimg_size = (100, 100) # 画像をリサイズすることでモザイク画像を取得 mosaic_img = resize_img('pikachu.png', outimg_size) # 取得したモザイク画像を保存 mosaic_img.save('mosaic_img.png', 'PNG', quality=100, optimize=True) # RGBに変換 rgb_img = mosaic_img.convert('RGB') # 使われている色の種類を取得し,それらのピクセル数をカウント img_pixel_colors = count_pixel_colors(rgb_img) for k, v in sorted(img_pixel_colors.items(), key=lambda x: -x[1]): print(k, v) # ピクセル数の多い色順にピクセルを並べた画像を作成 make_color_map(outimg_size, img_pixel_colors, 'color_map.png') if __name__ == '__main__': main('pikachu.png')
今後の展開
リサイズ処理で生成する画像について,使用するRGBを制限したい. 指定のRGBで画像を表現できるようにしたい. 例えば,マイクラのブロックの色だけで表現するとか.