LoginSignup
2
2

More than 1 year has passed since last update.

MMDetectionで得られたInstance segmentationの結果を取り出す方法について

Last updated at Posted at 2022-04-25

MMDetectionでtools/test.pyを用いて得られたInstance segmentationの結果はhoge.bbox.jsonhoge.segm.jsonに保存されます。(test.pyなどの詳しい使い方については公式documentを参考にしてください。)

MMDetectionでの推論例
$ python tools/test.py config/my_config.py checkpoints/my_config_weight.pth --options "jsonfile_prefix=results/hoge"

hoge.segm.jsonからsegmentation領域の情報を取り出すのに手間取ったためまとめておきます。
inference_detectorを用いた場合も同様に取り出せます。

筆者環境

  • WSL2 on windows11
  • ubuntu 20.04
  • docker
  • pytorch 1.11.0+cu113
  • MMDetection 2.23.0
  • cuda 11.3
  • GCC 7.3

Instance segmentationの結果について

MMDetectionではInstance segmentationの結果は、hoge.bbox.jsonhoge.segm.jsonといったjson形式で出力されます。
Instance segmentationのtaskでは、segmentationした領域のピクセル数(≒面積)やそのポリゴンの形に興味がある場合があります。
hoge.segm.jsonにsegmentationした領域の情報が入っていることは明らかなので中身を見てみます。

hoge.segm.json
{"image_id": 0, 
   "bbox": [587.4173583984375, 327.16925048828125, 326.24078369140625, 441.67816162109375], 
   "score": 0.9949996471405029, 
   "category_id": 0, 
   "segmentation": 
      {"size": [2048, 1323], 
       "counts": "f^nT1k1mm1c0@>D8H7I6I7J7I8H6J6K4L4L4L5K6J6J7I6I6K5J5L5K4L5K3N3L3N2M4M3M2N4L2N3M2N1O2M3N3M2M4M2M4M4L4L4L3M3M2O1N2N3M2N2N1O2N2O0O2N1O2O1N2N2O1N3M2O2M3N2M4M1N2O1O1N2O1O1N2O1O1N2O0O2N2O1N2N2N2O1N2N2O1N101N2O001N101O0O2O0O2O1O0O2O1O2N1N3N1O2N2N2M2O1O1O1N10001N10001O0O101O00001O00001O00010O00001O0000001O0O10001O00000O2O0001O01O000010O01O001O01O0001O0O100000000000000010O00001O001O001O001O00001O0O101O00001O000O2O00001N101O001N101O0O2O001N101O0O2O001O0O2O00001N101N101N2O0O2N101N2N101N2O0O2O1N101N2N101N2N2N2N2N3L3N2M4M2M4L4L3N2N2N2N2N101N1O2O1N2N101N2N102M2N2M4L4K6J6J5J7K5K3N3M2N2N3M2N2N3M2N3M3M4L4J7I6I6J6K5L4L4L5J5L5K7H8E:G8H9I6J8I7H8I8G8^Ob0F;Fg0VOY_ki0"}
}
{"image_id": 0, 
   "bbox": [509.74078369140625, 747.2927856445312, 271.965576171875, 288.40106201171875], 
   "score": 0.15585921704769135, 
   "category_id": 0, 
   "segmentation": 
      {"size": [2048, 1323], 
      "counts": "[k^Q16go1?A;E9D7J7M3M2M4N1N3L5L4K6J3K4M4M3N2O0O100O1O2O0O1O1O1N2O2M2O2M2O2M4L5L5K4L1O2O0O100O1O100O1O1O1N2N3M2N2N3N1O1O2N100O10000O10000O100O2O1N2N2M3M3N3L4M3L4N0O100O100O100O10000O3N1N2N101N101N100O2O0000000000000O1000001O0O2O001N101O1O00000O2O0000001O00001O1O100O1O1O1O2N1O000000000001O0O100000001O100O001O010O001O001O000O2O001O001N2O1N3M2N2N3M3L4M3L3N2O1O000O2O001O001O003L5K5L3L3N2M3N1N2SKWUNa4Uk1N2O0O100O2O0N2O2N1O2M3M3L5M2N3L3N3M3M3M2N2M3M3M3L4N2N2N2N2N2N1O2N2N2N1O2L3K6K5N2M4M6I9H9F^T[R1"}
},...
  • image_id:画像を特定するためのid
  • bbox:バウンディングボックスの形。 [中心のx座標, 中心のy座標, 幅, 高さ]の順
  • score:バウンディングボックスが正しく判定されている確率
  • category_id:検出した物体がどのカテゴリに属しているかを表すid
  • segmentation:RLE形式で書かれたsegmentation領域の情報
    • size:segmentation領域の[幅,高さ]
    • counts:RLE形式にencodeされたポリゴン座標

image_isからcategory_idまではobject detectionのtaskでも同様に出力されます(hoge.bbox.json)。
今回興味があるのはsegmentationした領域なのでsegmentationの内容を読み解く必要があります。
しかしこのままではRLE形式にエンコードされていて読み解けません。そのためデータ形式の変換が必要です。

RLE形式からdecode

まず、pycocotoolsをインストールします。

pycocotoolsのインストール
$ pip install cython
$ git clone https://github.com/cocodataset/cocoapi.git
$ cd cocoapi/PythonAPI/
$ make install
$ python setup.py install

上記のコマンドでpycocotoolsをインストールできます。

次にhoge.segm.jsonを読み込みます。

hoge.segm.jsonの読み込み
import json
json_open = open("hoge.segm.json")
json_load = json.load(json_open)
segm = json_load[0] #今回は1つだけ取り出します。
print(segm)
segm
{"image_id": 0, 
   "bbox": [587.4173583984375, 327.16925048828125, 326.24078369140625, 441.67816162109375], 
   "score": 0.9949996471405029, 
   "category_id": 0, 
   "segmentation": 
      {"size": [2048, 1323], 
       "counts": "f^nT1k1mm1c0@>D8H7I6I7J7I8H6J6K4L4L4L5K6J6J7I6I6K5J5L5K4L5K3N3L3N2M4M3M2N4L2N3M2N1O2M3N3M2M4M2M4M4L4L4L3M3M2O1N2N3M2N2N1O2N2O0O2N1O2O1N2N2O1N3M2O2M3N2M4M1N2O1O1N2O1O1N2O1O1N2O0O2N2O1N2N2N2O1N2N2O1N101N2O001N101O0O2O0O2O1O0O2O1O2N1N3N1O2N2N2M2O1O1O1N10001N10001O0O101O00001O00001O00010O00001O0000001O0O10001O00000O2O0001O01O000010O01O001O01O0001O0O100000000000000010O00001O001O001O001O00001O0O101O00001O000O2O00001N101O001N101O0O2O001N101O0O2O001O0O2O00001N101N101N2O0O2N101N2N101N2O0O2O1N101N2N101N2N2N2N2N3L3N2M4M2M4L4L3N2N2N2N2N101N1O2O1N2N101N2N102M2N2M4L4K6J6J5J7K5K3N3M2N2N3M2N2N3M2N3M3M4L4J7I6I6J6K5L4L4L5J5L5K7H8E:G8H9I6J8I7H8I8G8^Ob0F;Fg0VOY_ki0"}
}

次にpycocotoolsを使ってdecodeします。

pycocotoolを使ったdecode
import pycocotools.mask as mask
maskedArr = mask.decode(segm["segmentation"]) #segmentation部分のみがdecode対象のため
print(type(maskedArr)) 
print(maskedArr)
出力結果
<class `numpy.ndarray`>

[[0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 ...
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]]

pycocotools.mask.decodeによりRLE形式numpy形式に変換することができました。
maskedArrにsegmentationした領域が描画された配列が格納されているので、あとはopencvなどを使って面積などの特徴量を取得することができます。

inference_detectorを用いた場合

MMDet_InstanceSeg_Tutorial.ipynb
# Use the detector to do inference
img = 'demo/demo.jpg'
result = inference_detector(model, img)

MMDetectionのチュートリアルノートブックでは上記のようにしてInstance segmentationを行います。resultに結果が入っている状態です。
resultはbboxとsegmの情報が格納されています。

bbox, segm = results
print(bbox[0])
print(segm[0])
出力結果
array([[2.38843811e+02, 9.87134094e+01, 2.49885818e+02, 1.08494499e+02,
        1.03378251e-01], dtype=float32)
[array([[False, False, False, ..., False, False, False],
       [False, False, False, ..., False, False, False],
       [False, False, False, ..., False, False, False],
       ...,
       [False, False, False, ..., False, False, False],
       [False, False, False, ..., False, False, False],
       [False, False, False, ..., False, False, False]])]
  • bbox:バウンディングボックスの内容+確率[中心のx座標, 中心のy座標, 幅, 高さ, 確率]
  • segm:bool型で領域を描写

ここからsegmを一度RLE形式にencodeします。

RLE形式にencode
from mmdet.core import encode_mask_results
encode_result = (bbox, encode_mask_results(segm))
  • encode_result[0]:bboxの配列
  • encode_result[1]:RLE形式のsegmentation領域の情報

となるので、あとはencode_result[1]を上記のpycocotools.mask.decodeを用いて変換してやれば終わりです。

さいごに

今回はMMDetectionでのInstance segmentationの結果を取り出す方法についてまとめました。
間違いなどあればご指摘いただけると幸いです。
ありがとうございました。

参考URL

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2