はじめに
"本(book)"の物体検出しようと思った際、データセットを自分で作るのが面倒だと思い、既存のデータセットを使おうと思って調べました。
結局自分で作ったほうが綺麗なデータで学習できるかなと思い、そうしようと思ってますが、折角調べたのでいつか使うときのために残しておきます。
実行はjupyter notebookです。
目的:データセット"Open Images Dataset"から特定のクラスの画像とアノテーションデータを取り出す
本編
公式ページにもデータのダウンロードについては説明が書かれており、それに沿って行うだけです。
あと下記記事も参考にしました。
FiftyOne を使って Open Images Dataset のデータを取得する
- fiftyoneのインストール
!pip install fiftyone
- ダウンロード
引数として
・open imagesのバージョンを指定(open images以外のデータセットでも使えるものもあり)
・splitは"train", "validation", "test"のいずれかでデータの取り出し先指定
・label_typesは物体検出なら"detections"
・classesは取り出したいクラス名(open imagesは全部で600ある)
・max_sampleはダウンロードする最大画像枚数
・only_matching=Trueで指定したラベルだけ取得
import fiftyone.zoo as foz
dataset = foz.load_zoo_dataset(
"open-images-v7",
split="validation",
label_types=["detections"],
classes=["Book"],
max_samples=100,
only_matching=True,
)
上記を実行すると画像とアノテーション情報がまとまったdetection.csvなどが取得できます。
detection.csvはこんな感じ(一部表示)。
ImageIDは各画像の名前と一致しており、これをキーとして各BBoxとラベル名が取得できるようになっています。
LabelNameはclasses.csvを参照するとわかるようになっています。
この場合"Book"は"/m/0bt_c3"
(detection.csvにBook以外のラベルも存在してることに気づいた)
画像とアノテーション情報を表示してみます。
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt
import cv2
# アノテーションデータの読み込み
detection = pd.read_csv("C:\\<path>\\fiftyone\\open-images-v6\\train\\labels\\detections.csv")
# クラスラベルの読み込み
classes = pd.read_csv("C:\\<path>\\fiftyone\\open-images-v6\\train\\metadata\\classes.csv")
# ラベル名表示させたいのでdetectionにclassesを繋げとく(やや雑)
detection_classes = detection.merge(classes, left_on = "LabelName", right_on = "/m/011k07", how = "left")
# クラス名を文字型にしとく
detection_classes["Tortoise"] = detection_classes["Tortoise"].astype(str)
# 画像"102ef529073e278c.jpg"の読み込みとサイズ取得
img = cv2.imread("C:\\<path>\\fiftyone\\open-images-v6\\train\\data\\102ef529073e278c.jpg")
y, x = img.shape[0:2]
# 画像"102ef529073e278c.jpg"のアノテーション情報を取得
annotation = detection_classes[detection_classes["ImageID"] == "102ef529073e278c"]
# BBoxを画像上に表示
for idx, anno in annotations.iterrows():
coord1 = (int(round(x * anno.XMin)), int(round(y * anno.YMin)))
coord2 = (int(round(x * anno.XMax)), int(round(y * anno.YMax)))
cv2.rectangle(img, coord1, coord2, color=(0, 255, 0), thickness = 2)
cv2.putText(img, anno.Tortoise, (coord1[0], coord1[1]), cv2.FONT_HERSHEY_SIMPLEX, fontScale = 1.0, (0, 255, 0), thickness = 2)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
"only_matching=True"にしたのですが本以外のアノテーションもついてしまってました。
この辺は改めて調べようと思いつつ、とりあえずデータフレームの段階で条件を絞ってもう一度表示させます。
detection_classesのクラス名Bookだけのデータフレームを作ってannotation再定義して同じように実行します。
book_annotetion = detection_classes[detection_classes["Tortoise"] == "Book"]
実際に物体検出の学習で使う際にはこの後、アノテーション情報が入ったcsvファイルをSSDならxml形式、YoLoならtxt形式などに変換する必要がありますが、調べたらそれらのコードは転がってそうです。
以上で本だけの画像とアノテーションデータを取得することはできましたが、open imagesの画像ではあまり本のアップがなく、引きでの写真が多く、いくつかの本がまとまって1つのBBoxを与えられているものばかりでした。
個人的には本を確実に一冊一冊検出させたかったため、自分ででデータセット作ろうかなと思いました。
もちろんデータセットの中にが一冊一冊にBBoxが付けられているようなデータもあるので、これらのデータセットを使っても問題ないのかもしれませんが。。。
本アップでもまとめてBBoxついてたりする。
いろいろな画像があった。
おわりに
データセットを眺めてると日本っぽい画像もあったりしてなんか見てるだけでも面白かったです。
漫画一冊でも表紙のキャラクターに対してたくさんのラベルが付いてて驚きました。
今回初めてこういった画像データセットの中身見たので、今後使う機会があればと思います。