꺼내먹는지식 준

COCO data 처리 본문

AI/CV

COCO data 처리

알 수 없는 사용자 2022. 3. 22. 08:50
{
  "info": {
    "year": 2021,
    "version": "1.0",
    "description": "Garage Sale goods",
    "contributor": "NeverMind",
    "url": null,
    "date_created": "2021-02-02 02:10:00"
  },
  "licenses": [
    {
      "id": 0,
      "name": "CC BY 4.0",
      "url": "https://nevermind.org/licenses/by/4.0/youneverknow.ast"
    }
  ],
  "images": [
    {
      "width": 1024,
      "height": 1024,
      "file_name": "test/1705.jpg",
      "license": 0,
      "flickr_url": null,
      "coco_url": null,
      "date_captured": "2021-01-01 13:30:03",
      "id": 1705
    },
      "images": [
    {
      "width": 1024,
      "height": 1024,
      "file_name": "test/1706.jpg",
      "license": 0,
      "flickr_url": null,
      "coco_url": null,
      "date_captured": "2021-01-01 13:30:03",
      "id": 1706
    },
    ...
..

{
      "image_id": 1705,
      "category_id": 1,
      "area": 672507.36,
      "bbox": [
        29.8,
        128.8,
        988.4,
        680.4
      ],
      "iscrowd": 0,
      "id": 8045
    },
...

다음과 같은 형태, 즉 COCO data 형식에 맞는 데이터가 있다고 하자. 

 

  • 이미지의 width, height, id
  • 각 이미지 마다의 Bounding Box 정보 다만, 이미지마다 Bounding Box 의 개수는 다르기에, image_id 당 개수는 상이하다. 

 

 

 

coco = COCO(file_name)

 

다음의 선언 후, 여러가지를 해볼 수 있다. 

먼저, 

coco.getImgIds():return image id list

id list를 접근하기 쉽게 list로 return 해준다. 

coco.loadImgs(image_id): return image_info

list 의 id element들로 loadImgs를 하면, image_info를 얻을 수 있다. 

image_info 는 다음같은 형태이다. 

[{'width': 1024, 'height': 1024, 'file_name': 'train/4882.jpg',
'license': 0, 'flickr_url': None, 'coco_url': None, 'date_captured':
'2020-12-23 16:20:30', 'id': 4882}]

dict 형태로 다루기 위해 

image_info = coco.loadImgs(image_id)[0]

다음과 같이 사용한다. 

 

print("1: ", coco.dataset["images"][1])

print("2: ", coco.loadImgs(image_id))

1:  {'width': 1024, 'height': 1024, 'file_name': 'train/0001.jpg', 
'license': 0, 'flickr_url': None, 'coco_url': None, 'date_captured': 
'2021-01-10 16:30:39', 'id': 1}

2:  [{'width': 1024, 'height': 1024, 'file_name': 'train/4882.jpg',
'license': 0, 'flickr_url': None, 'coco_url': None, 'date_captured':
'2020-12-23 16:20:30', 'id': 4882}]

 

coco.dataset["images"] 하면 image에 해당하는 모든 내역 저장 

실제로 dataset 이라는 key는 없지만 자동 생성되는 것으로 보인다. 

 

annotation_id = coco.getAnnIds(imgIds=image_info['id'])

image_id로 image_info를 얻을 수 있지만, 더 나아가서 annotation id도 얻을 수 있다. 

[23139, 23140, 23141, 23142, 23143]

annotation id 는 coco 데이터가 제작되며 생성되는 것으로 보인다. 

annoatations['annotations']는 이미지 id 당 여러 개(= 해당 이미지에 담긴 객체 수만큼)의 dict가 존재한다. 

(즉, 한 ID에 객체가 몇개냐에 따라 얻을 수 있는 annotation_id가 다르다.)

coco.loadAnns(ann_ids): return annotation information list (annotation_info_list)

객체의 annotation id 에 해당되는 정보들을 얻을 수 있다. 

 

[{'image_id': 4882, 'category_id': 5, 'area': 768591.81, 'bbox': 
[0.0, 116.2, 944.1, 814.1], 'iscrowd': 0, 'id': 23139}, 
{'image_id': 4882, 'category_id': 7, 'area': 57309.72, 
'bbox': [302.1, 439.3, 265.2, 216.1], 'iscrowd': 0, 'id': 23140}, 
{'image_id': 4882, 'category_id': 0, 'area': 1772.74, 
'bbox': [511.3, 451.1, 58.7, 30.2], 'iscrowd': 0, 'id': 23141}, 
{'image_id': 4882, 'category_id': 1, 'area': 53008.67, 
'bbox': [255.0, 421.4, 271.7, 195.1], 'iscrowd': 0, 'id': 23142}, 
{'image_id': 4882, 'category_id': 1, 'area': 149633.22,
'bbox': [145.4, 295.4, 420.2, 356.1], 'iscrowd': 0, 'id': 23143}]

 

annotation_info_list[i]['bbox']: return i'th annotation [x_min, y_min, w, h]
    
annotation_info_list[i]['category_id']: return i'th annotation category

'bbox' 정보도 얻을 수 있고, ([x,y,width,height])

category_id 즉 classification 정보도 얻을 수 있다. 

 

아래와 같이 활용 가능하다. 

 image_id in coco.getImgIds():
    #id list 를 쉽게 생성 
    #coco data form 으로 만들어줘야 한다.
        
    image_info = coco.loadImgs(image_id)[0]
    #각 list 마다 
    annotation_id = coco.getAnnIds(imgIds=image_info['id'])
    annotation_info_list = coco.loadAnns(annotation_id)
        
    file_name = image_info['file_name']
        
    for annotation in annotation_info_list:
        gt.append([file_name, annotation['category_id'],
                   float(annotation['bbox'][0]),
                   float(annotation['bbox'][0]) + float(annotation['bbox'][2]),
                   float(annotation['bbox'][1]),
                   (float(annotation['bbox'][1]) + float(annotation['bbox'][3]))])

 

다음과 같이 잘 조정해서 

gt 를 다음의 형태로 잘 만든 후, 

[['train/0000.jpg', 0, 197.6, 745.4, 193.7, 663.4],
 ['train/0001.jpg', 3, 0.0, 57.6, 407.4, 588.0],
 ['train/0001.jpg', 7, 0.0, 144.6, 455.6, 637.2],
 ['train/0001.jpg', 4, 722.3, 996.5999999999999, 313.4, 565.3],
 ['train/0001.jpg', 5, 353.2, 586.9, 671.0, 774.4],
 ['train/0001.jpg', 5, 3.7, 781.9000000000001, 448.5, 690.5],

사전에 동일한 형태로 생성 되었던 new_pred 와 mAP 연산을 할 수 있다. 

 

from map_boxes import mean_average_precision_for_boxes
mean_ap, ap = mean_average_precision_for_boxes(gt, new_pred, iou_threshold=0.5)

mean_average_precision_for_boxes의 매개변수는 아래와 같다. 

ImageID,LabelName,XMin,XMax,YMin,YMax
i0.jpg,Shellfish,0.0875,0.8171875,0.35625,0.8958333

 

 

 

※추가

coco의 loadCats 기능 검색해도 잘 안나온다. 

이에 따라 간략하게 정리한다. 

coco data set을 잘 살펴보면, category (label) 개수에 맞게 제공되는 데이터 정보가 있다. 

다음의 형태이다. 

 "categories": [
    {
      "id": 0,
      "name": "General face",
      "supercategory": "General face"
    },
    {
      "id": 1,
      "name": "Paper face",
      "supercategory": "Paper face"
    },

loadcat은 input으로 id 를 넣어주면, 해당 id 에서 category 정보를 가져와, 그 category 정보와 name 과 supercategory를 output 으로 제공해준다. 다음의 예제를 살펴보자. 

 

coco.loadCats([1])
[{'id': 1, 'name': 'Paper face', 'supercategory': 'Paper face'}]
category = coco.loadCats([x for x in range(10)]) category
[{'id': 0, 'name': 'General face', 'supercategory': 'General face'},
 {'id': 1, 'name': 'Paper face', 'supercategory': 'Paper face'},
 {'id': 2, 'name': 'face pack', 'supercategory': 'face pack'},
 {'id': 3, 'name': 'Metal face', 'supercategory': 'Metal face'},
 {'id': 4, 'name': 'Glass face', 'supercategory': 'Glass face'},
 {'id': 5, 'name': 'Plastic face', 'supercategory': 'Plastic face'},
 {'id': 6, 'name': 'Sty face', 'supercategory': 'Sty face'},
 {'id': 7, 'name': 'stick face', 'supercategory': 'stick face'},
 {'id': 8, 'name': 'never', 'supercategory': 'never'},
 {'id': 9, 'name': 'Cloe', 'supercategory': 'Cloe'}]

 

'AI > CV' 카테고리의 다른 글

Object Detection Neck  (0) 2022.03.22
MMdetection  (0) 2022.03.22
mAP란? FLOPs 란?  (0) 2022.03.21
YOLO v3  (0) 2022.03.19
3D Understanding  (0) 2022.03.17
Comments