こんにちは、タナカです。
この記事では、labelmeというアノテーションツールで作ったjsonファイルから画像を生成する方法を紹介します。
labelmeというオープンソースのアノテーションツールを使うと下記のようなjsonファイルを作ることができます。図のようにこのjsonファイルはbase64形式の画像データやアノテーションをした際に作成した座標情報などを持っています。
今回はこのjsonファイルから元画像とマスク画像を生成する方法を紹介します。
labelmeで作られたjsonファイルから画像を生成する方法
1. labelmeとは
labelmeはMITによって開発されたアノテーションツールです。オープンソースであり、誰でも無料で利用することができます。セマンティックセグメンテーションやインスタンスセグメンテーションのデータをセットを作成するために使用します。
labelmeの使い方についてはアノテーションツールlabelmeの使い方で紹介していますのでご参考ください。
2. ライブラリの紹介
今回のコードで使う外部ライブラリを紹介します。
matplotlib
numpy
labelme
pillow
外部ライブラリをインストールしていない場合は、pip等でインストールしてください。
3. jsonファイルから画像を生成する方法
今回生成する画像は2種類あります。
- 元画像
- マスク画像
jsonファイルは辞書型で情報を保持しており、shapesなどのkeyをもとにして、情報を取り出すことができます。
3-1. 元画像を生成
jsonファイルの中の「imageData」が画像データのことでして、この情報をもとに元画像を生成することができます。
実際に元画像を生成するコードがこちらになります。
# 標準ライブラリ
import json
import base64
import io
# 外部ライブラリ
from labelme import utils
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image, ImageDraw
# jsonデータの読み込み
json_file = open('apple-1834639_640.json')
json_data = json.load(json_file)
# imageDataをkeyにしてデータを取り出す
img_b64 = json_data['imageData']
# labelmeのutils関数を使ってbase64形式をPIL型に変換する
img_data = base64.b64decode(img_b64)
img_pil = utils.img_data_to_pil(img_data)
# 画像の可視化
plt.imshow(img_pil)
plt.show()
このコードで生成された画像がこちらです。
3-2. マスク画像を生成
先ほど生成した元画像とshapes情報をもとにマスク画像を生成します。
実際のコードがこちらになります。
# アノテーションのときにポチポチした頂点座標を取得
points = json_data['shapes'][0]['points'] # 今回は画像中に1つだけ物体があることを想定
# list -> tuple
points = [tuple(point) for point in points] # or list(map(tuple, points))
# マスク画像を生成
w, h = img_pil.size
mask = Image.new('L', (w, h))
draw = ImageDraw.Draw(mask)
draw.polygon(points, fill = 1)
# 画像の可視化
plt.imshow(mask)
plt.show()
注意点は取り出した座標情報がlistで保持されているため、tupleに変換する必要があります。なぜなら、draw.polygonのところでlistのままだと下記のようなエラーが発生し、tupleに変換してくれと怒られるからです。
SystemError: new style getargs format but argument is not a tuple
このコードで生成された画像がこちらです。
まとめ
今回はlabelmeで作成したjsonファイルから画像を生成する方法を解説しました。
この元画像とマスク画像をデータセットとして使うことでセグメンテーションの学習を行うことができます。