
안녕하세요. 최근 Mask R-CNN을 공부하며, COCO Dataset에 대해 다뤄보게 되었습니다.
COCO Dataset에 유용한 API로 pycocotools를 사용했습니다. 그래서 간단하게 복습해봤습니다.
pycocotools github
MS COCO 데이터를 다루기 전에 COCO 데이터가 뭔지 간단하게 알아보겠습니다.
Object Detection분야에서 기존 PASCAL VOC 데이터를 다뤘었습니다.
PASCAL VOC는 20개의 카테고리로 이루어진 데이터 형태입니다. (당연히 데이터는 이미지 입니다.)
PASCAL VOC 데이터를 이용한 대회도 나왔습니다. 하지만, 모델이 점점 발전하며 PASCAL VOC 데이터만으로는 모델의 성능을 믿을 수 없었습니다.
PASCAL VOC 데이터를 살펴보면 하나의 이미지당 Object 수가 적었기 때문에 이는 실제 상황과 괴리가 있다고 볼 수 있습니다.
따라서 나온 데이터가 MS COCO입니다.
MS COCO는 총 80개의 카테고리로 이루어져 있으며, PASCAL VOC와 달리 하나의 이미지당 Object 수가 비교적 많았습니다.
이렇게 MS COCO를 이용한 대회도 나오게 되었고, IOU = 0.5 ~ 0.95까지로 비교하여 mAP 성능을 측정하는 등 PASCAL VOC 대회에 비해 까다로운 대회로 자리잡았습니다.
MS COCO의 경우 실제로는 카테고리가 91개이지만, 이미지에 속하지 않는 데이터를 제외하면 80개가 맞습니다.
pycocotools는 COCO 데이터 형태를 쉽게 다룰 수 있게 해주는 API입니다.
pycocotools를 이용해 COCO 데이터를 가져오며 주요 함수에 대해 공부하겠습니다.
from pycocotools.coco import COCO
### coco 객체 만들기.
coco = COCO(annFile)
pycocotools.coco의 COCO( )를 이용하면 COCO 객체를 만들 수 있습니다.
이 객체에 내장된 함수를 이용해 COCO 데이터를 다루기 때문에 COCO( ) 내부에서 대부분의 동작이 이루어진다고 보시면 됩니다.
참고로 annFile의 경로는 2017 MS COCO Train/Val 데이터의 instances_val2017.json 파일입니다.
http://images.cocodataset.org/annotations/annotations_trainval2017.zip
category_ids = coco.getCatIds()

이렇게 만들어진 coco 객체의 getCatIds 메서드를 이용하면 모든 category에 대한 id를 리스트 형태로 받을 수 있습니다.
category_id = coco.getCatIds(catNms=['person','dog','skateboard'])

getCatIds 메서드는 catNms라는 인자가 존재합니다.
인자는 리스트 형태로 입력받으며, 해당되는 카테고리에 대한 아이디를 반환하게 됩니다.
categories = coco.loadCats(coco.getCatIds())

loadCats 메서드를 사용하면 인자로 들어온 Category Id에 대한 상세 정보를 리스트 형태로 볼 수 있습니다.
상세 정보를 보시면 supercategory, id, name으로 키 값이 나눠져 있습니다. 각각은 다음과 같은 의미를 지닙니다.
- supercategory: 카테고리에 해당하는 부모 카테고리(따라서 부모 카테고리는 더 포괄적임)
- id: 카테고리 id
- name: id에 해당하는 label
catIds = coco.getCatIds(catNms=['person','dog','skateboard'])
imgids = coco.getImgIds(catIds)

getImgIds 메서드를 이용하면 인자로 들어온 category Id가 들어가 있는 이미지 Id를 반환합니다.
이때, image id는 각 category당 한 개만 반환됩니다.
예를 들어, coco.getImgIds([1])은 "사람이 존재하는 이미지 아이디를 반환해줘."라는 의미입니다. 하지만, 반환되는 값은 1개만 존재합니다.
실제로는 매우 많은 이미지가 해당되지만, 임시로 하나를 뽑아주는 것입니다.
img = coco.loadImgs(32418)

loadImgs 메서드는 loadCats 메서드와 비슷하게 이미지에 대한 상세 정보를 반환해줍니다.
이때, 반환되는 값은 리스트로 감싸진 딕셔너리 형태입니다.
인자로 여러 값을 리스트 형태로 넣어주면 여러 딕셔너리를 반환합니다.
catIds = coco.getCatIds(catNms=['person','dog','skateboard'])
img = coco.loadImgs(32418)
annids = coco.getAnnIds(imgIds=img['id'], catIds=catIds, iscrowd=None)

getAnnIds 메서드는 해당되는 Annotation Id를 반환해줍니다.
메서드 인자는 다음과 같습니다.
- imgIds: annotation Id를 가져올 이미지 Id
- catIds: 해당 이미지에서 가져올 category(만약 모든 카테고리에 대한 정보를 가져오려면 [ ]를 입력해주면 됨)
- iscrowd: crowd label에 대한 정보를 통해 annotation Id를 가져옴
annids = coco.getAnnIds(imgIds=img['id'], catIds=catIds, iscrowd=None)
anns = coco.loadAnns(annids)

loadAnns 메서드는 인자 annotation Id에 해당하는 annotation 상세 정보를 반환합니다.
딕셔너리가 리스트로 감싸진 형태이고, 각 딕셔너리는 하나의 Object를 의미합니다.
coco.showAnns(anns)

showAnns 메서드는 위에서 coco.loadAnns 메서드에서 구한 annotation 상세 정보를 인자로 넣어주면 자동으로 그림을 그려줍니다.
[개정판] 딥러닝 컴퓨터 비전 완벽 가이드
https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocotools/coco.py