본문 바로가기

개발

YOLOv5 갖고 놀기

 python benchmarks.py --weights yolov5s.pt --img 640

 

라는 명령어를 돌리니 대충 돌아가는 것 처럼 보인다.

 

그러나 내가 진짜 원하는 동작을 수행해야 한다.

 

1.  내가 원하는 학습을 수행해야 한다.

2. 학습의 결과가 제대로 전시되어야한다.

3. tflite 모델로 출력이 나와야한다.(현재는 XX.pt) 확장자로 나오는것 같다.

 

최초로 예제 파일을 받아보면, 여러가지 파일이 있고 대체 뭐부터 봐야 할지 눈이 뒤집힐 지경이다.

배경지식 없이 개발을 하면 이런 문제가 간혹있는데, 어자피 퍼스트무버가 아니니 다른 사람의 레퍼런스를 참조해서 시간을 절약해보자.

 

1. 내가 원하는 학습을 수행하자.

이는 커스텀트레이닝(custom Training)이라고 하며, 하는 방식으로는 크게 두가지가 있다.

첫 번째는 누가 만들어 놓은 적절한 데이터셋을 다운로드 받아서 수행하는 방식이고,

두 번째는 내가 직접 데이터셋을 만드는 것이다.

두 번째 직접 데이터셋을 만들기 위해서는 학습 데이터에 대한 이해가 필요하다.

yolo를 학습하기 위한 데이터셋 형태는 다음과 같다.

1) 학습을 위한 이미지

2) 개별 이미지의 yolo 형식 annotation 텍스트

 

이 때 주의할점은 Annotation 파일들은 개별 이미지 파일과 같은 이름을 가져야 한다.

또한 이미지 폴더가 위치한 디렉토리 내의 /labels 폴더에 저장되어야 한다.

따라서 yolo 데이터들은 다음과 같은 구조로 저장되어야 한다.

 

yolo bounding box format은 다음과 같다.

 

지단 형님의 머리가 매력적인 사진이다. 

이미지에 좌표를 만드는 과정이 쉽진 않아 보인다.

bounding box는 [x, y, w, h] 형태이고 이는 이미지 크기를 0-1로 Normalize했을 때의 값이다.
또한 개별 annotation txt 파일은 다음과 같이 클래스(인덱스), x, y, w, h 형태로 쓰여 있어야 한다.

 

 

이건  annotation txt 파일을 열어본 결과로 ID가 45인 객체의 x,y 중심좌표와 바운딩 박스의 크기(좌우, 높이)를 Nomalizee 해서 저장한 값이다.

 

완전히 커스텀한 데이터셋을 만들기 위해서는 위 파일들을 만들어내야 한다.

 

여기 커스텀데이터셋을 만들기 위한 좋은 제작 툴이 있어 소개한다.

 

https://www.makesense.ai/

 

Make Sense

 

www.makesense.ai

 

#xml 형식을 yolo 형식으로 변환하기
#파일 경로는 다음과 같다고 가정하자.
#dataset
#ㄴ annotations (개별 xml 파일이 존재하는)
#ㄴ images (이미지 파일이 존재하는)
#ㄴ labels (새 yolo label이 들어갈 폴더)
# 경로를 지정해주자.

path = "./dataset"
annot_path = os.path.join(path,"annotations")
img_path = os.path.join(path,"images")
label_path = os.path.join(path,"labels")

import xml.etree.ElementTree as ET
import glob
import os
import json

# xml bbox 형식을 yolo bbox 형태로 변환하는 함수

def xml_to_yolo_bbox(bbox, w, h):
    # xmin, ymin, xmax, ymax
    x_center = ((bbox[2] + bbox[0]) / 2) / w
    y_center = ((bbox[3] + bbox[1]) / 2) / h
    width = (bbox[2] - bbox[0]) / w
    height = (bbox[3] - bbox[1]) / h
    return [x_center, y_center, width, height]
    
 classes = []

from tqdm import tqdm

files = glob.glob(os.path.join(annot_path, '*.xml'))
for fil in tqdm(files):
    
    basename = os.path.basename(fil)
    filename = os.path.splitext(basename)[0]
    
    result = []
    
    tree = ET.parse(fil)
    root = tree.getroot()
    width = int(root.find("size").find("width").text)
    height = int(root.find("size").find("height").text)
    for obj in root.findall('object'):
        label = obj.find("name").text
        if label not in classes:
            classes.append(label)
        index = classes.index(label)
        pil_bbox = [int(x.text) for x in obj.find("bndbox")]
        yolo_bbox = xml_to_yolo_bbox(pil_bbox, width, height)
        bbox_string = " ".join([str(x) for x in yolo_bbox])
        result.append(f"{index} {bbox_string}")
    if result:
        with open(os.path.join(label_path, f"{filename}.txt"), "w", encoding="utf-8") as f:
            f.write("\n".join(result))

 

첫 번째의 처음부터 yolo 전용으로 데이터셋을 구하는 사이트는 아래와 같다.

 

https://roboflow.com/

 

Roboflow: Give your software the power to see objects in images and video

Everything you need to build and deploy computer vision models.

roboflow.com

 

로보 플로우를 구경하는건 다음 포스팅에서 수행해보겠다.

728x90
반응형
LIST

'개발' 카테고리의 다른 글

GPT가 분석한 YOLOv5 Export.py  (0) 2024.01.15
YOLOv5: Export.py  (0) 2024.01.15
YOLOv5 처음 실행해보기  (0) 2024.01.12
YOLOv5 개발환경 구축하기  (0) 2024.01.12
YOLOv5 to tflite  (0) 2024.01.10