본문 바로가기
딥러닝관련/Detection

SSD(single shot detector) 코드 분석 1. (data)

by 머리올리자 2022. 6. 4.

아래 SSD 코드를 보고 필요한 내용 개인적으로 기록

https://github.com/lufficc/SSD

 

GitHub - lufficc/SSD: High quality, fast, modular reference implementation of SSD in PyTorch

High quality, fast, modular reference implementation of SSD in PyTorch - GitHub - lufficc/SSD: High quality, fast, modular reference implementation of SSD in PyTorch

github.com

 

PASCAL VOC data

 

training data : PASCAL VOC 2007 & 2012

testing data : PASCAL VOC 2007 

 

PASCAL 데이터셋을 압축 받고 풀면

 

VOC2007\ImageSets\Main 폴더에 "trainval.txt"라는 파일이 있으며 데이터에 대한 파일명이 아래와 같이 나열되어 있다.

(추가적으로 폴더 안에 train_test,  train_train, train_trainval, train_val 이런 파일들도 존재하는데 정확한 용도는 나중에 찾아봐야겠다.)

 

__getitem__

    def _get_annotation(self, image_id):
        annotation_file = os.path.join(self.data_dir, "Annotations", "%s.xml" % image_id)
        objects = ET.parse(annotation_file).findall("object")
        boxes = []
        labels = []
        is_difficult = []
        for obj in objects:
            class_name = obj.find('name').text.lower().strip()
            bbox = obj.find('bndbox')
            # VOC dataset format follows Matlab, in which indexes start from 0
            # The index uses 1-based counting, and Scala is 0-based, so we’ll subtract 1 from the x and y position when we parse the bndbox.
            x1 = float(bbox.find('xmin').text) - 1
            y1 = float(bbox.find('ymin').text) - 1
            x2 = float(bbox.find('xmax').text) - 1
            y2 = float(bbox.find('ymax').text) - 1
            boxes.append([x1, y1, x2, y2])
            labels.append(self.class_dict[class_name])
            is_difficult_str = obj.find('difficult').text
            is_difficult.append(int(is_difficult_str) if is_difficult_str else 0)

        return (np.array(boxes, dtype=np.float32),
                np.array(labels, dtype=np.int64),
                np.array(is_difficult, dtype=np.uint8))

 

위 코드를 보면 annotation의 정보를 가져온다.

 

현재 image_id가 009133이라고 해보자

 

그러면 annotation_file은 아래와 같은 파일이며

(VOC2007/Annotations/009133.xml)

 

해당하는 이미지는 아래와 같다.

(VOC2007/JPEGImages/009133.jpg)

Element tree의 라이브러리를 이용하여 object의 정보를 얻고 순서대로

classname

x1, y1, x2, y2의 정보를 얻는다.

 

여기서 특이한 점은 좌표 정보에 -1을 해줬는데 주석에 따르면 이는

index가 1-based counting이기 때문에 1을 빼줌으로써 0-based counting으로 맞춰줘야 한다고 한다.

(확실히 1-based counting인지 이 부분은 나중에 추가로 확인해봐야겠다.)

 

또한 코드를 보면 difficult의 항목이 있는데 그 예시를 보면

(VOC 2012 : 2008_006761)

<annotation>
	<folder>VOC2012</folder>
	<filename>2008_006761.jpg</filename>
	<source>
		<database>The VOC2008 Database</database>
		<annotation>PASCAL VOC2008</annotation>
		<image>flickr</image>
	</source>
	<size>
		<width>500</width>
		<height>375</height>
		<depth>3</depth>
	</size>
	<segmented>0</segmented>
	<object>
		<name>aeroplane</name>
		<pose>Frontal</pose>
		<truncated>1</truncated>
		<occluded>1</occluded>
		<bndbox>
			<xmin>1</xmin>
			<ymin>39</ymin>
			<xmax>500</xmax>
			<ymax>349</ymax>
		</bndbox>
		<difficult>0</difficult>
	</object>
	<object>
		<name>person</name>
		<pose>Right</pose>
		<truncated>0</truncated>
		<occluded>0</occluded>
		<bndbox>
			<xmin>89</xmin>
			<ymin>218</ymin>
			<xmax>111</xmax>
			<ymax>267</ymax>
		</bndbox>
		<difficult>1</difficult>
	</object>
	<object>
		<name>person</name>
		<pose>Frontal</pose>
		<truncated>0</truncated>
		<occluded>0</occluded>
		<bndbox>
			<xmin>46</xmin>
			<ymin>204</ymin>
			<xmax>53</xmax>
			<ymax>230</ymax>
		</bndbox>
		<difficult>1</difficult>
	</object>
	<object>
		<name>person</name>
		<pose>Unspecified</pose>
		<truncated>1</truncated>
		<occluded>0</occluded>
		<bndbox>
			<xmin>147</xmin>
			<ymin>242</ymin>
			<xmax>168</xmax>
			<ymax>269</ymax>
		</bndbox>
		<difficult>1</difficult>
	</object>
</annotation>

위 이미지의 사람과 같이 물체의 크기가 작아서 찾기 어려운 경우에 difficult를 1(True)로 설정한듯 하다.