17장. Batch Processing 과 YOLO 데이터 준비
폴더와 경로 다루기
도서관에서 책을 찾을 때는 서가 번호, 칸 번호, 책 이름을 차례로 따라갑니다. "3층 / 사진 서가 / 객체 탐지 입문" 처럼 적힌 주소가 있으면 누구라도 같은 책에 닿습니다. 파일의 경로도 이런 주소입니다. 파이썬의 pathlib 는 이 주소를 글자 덩어리가 아니라 "서가, 칸, 책 이름"을 따로 꺼낼 수 있는 물건으로 다루게 해 줍니다.
그림의 네 카드가 폴더를 다룰 때 가장 자주 쓰는 도구입니다. 여기서 서가를 훑으며 책을 찾는 일이 glob, 책을 번호순으로 꽂는 일이 sorted, 사진 책만 고르는 일이 확장자(suffix) 거르기, 새 서가를 들이는 일이 mkdir 입니다.
Path 로 꺼낼 수 있는 것
Path("ch17_raw/part_001.png") 에서 꺼낼 수 있는 값입니다.
| 쓰는 법 | 결과 | 뜻 |
|---|---|---|
p.name | part_001.png | 파일 이름 |
p.stem | part_001 | 확장자를 뗀 이름(stem, 줄기) |
p.suffix | .png | 확장자(suffix, 꼬리) |
p.parent | ch17_raw | 담고 있는 폴더(parent, 부모) |
p.parent / "x.txt" | ch17_raw/x.txt | / 로 경로를 잇는다 |
p.exists() | True | 실제로 있는지 |
폴더를 훑는 세 가지 방법
| 방법 | 찾는 범위 | 예 |
|---|---|---|
folder.iterdir() | 폴더 바로 안의 모든 항목(하위 폴더도 하나로) | 폴더에 무엇이 있나 볼 때 |
folder.glob("*.png") | 바로 안에서 무늬에 맞는 것 | 확장자가 정해져 있을 때 |
folder.rglob("*") | 하위 폴더까지 모두(r 은 recursive, 되풀이) | 폴더가 여러 겹일 때 |
from pathlib import Path
inbox = Path("ch17_inbox")
# glob 은 바로 안만, rglob 은 하위 폴더(old/)까지 찾는다
print([p.name for p in sorted(inbox.glob("*.png"))])
print([p.name for p in sorted(inbox.rglob("*.png"))])
# 확장자를 소문자로 바꿔 견주면 .PNG 같은 대문자도 잡힌다
IMAGE_EXT = {".png", ".jpg", ".jpeg"}
images = [p.name for p in sorted(inbox.rglob("*")) if p.suffix.lower() in IMAGE_EXT]
print(images)
# 결과 폴더 만들기: parents=True 는 중간 폴더까지, exist_ok=True 는 이미 있어도 괜찮다는 뜻
out = Path("out_ch17_demo") / "gray"
out.mkdir(parents=True, exist_ok=True)
print(out.exists())glob("*.png") 의 * 는 "아무 글자나 몇 개든"이라는 뜻입니다. .PNG 처럼 대문자로 끝나는 파일은 무늬에 따라 빠질 수 있어서, 넓게 찾은 뒤 suffix.lower() 로 거르는 쪽이 안전합니다.
주의할 점
glob이 돌려주는 차례는 정해져 있지 않습니다. 언제나sorted로 줄을 세워야 다시 돌려도 같은 차례가 나옵니다.- 결과 폴더는 원본 폴더 밖에 만듭니다. 결과를 원본 폴더 안에 쓰면 다음에
glob으로 훑을 때 결과물까지 다시 처리합니다.