본문 바로가기
컴퓨터비전

Pascal VOC 데이터 세트 탐색하기

by 차분한 공돌이 2024. 2. 20.

PASCAL VOC 2012 데이터 다운로드 받기

 

!mkdir ./data #data디렉토리 만들고

!wget http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar #다운로드 받기
!tar -xvf VOCtrainval_11-May-2012.tar -C /content/data #data 디렉토리에 압축해제하기

 

 

JPEGImages 디렉토리에 있는 임의의 이미지 보기

 

import cv2
import matplotlib.pyplot as plt
import os
%matplotlib inline

# 코랩 버전은 상대 경로를 사용하지 않습니다. /content 디렉토리를 기준으로 절대 경로를 이용합니다.
# default_dir 은 /content/data 로 지정하고 os.path.join()으로 상세 파일/디렉토리를 지정합니다.
default_dir = '/content/data'
img = cv2.imread(os.path.join(default_dir, 'VOCdevkit/VOC2012/JPEGImages/2007_000032.jpg'))
#os.path.join('/content/data','VOCdevkit/VOC2012/JPEGImages/2007_000032.jpg' ) => /content/data/VOCdevkit/VOC2012/JPEGImages/2007_000032.jpg
#cv2.imread : #지정된 경로의 이미지 파일이 읽혀져서 OpenCV에서 사용할 수 있는 형식인 Numpy 배열로 반환
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #cv2.imread()로 이미지 가져오면 BGR 형태이고, matplotlib으로 이미지 표시하려면 RGB형태여야 해서 바꿔주는 것
print('img shape:', img.shape)

plt.figure(figsize=(8, 8))
plt.imshow(img_rgb)
plt.show()

 

 

 

Annotations 디렉토리에 있는 임의의 annotation 파일 보기

 

!cat /content/data/VOCdevkit/VOC2012/Annotations/2007_000032.xml
#텍스트 파일을 출력하는 명령어

 

 

 

 

SegmentationObject 디렉토리에 있는 임의의 masking 이미지 보기

 

img = cv2.imread(os.path.join(default_dir, 'VOCdevkit/VOC2012/SegmentationObject/2007_000032.png'))
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
print('img shape:', img.shape)

plt.figure(figsize=(8, 8))
plt.imshow(img_rgb)
plt.show()

 

 

 

Annotation xml 파일에 있는 요소들을 파싱하여 접근하기

 

● ElementTree를 이용하여 XML 파싱(|xml 패키지는 이미 코랩에 설치되어 있음)

 

# !pip install lxml
import os
import xml.etree.ElementTree as ET

xml_file = os.path.join(ANNO_DIR, '2007_000032.xml')

# XML 파일을 Parsing 하여 Element 생성
tree = ET.parse(xml_file) #노드 단위로 조각조각 낸 후
root = tree.getroot() #가장 뿌리에 있는 <annotation> 노드를 root에 할당하기

# image 관련 정보는 root의 자식으로 존재
image_name = root.find('filename').text #root = <annotation> 노드 밑에 <filename>노드를 찾은 후 
#<filename>2007_000032.jpg</filename> 여기서 2007_000032.jpg(=text)만 뽑아내
full_image_name = os.path.join(IMAGE_DIR, image_name)
image_size = root.find('size')
image_width = int(image_size.find('width').text) #<width>500</width> 에서 500만 뽑아낸 후 아직 문자형이니 int로 숫자형으로
image_height = int(image_size.find('height').text)

# 파일내에 있는 모든 object Element를 찾음.
objects_list = []
for obj in root.findall('object'):
    #object1에 대해
    # object element의 자식 element에서 bndbox를 찾음.
    xmlbox = obj.find('bndbox')
    '''
    <bndbox>
			<xmin>133</xmin>
			<ymin>88</ymin>
			<xmax>197</xmax>
			<ymax>123</ymax>
		</bndbox>
    '''
    # bndbox element의 자식 element에서 xmin,ymin,xmax,ymax를 찾고 이의 값(text)를 추출
    x1 = int(xmlbox.find('xmin').text) #<xmin>133</xmin> 에서 133만 추출 -> 숫자화
    y1 = int(xmlbox.find('ymin').text)
    x2 = int(xmlbox.find('xmax').text)
    y2 = int(xmlbox.find('ymax').text)

    bndbox_pos = (x1, y1, x2, y2) #(133, 88, 197, 123)
    class_name=obj.find('name').text #<name>aeroplane</name> 에서 aeroplane만 추출
    object_dict={'class_name': class_name, 'bndbox_pos':bndbox_pos}
    # {'class_name': 'aeroplane', 'bndbox_pos':(133, 88, 197, 123)}
    objects_list.append(object_dict)

print('full_image_name:', full_image_name,'\n', 'image_size:', (image_width, image_height))

for object in objects_list:
    print(object)

 

 

Annotation내의 Object들의 bounding box 정보를 이용하여 Bounding box 시각화

 

import cv2
import os
import xml.etree.ElementTree as ET

xml_file = os.path.join(ANNO_DIR, '2007_000032.xml')

tree = ET.parse(xml_file)
root = tree.getroot()

image_name = root.find('filename').text
full_image_name = os.path.join(IMAGE_DIR, image_name)

img = cv2.imread(full_image_name)
# opencv의 rectangle()는 인자로 들어온 이미지 배열에 그대로 사각형을 그려주므로 별도의 이미지 배열에 그림 작업 수행.
draw_img = img.copy()
# OpenCV는 RGB가 아니라 BGR이므로 빨간색은 (0, 0, 255)
green_color=(0, 255, 0)
red_color=(0, 0, 255)

# 파일내에 있는 모든 object Element를 찾음.
objects_list = []
for obj in root.findall('object'):
    xmlbox = obj.find('bndbox')

    left = int(xmlbox.find('xmin').text)
    top = int(xmlbox.find('ymin').text)
    right = int(xmlbox.find('xmax').text)
    bottom = int(xmlbox.find('ymax').text)

    class_name=obj.find('name').text

    # draw_img 배열의 좌상단 우하단 좌표에 녹색으로 box 표시
    cv2.rectangle(draw_img, (left, top), (right, bottom), color=green_color, thickness=1)
    # draw_img 배열의 좌상단 좌표에 빨간색으로 클래스명 표시
    cv2.putText(draw_img, class_name, (left, top - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.4, red_color, thickness=1)
    # 0.4: 텍스트의 크기를 지정
img_rgb = cv2.cvtColor(draw_img, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10, 10))
plt.imshow(img_rgb)

 

 

 

 

Reference

 

https://www.inflearn.com/course/딥러닝-컴퓨터비전-완벽가이드/dashboard