デジカメで撮った写真をデータとして取り込んだり、加工したり、出力したいことがあると思います。
今回は、画像のRGB値をcsvファイルに出力したり、その逆でcsvから画像にする方法をご紹介します。
やること1
・画像を読み込んでRGB値に変換する
・csvに出力する
やること2
・csvを読み込んでRGB値のリストにする
・画像にして出力する
それでは順番に見ていきましょう!
順番にみていく
やること1_画像を読み込んでRGB値に変換する
サンプル画像はこちらを使いました。
![](https://atosuko.com/wp-content/uploads/2023/04/target_jpg_mini-1024x682.jpg)
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)
サンプル画像はこちらのサイトからお借りしました。フリーの画像素材を提供してくださっています。超優良サイトです。
![](https://www.pakutaso.com/shared/img/site/ogp.jpg)
やること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行列として出力しています。
![](https://atosuko.com/wp-content/uploads/2023/04/1.jpg)
![](https://atosuko.com/wp-content/uploads/2023/04/2.jpg)
やること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バッチファイルにして実行すると次のようになります。
![](https://atosuko.com/wp-content/uploads/2023/04/3.jpg)
![](https://atosuko.com/wp-content/uploads/2023/04/4-1024x555.jpg)
それぞれ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")
以上となります。
少しでもお役に立てれば幸いです。
それでは、読んで頂きありがとうございました!