2010年2月28日日曜日

PythonのImageモジュールを使う

この間Python Imaging Libraryを使ったが、画像データをRGBのリストにする方法を調べるだけでけっこう時間がかかってしまったのでメモっておく。利用しているPythonは2.5.2。

プログラムの内容は自分でもよくわかってないけど、画像をNxNに分割して、分割した領域の色の平均を取ってるのだと思われるが、正しいんだろうか。

HSVとかXYZとか色空間ってなんなんだろう。ライブラリ+人に言われたアルゴリズムで適当に変換したけど。

本題のImageモジュールの使い方としては、

  • Image.open(path)でファイルを開きオブジェクトを作る
  • オブジェクトのサイズ(obj.size)は(width, height)
  • オブジェクトのモード(obj.mode)はconvertメソッドで変更できる
  • getdataメソッドでピクセルのリストを取得できる。この状態ではPILで使うデータ型なので、一般的なリストが欲しければlist(obj.getdata())とする

という流れだった。 getdataメソッドくらいしか利用していないけど、他にもいろいろ出来るようだ。

import Image;
import sys;
import math;
import colorsys;

nsplit = 10

def HSVtoXYZ(h,s,v):
return s*v*math.cos(h), s*v*math.sin(h), v

def RGBtoXYZ(r,g,b):
return apply(HSVtoXYZ, colorsys.rgb_to_hsv(r/255.0,g/255.0,b/255.0))

def ColorBlockAverage(seq, x, y, xSize, ySize, width):
r,g,b = 0,0,0
for ytmp in range(0,ySize):
for xtmp in range(0,xSize):
rgb = seq[(y+ytmp)*width + (x+xtmp)]
r += rgb[0]
g += rgb[1]
b += rgb[2]
return RGBtoXYZ(r/(xSize*ySize), g/(xSize*ySize), b/(xSize*ySize))

def ColorAverages(seq, n, width, height):
xSize = width/n
ySize = height/n
result = []
for y in range(0,n):
for x in range(0,n):
result.append(ColorBlockAverage(seq,x*xSize,y*ySize,xSize,ySize,width))
return result

argvs = sys.argv
argc = len(argvs)
if (argc < 2):
print "Required 1 argument"
quit()

try:
img = Image.open(argvs[1])
# print img.format, img.size, img.mode

width, height = img.size

if img.mode == "RGB" :
# print "RGB image"
""
else:
# print "Image file is not RGB mode. Convert to RGB mode"
img.convert("RGB")

# R,G,B = 0,1,2
seq = list(img.getdata())
result = ColorAverages(seq, nsplit, width, height)

for xyz in result:
print xyz[0],xyz[1],xyz[2],
print ""

except IOError:
print "IOError"

ひどいコードを書いている自身はあるが、Pythonはろくに触ったことないし・・・という言い訳で逃げることにする。

ライブラリのパワーでなんとかしてもらえるのがPythonの素晴らしいところですね。

0 件のコメント:

コメントを投稿