FCNでSemantic segmentationをやってみようと思いたち、物体のパーツ単位で正解マスクが提供されているPASCAL-Part Datasetを使うことにした。のだが、正解マスクが含まれているmatファイルのフォーマットがよくわからない!データセットにはオリジナル画像 やマスク画像をタイル表示するデモ用のmatlabスクリプトがあるけれど、matlabはあまり慣れてない... こういうのは慣れてるものを使えばいいやということで、ipythonでインタラクティブに解析することにしたよ。
ルート > オブジェクト > パーツ
結局、データのルート > オブジェクト > オブジェクト毎パーツというような階層になってて、書いてみれば直感的にわかるけど、多量にネストされていて理解するまでに時間がかかった...
例えば、下の画像であれば
In [1]: import scipy.io as sio In [2]: data = sio.loadmat('Annotations_Part/2008_003228.mat') In [3]: data.keys() Out[3]: dict_keys(['__header__', '__version__', '__globals__', 'anno']) In [4]: data['anno'][0][0][0] Out[4]: array(['2008_003228'], dtype='<U11') # ここがルートで、この画像に含まれるオブジェクト数は4 In [5]: data['anno'][0][0][1].shape Out[5]: (1, 4) # オブジェクトの情報 # オブジェクトはpersonが3個、catが1個(画像左の黒い領域) In [6]: data['anno'][0][0][1][:, 0][0][0] Out[6]: array(['person'], dtype='<U6') In [7]: data['anno'][0][0][1][:, 1][0][0] Out[7]: array(['person'], dtype='<U6') In [8]: data['anno'][0][0][1][:, 2][0][0] Out[8]: array(['person'], dtype='<U6') In [9]: data['anno'][0][0][1][:, 3][0][0] Out[9]: array(['cat'], dtype='<U3') # パーツの情報 # 1番目のオブジェクトのパーツ数, personはmaxで24パーツまで In [11]: data['anno'][0][0][1][:, 1][0][3].shape Out[11]: (1, 16) # 0番目のパーツの名前 => head In [16]: data['anno'][0][0][1][:, 1][0][3][:, 0][0][0] Out[16]: array(['head'], dtype='<U4') # 1番目のパーツの名前 => left ear In [21]: data['anno'][0][0][1][:, 1][0][3][:, 1][0][0] Out[21]: array(['lear'], dtype='<U4') # 正解マスク In [22]: data['anno'][0][0][1][:, 1][0][3][:, 1][0][1] Out[22]: array([[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]], dtype=uint8) # 正解マスクのサイズ = 画像サイズ In [23]: data['anno'][0][0][1][:, 1][0][3][:, 1][0][1].shape Out[23]: (375, 500)
後は、これを取り出して画像とペアにすれば、FCN用のPart datasetが準備出来ることになる!(ほんとはまだ)
おまけで、matlabのデモコードを実行したときのマスク画像(右下)はこんなの。