【Python】画像からRGB値を取得してcsvにする方法、数値化したcsvから画像化する方法

デジカメで撮った写真をデータとして取り込んだり、加工したり、出力したいことがあると思います。
今回は、画像のRGB値をcsvファイルに出力したり、その逆でcsvから画像にする方法をご紹介します。

やること1
・画像を読み込んでRGB値に変換する
・csvに出力する

やること2
・csvを読み込んでRGB値のリストにする
・画像にして出力する

それでは順番に見ていきましょう!

目次

順番にみていく

やること1_画像を読み込んでRGB値に変換する

サンプル画像はこちらを使いました。

pillowを利用して画像を読み込みます。(target.jpg)

from PIL import Image

# 画像ファイルを読み込む
img = Image.open('target.jpg')
# 画像のピクセルデータを取得
pixels = img.load()
# 画像の幅と高さを取得
width, height = img.size


最終的なcsvのイメージは画像どおりの行列です。
width×height行列にします。

from PIL import Image

# 画像ファイルを読み込む
img = Image.open('target.jpg')
# 画像のピクセルデータを取得
pixels = img.load()
# 画像の幅と高さを取得
width, height = img.size

# RGB値を列ごと
r_values = []
g_values = []
b_values = []

# 画像の各ピクセルのRGB値をリストに格納
for y in range(height):
    tmp_r = []
    tmp_g = []
    tmp_b = []
    for x in range(width):
        r, g, b = pixels[x, y]
        tmp_r.append(r)
        tmp_g.append(g)
        tmp_b.append(b)
        #rgb_values.append((r, g, b))
    r_values.append(tmp_r)
    g_values.append(tmp_g)
    b_values.append(tmp_b)

サンプル画像はこちらのサイトからお借りしました。フリーの画像素材を提供してくださっています。超優良サイトです。

やること1_csvに出力する

取り込んだRGB値のリストを、csvファイルとして出力します。
csvモジュールを利用しました。

import csv

# CSVファイルにRGB値を書き込む
with open('image_r.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    for item in r_values:
        writer.writerow(item)
with open('image_g.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    for item in g_values:
        writer.writerow(item)
with open('image_b.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    for item in b_values:
        writer.writerow(item)

これらを実行した結果がこちらです。
「image_r.csv」、「image_g.csv」、「image_b.csv」に出力されます。
たとえば、「image_r.csv」にはRGB値256階調のうち、R値だけをwidth×height行列として出力しています。

やること2_csvを読み込んでRGB値のリストにする

次に逆手順を想定して、csvを読み込んでRGB値のリストに取り込みたいと思います。

import csv

# CSVファイルからRGB値を読み込む
r_values = []
g_values = []
b_values = []
with open('image_r.csv', newline='') as csvfile:
    reader = csv.reader(csvfile)
    # 行数を数える
    height = sum(1 for row in reader)
    # CSVファイルを開き直す
    csvfile.seek(0)
    # 列数を数える
    width = len(next(reader))
    print(f"width = {width}, height = {height}")
    # 値を取り出す, 一次元で格納([x, y]→ [y * width + x] )
    for row in reader:
        for item in row:
            r_values.append(int(item))
with open('image_g.csv', newline='') as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        for item in row:
            g_values.append(int(item))
with open('image_b.csv', newline='') as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        for item in row:
            b_values.append(int(item))

csvモジュールを利用しました。
csvはwidth×height行列でした。
取り込んだリストは一次元のリストです。
[y * width + x]番目を取り出すと所定のx,y座標のデータを取り出せる配置になります。

やること2_画像にして出力する

pillowモジュールを利用しました。
ピクセルごとにタプル形式でRGB値を指定します。次のようになります。

from PIL import Image
new_pixels[x, y] = (R, G, B)

これを、画像のwidht×height分だけ実行します。
画像データが作成されます。

from PIL import Image

# RGB値を元に画像を作成する
new_img = Image.new('RGB', (width, height))
new_pixels = new_img.load()
for y in range(height):
    for x in range(width):
        max = len(r_values)
        if(y * width + x < max):
            new_pixels[x, y] = (r_values[y * width + x], g_values[y * width + x], b_values[y * width + x])#タプル表記(R, G, B)

最終的に画像にして出力します。

from PIL import Image

# 画像を表示する
new_img.show()
new_img.save("target_after.jpg")


windowsバッチファイルにして実行すると次のようになります。

それぞれRGB値のcsv(1600×1066行)のデータを読み込み、画像にすることができました。

サンプルコード1_画像からcsvにする

やること1で紹介したコードを合体したものがこちらです。
次をします。
・画像を読み込んでRGB値に変換する
・csvに出力する

# 画像ファイルを読み込む
img = Image.open('target.jpg')
# 画像のピクセルデータを取得
pixels = img.load()
# 画像の幅と高さを取得
width, height = img.size

# RGB値を格納するリストを初期化
#rgb_values = []
# RGB値を列ごと
r_values = []
g_values = []
b_values = []

# 画像の各ピクセルのRGB値をリストに格納
for y in range(height):
    tmp_r = []
    tmp_g = []
    tmp_b = []
    for x in range(width):
        r, g, b = pixels[x, y]
        tmp_r.append(r)
        tmp_g.append(g)
        tmp_b.append(b)
        #rgb_values.append((r, g, b))
    r_values.append(tmp_r)
    g_values.append(tmp_g)
    b_values.append(tmp_b)
# CSVファイルにRGB値を書き込む
with open('image_r.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    for item in r_values:
        writer.writerow(item)
with open('image_g.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    for item in g_values:
        writer.writerow(item)
with open('image_b.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    for item in b_values:
        writer.writerow(item)

サンプルコード2_csvから画像にする

やること2で紹介したコードを合体したものがこちらです。
次をします。
・csvを読み込んでRGB値のリストにする
・画像にして出力する

# CSVファイルからRGB値を読み込む
r_values = []
g_values = []
b_values = []
with open('image_r.csv', newline='') as csvfile:
    reader = csv.reader(csvfile)
    # 行数を数える
    height = sum(1 for row in reader)
    # CSVファイルを開き直す
    csvfile.seek(0)
    # 列数を数える
    width = len(next(reader))
    print(f"width = {width}, height = {height}")
    # 値を取り出す, 一次元で格納([x, y]→ [y * width + x] )
    for row in reader:
        for item in row:
            r_values.append(int(item))
with open('image_g.csv', newline='') as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        for item in row:
            g_values.append(int(item))
with open('image_b.csv', newline='') as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        for item in row:
            b_values.append(int(item))

# RGB値を元に画像を作成する
new_img = Image.new('RGB', (width, height))
new_pixels = new_img.load()
for y in range(height):
    for x in range(width):
        max = len(r_values)
        if(y * width + x < max):
            new_pixels[x, y] = (r_values[y * width + x], g_values[y * width + x], b_values[y * width + x])#タプル表記(R, G, B)

# 画像を表示する
new_img.show()
new_img.save("target_after.jpg")

以上となります。
少しでもお役に立てれば幸いです。
それでは、読んで頂きありがとうございました!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次