Pythonの画像ライブラリであるpillow(PIL)パッケージを使って、画像に矩形(長方形)を描画する方法を紹介します。
この記事でできること
画像を読み込み、矩形を描画した画像を出力し、画像ファイルとして保存します。「矩形」とは画像処理やコンピュータビジョン分野の人が良く使う言葉で、要するに長方形です。
ここでは、次の画像を例にします。この画像は、いらすとやの「人脈・コネがない人のイラスト」です。
この記事では、上の画像に対して人の顔の部分を赤い矩形(長方形)で囲った画像を作成します。
画像内のどこが人の顔なのかの座標は手入力です。顔を自動で検出する方法についてはこの記事の内容に含みません。
pillowパッケージのインストール
まずは準備として、pythonのpillowパッケージをインストール。
pip install pillow
Anacondaを使用している場合はpipではなくcondaでインストールします。
conda install pillow
微妙に注意点ですが、pythonでpillowパッケージを使用するには、”PIL”をfromとしてpillowの各種モジュールをimportすることになります。pillowは開発が停止したPIL(Python Image Library)からフォークされました。そのため、PILからimportするのです。
今回importするモジュールは、後述するように、”Image”と”ImageDraw”です。
from PIL import Image
from PIL import ImageDraw
矩形を画像に描画し保存
まずは、この節で説明するサンプルコード全体を貼り付け。
from PIL import Image
img = Image.open("img_file.png") # 画像ファイル読み込み
from PIL import ImageDraw
draw = ImageDraw.Draw(img) # 矩形の描画の準備
rectcolor = (255, 0, 0) # 矩形の色(RGB)。red
linewidth = 4 # 線の太さ
draw.rectangle([(161, 50), (260, 162)], \
outline=rectcolor, width=linewidth) # 矩形の描画
img.save("img_file_out.png") # ファイルの保存
このソースコードを順番に説明していきます。最初は画像の読み込みです。Image.openというメソッドで画像ファイル名を指定し、imgという変数に画像を読み込みます。
from PIL import Image
img = Image.open("img_file.png") # 画像ファイル読み込み
次に、矩形描画の準備をします。見慣れないメソッドは、そういうもんなんだと思って流して頂ければ問題ないです。
from PIL import ImageDraw
draw = ImageDraw.Draw(img) # 矩形の描画の準備
準備が出来たので、矩形を描画し、新規の画像ファイルとして保存します。矩形の色や、矩形の線の太さを指定した後、矩形の座標を指定して描画した後に画像ファイルとして保存します。
rectcolor = (255, 0, 0) # 矩形の色(RGB)。red
linewidth = 4 # 線の太さ
draw.rectangle([(161, 50), (260, 162)], outline=rectcolor, width=linewidth) # 矩形の描画
img.save("img_file_out.png") # ファイルの保存
保存されたファイル”img_file_out.png”は次のようになります。
draw.rectangleの引数”[(161, 50), (260, 162)]”は矩形の座標です。
座標の考え方は下図のようになります。一つ目のタプル(161, 50)は矩形の左上のxy座標を表し、2つ目のタプル(260, 162)は矩形の右下のxy座標を表します。xy座標の考え方は中学生以来習ってきたのとは少し違って、画像の左上隅の座標を(0, 0)として、右方向がx座標のプラス方向、下方向がy方向のプラス方向となっています。画像処理ではよく使われる座標系です。
画像に複数の矩形を描画
これまでに説明したことを使って複数の矩形を描画します。複数の矩形座標を指定して、draw.rectangle()を何度も実行するだけです。
from PIL import Image
def draw_rect_simple(img, rects):
from PIL import ImageDraw
rectcolor = (255, 0, 0) # red
linewidth = 4 # 線の太さ
draw = ImageDraw.Draw(img) # 準備
for i, rect in enumerate(rects):
rect_tup = [(rect[0], rect[1]), (rect[2], rect[3])]
draw.rectangle(rect_tup, outline=rectcolor, width=linewidth)
return img
if __name__ == '__main__':
img = Image.open("img_file.png") # 画像読み込み
rects = [[161,50,260,161],
[318,135,418,243],
[46,267,142,373],
[181,244,275,352],
[340,351,440,455],
[500,257,598,371],
[648,33,742,146]] # 矩形の座標リスト
img = draw_rect_simple(img, rects) # 矩形の描画
img.save("img_file_out.png") # 画像のファイル出力
変数rectsに複数の矩形座標のリストを指定し、関数draw_rect_simple()で複数の矩形を描画しています。forループ内で関数draw_rect_simple()が実行される度に、矩形が上書きの形で描画されます。
おわりに
今回は画像への矩形の描画方法を記載しました。次の記事では、クラス名等のテキストを矩形の上に付随して表示する方法を紹介していますので、併せて参考にして頂けると。
矩形の描画は物体検出AI(object detection)の検出結果を表示する際によく使います。今後はSSDやYOLOなどの物体検出AIの関連記事を書いていく予定です。
コメント