사용한 코드들의 목록입니다.

데이터베이스 축약을 위한 랜덤 추출(Unused)

import shutil, random, os

dirpath = "/Users/taeyeong/Desktop/mp/dataset/dataset2"
destDirectory = "/Users/taeyeong/Desktop/mp/dataset/dataset2min"

filename = [i[:-4] for i in os.listdir(dirpath) if i[-3:] == "jpg"]

l = random.sample(filename, 440)

for fname in l:
    srcpath = os.path.join(dirpath, f"{fname}.jpg")
    srcpathj = os.path.join(dirpath, f"{fname}.json")
    despath = os.path.join(destDirectory, f"{fname}.jpg")
    despathj = os.path.join(destDirectory, f"{fname}.json")

    shutil.copyfile(srcpath, despath)
    shutil.copyfile(srcpathj, despathj)

동일 이름의 jpg와 json을 특정 수만큼 추출해서 다른 디렉터리로 복사한다.

검증용 데이터셋 라벨링

app.roboflow.com에서 검증용 ‘흔들린 사진’ 데이터셋 라벨링

이때, 자동 라벨링 코드를 이용해 기초 라벨링을 완료 후 오류가 있는지 검수 및 수정함.

# This code snippet requires installing these packages:
# roboflow autodistill autodistill_grounding_dino

import os
from urllib.request import urlretrieve
import roboflow
from autodistill_grounding_dino import GroundingDINO
from autodistill.detection import CaptionOntology

BATCH_ID = "0H7SZIAtpKZA45buqtJv"
BOX_THRESHOLD = 0.70
CAPTION_ONTOLOGY = {"cars": "cars"}
PROJECT_ID = "mp-col1p"
TEXT_THRESHOLD = 0.70
WORKSPACE_ID = "9cn8YyhONMOKpmA71GVo"
WORKSPACE_URL = "microp"

# Set Roboflow and Project
roboflow.login()
rf = roboflow.Roboflow(api_key="fIxh3sstt2ACw5G6pKY2")
project = rf.workspace(WORKSPACE_URL).project(PROJECT_ID)

# Setup Working Directory
WORK_DIR = os.path.join(os.getcwd(), WORKSPACE_URL, PROJECT_ID, BATCH_ID)
os.makedirs(os.path.join(WORK_DIR, "images"), exist_ok=True)

# Download and Label Images
records = [
    image
    for page in project.search_all(batch=True, batch_id=BATCH_ID, fields=["id"])
    for image in page
]
for image in records:
    image_url = f'<https://source.roboflow.com/{WORKSPACE_ID}/{image["id"]}/original.jpg>'
    urlretrieve(image_url, os.path.join(WORK_DIR, "images", image["id"] + ".jpg"))

model = GroundingDINO(
    ontology=CaptionOntology(CAPTION_ONTOLOGY),
    box_threshold=BOX_THRESHOLD,
    text_threshold=TEXT_THRESHOLD,
)
model.label(os.path.join(WORK_DIR, "images"), extension=".jpg")

# Upload Annotations
annotations_dir = os.path.join(WORK_DIR, "images_labeled")
for subdir in ["train", "valid"]:
    label_dir = os.path.join(annotations_dir, subdir, "labels")
    for image_record in records:
        annotation_path = os.path.join(label_dir, image_record["id"] + ".txt")
        if os.path.exists(annotation_path):
            print(
                project.single_upload(
                    image_id=image_record["id"], annotation_path=annotation_path
                )
            )

이후 라벨링한 결과를 YOLO Text로 export하여 모델 튜닝에 활용하였음.

Blurring

모델 훈련에 이용되는 사진에 블러 처리를 하기 위해 아래와 같은 코드를 활용해 블러 처리함.

ref: https://stackoverflow.com/questions/40817634/opencv-how-to-add-artificial-smudge-motion-blur-effects-to-a-whole-image

import cv2
import os
import random
import numpy as np
from wand.image import Image

A = 30 # 각도 +- 편차 설정
L = 40 # 흐림 길이 (강도) 설정

def filter1(l, angle=15, length=20):
    cv2.imwrite(
        f"dataset/ellipse_{A}_{L}/images/{l}",
        filter1_in(
            cv2.imread(f"dataset/train/images/{l}"),
            length,
            angle,
        ),
    )

def filter1_in(img, length, angle):  # 타원 중첩 흐림 효과
    filt = np.zeros((50, 50, 3))
    filt = cv2.ellipse(
        psf,
        (25, 25),
        (length, 0),
        angle,
        0,
        360, 
        (1, 1, 1),
        thickness=-1,
    )
    filt /= filt[:, :, 0].sum()
    return cv2.filter2D(img, -1, filt)

def filter2(l, angle=15, length=20):  # 커널 적용한 가우시안 블러
    with Image(filename=f"dataset/train/images/{l}") as img:
        img.motion_blur(radius=16, sigma=length, angle=angle)
        img.save(filename=f"dataset/gauss_{A}_{L}/images/{l}")

for i in os.listdir("dataset/train/images"):
    ang = random.randint(-A, A)
    print(f"Processing {i}... Param: angle: {ang}, length: {L}")
    filter1(i, ang, L)
    filter2(i, ang, L)

YOLO 실행 Code