1. COCO Data Set이란?
COCO Data Set은 "Common Objects in Context"의 약자로 Object detation, Segmentation, image capsion과 같은 컴퓨터 비전 작업을 위해 널리사용되는 대규모 이미지 데이터셋입니다. COCO Data Set은 오픈 라이선스를 가지고 있어 학술 연구와 상업적인 목적을 포함한 다양한 분야에서 활용됩니다. 특히 논문에서 성능 평가 목적으로 많이 사용됩니다. COCO Data Set은 다양한 카테고리에 속하는 약33만 개의 이미지로 구성되어 있으며, 이들 이미지에는 약 80개 이상의 일상적인 객체가 포함되어 있습니다. 각 이미지에는 bbox, segmentation, caption, keypoint 정보가 제공됩니다.
2. 데이터셋 다운로드
COCO Data Set은 코드로 다운로드 받는 방법이 있고 홈페이지에서 다운로드 받는 방식이 있습니다. 필자는 홈페이지에서 다운로드 받았습니다. 링크를 통해 공식 웹 사이트로 이동을 합니다.
공식 웹사이트에서 Dataset 메뉴에 들어가면 데이터셋을 다운로드할 수 있습니다. 필자는 2017년도 Train, Val, Test 이미지 데이터셋과 Train/Val annotations을 다운로드 받았습니다. 학습(training) 데이터셋은 118,000장, 검증(validation) 데이터셋은 5,000장, 테스트(test) 데이터셋은 41,000장의 이미지로 구성되어 있습니다. 합쳐서 용량은 약 26GB입니다. 그렇기 때문에 용량을 충분하게 만들어 놔야하고 시간도 많이 걸립니다.
다운로드된 압축파일을 해제하면 아래와 같이 이미지가 있으며 annotation파일을 압축해제하면 json파일이 있습니다.
3. Annotation 파일
Object detation, Segmentation에 가장 많이 사용되는 Annotation 파일은 다음과 같은 구성을 가지고 있습니다. 큰 단락으로 info, License, images, annotations, categories로 나눠져 있습니다. 단락 중 annotations과 categories는 captions, instances, keypoints 파일에 따라 다르게 구성됩니다.
3.1 info, License
Annotation파일의 가장 첫 번째에는 데이터셋에 관련된 정보들이 있다. 그 다음으로는 이미지에 관련된 License url과 이름이 들어가 있다.
"info": {
"description": "COCO 2017 Dataset",
"url": "http://cocodataset.org",
"version": "1.0",
"year": 2017,
"contributor": "COCO Consortium",
"date_created": "2017/09/01"
},
"licenses": [
{
"url": "http://creativecommons.org/licenses/by-nc-sa/2.0/",
"id": 1,
"name": "Attribution-NonCommercial-ShareAlike License"
},
{
"url": "http://creativecommons.org/licenses/by-nc/2.0/",
"id": 2,
"name": "Attribution-NonCommercial License"
},
{
"url": "http://creativecommons.org/licenses/by-nc-nd/2.0/",
"id": 3,
"name": "Attribution-NonCommercial-NoDerivs License"
}
...
]
3.2 Images
License 다음으로는 이미지 파일에 관련된 내용이 나온다. 이 내용에는 라이센스 번호와 파일이름, 이미지 url, 이미지 크기, captured 날짜, 아이디가 들어가있다.
"images": [
{
"license": 4,
"file_name": "000000397133.jpg",
"coco_url": "http://images.cocodataset.org/val2017/000000397133.jpg",
"height": 427,
"width": 640,
"date_captured": "2013-11-14 17:02:52",
"flickr_url": "http://farm7.staticflickr.com/6116/6255196340_da26cf2c9e_z.jpg",
"id": 397133
},
{
"license": 1,
"file_name": "000000037777.jpg",
"coco_url": "http://images.cocodataset.org/val2017/000000037777.jpg",
"height": 230,
"width": 352,
"date_captured": "2013-11-14 20:55:31",
"flickr_url": "http://farm9.staticflickr.com/8429/7839199426_f6d48aa585_z.jpg",
"id": 37777
}
...
]
3.3.1 Annotations(Caption)
다음으로 annotations 내용이 나온다. annotations은 위에서 말했던것과 같이captions, instances, keypoints에 따라 다르다. 아래 annotations는 caption annotations이다. 이미지 아이디와, caption id그리고 caption 내용이 있다.
"annotations": [
{
"image_id": 179765,
"id": 38,
"caption": "A black Honda motorcycle parked in front of a garage."
},
}
]
3.3.2 Annotations(Instances)
아래 annotations는 instances annotations이다. segmentation정보와 area, iscrowd, image_id, bbox, category_id, id가 있다.
"annotations": [
{
"segmentation": [
[
510.66,
423.01,
511.72,
420.03,
510.45,
...
506.31,
423.32,
510.03,
423.01,
510.45,
423.01
]
],
"area": 702.1057499999998,
"iscrowd": 0,
"image_id": 289343,
"bbox": [
473.07,
395.93,
38.65,
28.67
],
"category_id": 18,
"id": 1768
}
]
3.3.3 Annotations(keypoint)
아래 annotations는 keypoint annotations이다. segmentation정보와 area, iscrowd, image_id, bbox, category_id, id가 있다.
"annotations": [
{
"segmentation": [
[
125.12,
539.69,
140.94,
522.43,
100.67,
496.54,
...
145.26,
567.01,
117.93,
551.19,
133.75,
532.49
]
],
"num_keypoints": 10,
"area": 47803.27955,
"iscrowd": 0,
"keypoints": [
0,
0,
0,
0,
...
0,
0,
162,
551,
2
],
"image_id": 425226,
"bbox": [
73.35,
206.02,
300.58,
372.5
],
"category_id": 1,
"id": 183126
}
]
3.4.1 Categories(Instances)
다음으로 categories 내용이 나온다. categories 은 위에서 말했던것과 같이 captions, instances, keypoints에 따라 다르다. captions는 Categories가 없다. 아래 annotations는 instances categories이다. 아이디, 카테고리, 이름이 있다.
"categories": [
{
"supercategory": "person",
"id": 1,
"name": "person"
},
{
"supercategory": "vehicle",
"id": 2,
"name": "bicycle"
},
{
"supercategory": "vehicle",
"id": 3,
"name": "car"
}
...
]
3.4.2 Categories(Keypoint)
아래 categories는 keypoint categories이다. 카테고리, 아이디, 이름, keypoint 이름, Skeleton 정보가 있다.
"categories": [
{
"supercategory": "person",
"id": 1,
"name": "person",
"keypoints": [
"nose",
"left_eye",
"right_eye",
"left_ear",
"right_ear",
"left_shoulder",
"right_shoulder",
"left_elbow",
"right_elbow",
"left_wrist",
"right_wrist",
"left_hip",
"right_hip",
"left_knee",
"right_knee",
"left_ankle",
"right_ankle"
],
"skeleton": [
[16, 14],
[14, 12],
[17, 15],
...
[3,5],
[4, 6],
[5, 7]
]
}
...
]
4. COCO data set lode code
아래 코드는 COCO 데이터 셋에서 이미지를 로드하고, 해당 이미지에 대한 Segmentation, bouding box, Class name을 시각화하는 코드입니다.
import cv2
import numpy as np
from pycocotools import mask as maskUtils
from torchvision.datasets import CocoDetection
import random
# 데이터셋 경로 설정
data_dir = 'D:/Coco/val2017'
Caption_file = 'D:/Coco/annotations/captions_val2017.json' #Caption
instances_file = 'D:/Coco/annotations/instances_val2017.json' #Segmentation, category_id, bbox
keypoints_file = 'D:/Coco/annotations/person_keypoints_val2017.json' #Segmentation, keypoints, id, bbox
# 데이터셋 로드
dataset = CocoDetection(root=data_dir, annFile=instances_file)
coco = dataset.coco
# 색상 목록
colors = []
for _ in range(50):
color = [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]
colors.append(color)
# 이미지와 인스턴스 정보 가져오기
for i in range(len(dataset)):
image, target = dataset[i]
# 이미지 시각화
image = np.array(image)
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# 인스턴스 정보 가져오기
for obj in target:
segmentation = obj["segmentation"]
bbox = obj["bbox"]
category_id = obj["category_id"]
color = colors[category_id % len(colors)]
color_bgr = color[::-1] # Convert RGB to BGR
# 바운딩 박스 시각화
bbox = [int(coord) for coord in bbox]
cv2.rectangle(image, (bbox[0], bbox[1]), (bbox[0] + bbox[2], bbox[1] + bbox[3]), color_bgr, 2)
#segmentation이 유효한지 확인
if isinstance(segmentation, list):
h, w = image.shape[:2]
mask = np.zeros((h, w), dtype=np.uint8)
for seg in segmentation:
poly = np.array(seg).reshape((-1, 2)).astype(np.int32)
cv2.fillPoly(mask, [poly], 255) # color is not specified here
mask_color = np.stack([mask]*3, axis=-1)
for i in range(3):
mask_color[..., i][mask_color[..., i] == 255] = color[i] # Use RGB color for mask
alpha = ((mask_color > 0).max(axis=2) * 128).astype(np.uint8)
rgba_mask = np.concatenate([mask_color, alpha[:, :, np.newaxis]], axis=2)
image_rgba = cv2.cvtColor(image, cv2.COLOR_BGR2RGBA)
image_rgba = cv2.addWeighted(image_rgba, 1, rgba_mask, 0.5, 0)
image = cv2.cvtColor(image_rgba, cv2.COLOR_RGBA2BGR)
# 클래스 이름 가져오기
cat_id = coco.getCatIds(catIds=[category_id])
cat_name = coco.loadCats(cat_id)[0]['name']
# 클래스 이름 시각화
cv2.putText(image, cat_name, (bbox[0], bbox[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color_bgr, 2)
# 이미지 출력
cv2.imshow('Image', image)
if cv2.waitKey(0) == ord('q'):
break
cv2.destroyAllWindows()