PILのImage.transformの使い方 (EXTENT)
先日、pythonで画像を変形させてみたいと思った。まあ、バッチで処理したかったので。
調べてみたらImage.transformという関数があるのを知るが、 使ってみようとしたところ、どんなパラメータを指定したらいいのかわからず途方にくれる。(泣)
ネットで調べたりして、なんとか使えるレベルまでになったので Image.transform の使い方を整理してみた。
とりあえず、今回は概要とEXTENTの使い方。
Image.transformの概要
reference
Image Module — Pillow (PIL Fork) 3.1.1 documentation
自分の環境では、Python2.7.6でPillowが2.3.0だが、ここで問題ないと思われるので。
Pillowに限らず、Python周りのバージョンとドキュメントの関連性の知識が足りずこれでいいのか判断できない。あとでPythonのドキュメントを見ておかないと。
変形方法の種類 (method)
methodというパラメータで指定するが、以下の5つがある。
PIL.Image.EXTENT
矩形を切り取って拡大。PIL.Image.AFFINE
AFFINE変換。移動、拡大、縮小、回転、反転ができる。PIL.Image.PERSPECTIVE
遠近感のある画像に変換。PIL.Image.QUAD
ランベルトの四角形っていうやつの変形と思われる。 端がよれて"くる"ってなってる紙とかの写真を四角形に補正するために使われるのだと思う。PIL.Image.MESH
QUADを連続して行うためのもの。
変形のパラメータ (data)
dataで変形のパラメータを指定する。
methodの変形方法に合わせて指定する必要がある。
ここがpillowのリファレンスに記載がなく困った。
ネットで検索したところ以下がヒット。これを参考にした。
描画時の補間の方法。filter。 (resample)
変形するときに描画する点を埋め合わせないといけないケースがあるが、
その方法を指定する。
以下の3つがある。
PIL.Image.NEAREST
デフォルト。となりの点を見て補間。2値画像や"P"モードの場合、これしか指定できない。 "P"モードとはパレットを使うモードらしいが、よくわからず。PIL.Image.BILINEAR
2x2で見て補間。PIL.Image.BICUBIC
4x4で見て補間。
Image.EXTENT の変形
Image.EXTENTのdata指定方法。
4 tupples (x0, y0, x1, y1)
Image.EXTENTのサンプル
# -*- coding: utf-8 -*- from __future__ import print_function from PIL import Image from PIL import ImageDraw import numpy as np import argparse parser = argparse.ArgumentParser(description="Image.transformのサンプル") parser.add_argument("--output","-o", required=True, type=str , help="出力ファイル") args = parser.parse_args() # 変換元の画像をロード def load_image() : #im = Image.open("xxxx.png") # サンプルとして、41x33の画像を作成。グレースケール256階調 # 8ドットごとに格子を描画 im = Image.new("L", (41, 33), color=0) draw = ImageDraw.Draw(im) for i in range(6) : draw.line([(i*8, 0), (i*8, 32)], fill=255, width=1) for i in range(5) : draw.line([(0, i*8), (40, i*8)], fill=255, width=1) # 四角を左上の格子の中に描画 draw.rectangle([3, 3, 6, 6], fill=255) del draw return im im = load_image() # # Image.EXTENT # # data : 4 tupples (x0, y0, x1, y1) # # dataで矩形を指定して切り取る。 # subnm = "nearest" data = (0, 5, 20, 20) im2 = im.transform(im.size, Image.EXTENT, data, Image.NEAREST) filenm = args.output + "-" + subnm + "-" + "_".join(map(str, data)) + ".png" print("filenm:", filenm) im2.save(filenm) subnm = "bilinear" data = (0, 5, 20, 20) im2 = im.transform(im.size, Image.EXTENT, data, Image.BILINEAR) filenm = args.output + "-" + subnm + "-" + "_".join(map(str, data)) + ".png" print("filenm:", filenm) im2.save(filenm) subnm = "bicubic" data = (0, 5, 20, 20) im2 = im.transform(im.size, Image.EXTENT, data, Image.BICUBIC) filenm = args.output + "-" + subnm + "-" + "_".join(map(str, data)) + ".png" print("filenm:", filenm) im2.save(filenm)
変換元の画像
※ふちが白枠。
変換後の画像
resample=Image.NEAREST
resample=Image.BILINEAR
resample=Image.BICUBIC
コメント
EXTENTはそのままなので簡単。
関連
PILのImage.transformの使い方 (AFFINE) - umejanのブログ
PILのImage.transformの使い方 (QUAD, MESH) - umejanのブログ
PILのImage.transformの使い方 (PERSPECTIVE) - umejanのブログ