꺼내먹는지식 준
COCO data 처리 본문
{
"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 |