Facebook AIが開発したPyTorchベースの物体検出ライブラリ Detectron2 のインストールと使用方法

スターやコメントしていただけると励みになります。 また、記事内で間違い等ありましたら教えてください。

Detectron2 とは

Detectron2とは、Facebook AIが開発したPyTorchベースの物体検出のライブラリです。
様々なモデルとそのPre-Trainedモデルが公開されており、panoptic segmentation, Densepose, Cascade R-CNN, rotated bounding boxes, PointRend, DeepLabなどを簡単に実装することができるようです。
とりあえず、ここではインストールから簡単なコードの実装まで行いたいと思います。

GitHub - facebookresearch/detectron2: Detectron2 is FAIR's next-generation platform for object detection and segmentation.

インストール

公式githubのページに書いてある通りですが、下記でインストールできました。

pip install opencv-python
pip install torch torchvision
CC=clang CXX=clang++ ARCHFLAGS="-arch x86_64" python -m pip install 'git+https://github.com/facebookresearch/detectron2.git'

実行

モジュールインポート

import torch, torchvision
print(torch.__version__, torch.cuda.is_available())

import torch
assert torch.__version__.startswith("1.7")

# Some basic setup:
# Setup detectron2 logger
import detectron2
from detectron2.utils.logger import setup_logger
setup_logger()

# import some common libraries
import numpy as np
import matplotlib.pyplot as plt
import os, json, cv2, random

# import some common detectron2 utilities
from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2.utils.visualizer import Visualizer
from detectron2.data import MetadataCatalog, DatasetCatalog

# 画像を保存するディレクトリを作成
dirname_picture = "./pictures/"
os.makedirs(dirname_picture, exist_ok=True)

# 画像表示用の関数を定義
def cv2_imshow(img):
    plt.figure(figsize=(8, 8))
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    plt.imshow(img)
    plt.show()

サンプル画像をダウンロード

COCOデータセットからサンプル画像をダウンロードしておきます。

http://images.cocodataset.org/val2017/000000439715.jpg

im = cv2.imread("./pictures/input.jpg")
cv2_imshow(im)

事前学習済みモデルを使用した予測

Pre-Trainedモデルは、Detectron2のModel Zooから探せます。 モデルの動物園とかいう活かした名前ですね。

以下のURLを見るとダウンロードできるモデルの一覧を取得できます。 かなり大量の種類があるので便利すぎます。 https://github.com/facebookresearch/detectron2/blob/master/MODEL_ZOO.md

Instance Segmentation

Instance Segmentationでは、物体の認識をピクセルレベルで実施しており、Bounding Boxだけでなく、対象物の領域も認識できます。
今回はチュートリアル通り、"COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"を用います。

# Detectron2のコンフィグを読み込みます
cfg = get_cfg()

# モデル固有のコンフィグをマージします
cfg.merge_from_file(model_zoo.get_config_file("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"))

# thresholdを設定します。この閾値より予測の確度が高いもののみ出力されます。
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5

# 今回利用するモデルのトレーニング済みファイルを読み込みます。
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")

# defaultだとcfgのDEVICE=cudaになっているので、cudaない場合はcpuに変更
cfg.MODEL.DEVICE = "cpu"
# predictorを構築し、予測を実行します
predictor = DefaultPredictor(cfg)
outputs = predictor(im)
# 予測された結果を確認します。
# 出力フォーマットはhttps://detectron2.readthedocs.io/en/latest/tutorials/models.html#model-output-formatで確認できます
print(outputs["instances"].pred_classes)
print(outputs["instances"].pred_boxes)

うまく推論できているのが分かります。簡単に使用できていいですね。

# `Visualizer`を使用することで、画像上に予測結果を表示できます
v = Visualizer(im[:, :, ::-1], MetadataCatalog.get(cfg.DATASETS.TRAIN[0]), scale=1.2)
out = v.draw_instance_predictions(outputs["instances"].to("cpu"))
cv2_imshow(out.get_image()[:, :, ::-1])

結果はこちらです。

f:id:yamayou_1:20210227162849p:plain

Object Detection

上と同じような流れで他のモデルも読み込むことができます。
ここでは、"COCO-Detection/faster_rcnn_R_50_FPN_3x.yaml"を使用します。

# Detectron2のコンフィグを読み込みます
cfg = get_cfg()

# モデル固有のコンフィグをマージします
cfg.merge_from_file(model_zoo.get_config_file("COCO-Detection/faster_rcnn_R_50_FPN_3x.yaml"))

# thresholdを設定します。この閾値より予測の確度が高いもののみ出力されます。
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5

# 今回利用するモデルのトレーニング済みファイルを読み込みます。
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-Detection/faster_rcnn_R_50_FPN_3x.yaml")

# defaultだとcfgのDEVICE=cudaになっているので、cudaない場合はcpuに変更
cfg.MODEL.DEVICE = "cpu"

# predictorを構築し、予測を実行します
predictor = DefaultPredictor(cfg)
outputs = predictor(im)

# 予測された結果を確認します。
# 出力フォーマットはhttps://detectron2.readthedocs.io/en/latest/tutorials/models.html#model-output-formatで確認できます
print(outputs["instances"].pred_classes)
print(outputs["instances"].pred_boxes)

# `Visualizer`を使用することで、画像上に予測結果を表示できます
v = Visualizer(im[:, :, ::-1], MetadataCatalog.get(cfg.DATASETS.TRAIN[0]), scale=1.2)
out = v.draw_instance_predictions(outputs["instances"].to("cpu"))
cv2_imshow(out.get_image()[:, :, ::-1])

f:id:yamayou_1:20210227162940p:plain

Keypoint Detection

Keypoint Detectionでは、人の姿勢を認識できます。
用途としては人以外にも適用する試みがあるみたいですが、アノテーションが難しいようですね。
コードは、同じ流れで実行できます。今回は、"COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml"を用います。

# Detectron2のコンフィグを読み込みます
cfg = get_cfg()

# モデル固有のコンフィグをマージします
cfg.merge_from_file(model_zoo.get_config_file("COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml"))

# thresholdを設定します。この閾値より予測の確度が高いもののみ出力されます。
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5

# 今回利用するモデルのトレーニング済みファイルを読み込みます。
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml")

# defaultだとcfgのDEVICE=cudaになっているので、cudaない場合はcpuに変更
cfg.MODEL.DEVICE = "cpu"

# predictorを構築し、予測を実行します
predictor = DefaultPredictor(cfg)
outputs = predictor(im)

# 予測された結果を確認します。
# 出力フォーマットはhttps://detectron2.readthedocs.io/en/latest/tutorials/models.html#model-output-formatで確認できます
print(outputs["instances"].pred_classes)
print(outputs["instances"].pred_boxes)

# `Visualizer`を使用することで、画像上に予測結果を表示できます
v = Visualizer(im[:, :, ::-1], MetadataCatalog.get(cfg.DATASETS.TRAIN[0]), scale=1.2)
out = v.draw_instance_predictions(outputs["instances"].to("cpu"))
cv2_imshow(out.get_image()[:, :, ::-1])

f:id:yamayou_1:20210227163053p:plain

Panoptic Segmentation

Panoptic Segmentationでは、全てのピクセルに対してラベルが振られているため、Instance Segmentationで予測されなかった他のオブジェクトも分類されます。
ここでは、"COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml"を用います。

# Detectron2のコンフィグを読み込みます
cfg = get_cfg()

# モデル固有のコンフィグをマージします
cfg.merge_from_file(model_zoo.get_config_file("COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml"))

# thresholdを設定します。この閾値より予測の確度が高いもののみ出力されます。
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5

# 今回利用するモデルのトレーニング済みファイルを読み込みます。
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml")

# defaultだとcfgのDEVICE=cudaになっているので、cudaない場合はcpuに変更
cfg.MODEL.DEVICE = "cpu"

# predictorを構築し、予測を実行します
predictor = DefaultPredictor(cfg)
# Panoptic Segmentationは少しコード違います
panoptic_seg, segments_info = predictor(im)["panoptic_seg"]

# 予測された結果を確認します。
# 出力フォーマットはhttps://detectron2.readthedocs.io/en/latest/tutorials/models.html#model-output-formatで確認できます
print(outputs["instances"].pred_classes)
print(outputs["instances"].pred_boxes)

# `Visualizer`を使用することで、画像上に予測結果を表示できます
v = Visualizer(im[:, :, ::-1], MetadataCatalog.get(cfg.DATASETS.TRAIN[0]), scale=1.2)
out = v.draw_panoptic_seg_predictions(panoptic_seg.to("cpu"), segments_info)
cv2_imshow(out.get_image()[:, :, ::-1])

f:id:yamayou_1:20210227163155p:plain

長くなったので、今回はここまで。
次回以降はファインチューニングやデータ水増しを試してみたいです。