OpenCV 비전 실무17장 · Batch Processing 과 YOLO 데이터 준비5 / 21← 이전목차다음 →MetaContents

17장. Batch Processing 과 YOLO 데이터 준비

멈추지 않는 일괄 처리

택배 기사가 하루에 상자 백 개를 나른다고 해 봅시다. 어느 집이 문을 안 열어 줬다고 그날 배달을 모두 멈추지는 않습니다. "부재, 문 앞에 둠" 이라고 적고 다음 집으로 갑니다. 저녁에는 배달 기록을 보고 못 전한 상자만 다시 챙깁니다. 일괄 처리 프로그램도 이렇게 만들어야 합니다. 깨진 파일 하나 때문에 수백 장 처리가 멈추면 안 됩니다.

시도하기, 확인하기, 기록하기, 계속하기의 네 단계를 이은 흐름도

그림의 네 단계를 파일마다 되풀이합니다. 여기서 문을 두드려 보는 일이 try, 문이 열렸는지 보는 일이 None 확인, 배달 기록이 로그, 다음 집으로 가는 일이 continue 입니다. 1장 프로젝트에서도 깨진 파일을 "읽기 실패"로 적고 넘어갔습니다. 이 장에서는 실패의 이유를 나눠 적고 기록을 파일로 남깁니다.

실패의 갈래와 확인하는 법

실패생기는 까닭확인하는 법기록할 이유
빈 파일저장하다 끊김파일 크기 stat().st_size == 0빈 파일
깨진 파일내려받다 끊김cv2.imread 가 None읽기 실패
너무 작은 그림아이콘, 미리보기가로나 세로가 기준보다 작다너무 작음
저장 실패한글 경로, 디스크 가득cv2.imwrite 가 False저장 실패
뜻밖의 오류미처 생각 못 한 경우try / except 로 잡는다예외 이름

걸린 시간 재기

time.perf_counter() 는 아주 잘게 잰 지금 시각(초)을 돌려줍니다. perf 는 performance(성능)의 줄임입니다. 시작과 끝의 차이가 걸린 시간입니다. 걸린 시간은 컴퓨터마다, 같은 컴퓨터에서도 돌릴 때마다 조금씩 다릅니다.

Python
import time
from pathlib import Path
import cv2

def safe_read(path):
    """읽기에 성공하면 (그림, "성공"), 실패하면 (None, 이유) 를 돌려준다."""
    if path.stat().st_size == 0:
        return None, "빈 파일"
    img = cv2.imread(str(path))
    if img is None:
        return None, "읽기 실패"
    return img, "성공"

start = time.perf_counter()
for path in sorted(Path("ch17_inbox").glob("*.png")):
    try:
        img, status = safe_read(path)
    except Exception as e:          # 뜻밖의 오류도 이름만 적고 넘어간다
        img, status = None, type(e).__name__
    print(f"{path.name:12} {status}")
print("걸린 시간(초):", round(time.perf_counter() - start, 4))

except Exception as e 는 거의 모든 오류를 잡아 e 라는 이름에 담습니다. type(e).__name__ 은 그 오류의 갈래 이름(ValueError 같은)입니다. 깨진 파일을 읽을 때 터미널에 [ WARN:0@...] 나 libpng error 같은 글이 찍힐 수 있습니다. OpenCV 안쪽에서 찍는 알림이라 프로그램은 멈추지 않습니다.

주의할 점

  • except 로 오류를 잡았으면 반드시 기록에 남깁니다. 잡기만 하고 조용히 넘어가면 무엇이 빠졌는지 아무도 모릅니다.
  • 진행 표시([12/60] 같은 줄)는 너무 자주 찍으면 오히려 느려집니다. 몇 장마다 한 번씩 찍습니다.
← 이전 절17장 · 폴더와 경로 다루기다음 절 →17장 · 객체 탐지 데이터셋이란