영상 1개당 순차적으로 5단계가 실행됩니다.
[영상 1개]
│
├─ (1) ffmpeg — 핸들 UI 프레임 추출 → frames30_pts_steer/
├─ (2) ffmpeg — 속력 프레임 추출 → frames30_pts/
├─ (3) classify_sevenseg.py → _cls_result.csv
├─ (4) classify_steering.py → _steer_result.csv
└─ (5) export_speed_to_excel.py → _speed_time.xlsx
현재 구조: 같은 .mp4 파일을 서로 다른 영역으로 크롭하기 위해 ffmpeg 프로세스를 두 번 실행합니다.
개선 방안: ffmpeg의 split 필터를 사용하여 1회 디코딩 → 2개 출력 스트림으로 분기합니다.
ffmpeg -i video.mp4 \
-filter_complex "split=2[s1][s2]; \
[s1]crop=58:19:1017:945,fps=30[steer]; \
[s2]crop=iw*0.013:ih*0.05:iw*0.0235:ih*0.08,fps=30[speed]" \
-map "[steer]" frames_steer/img_%010d.png \
-map "[speed]" frames_speed/img_%010d.png예상 효과: 프레임 추출 시간 약 30~50% 단축
현재 구조: --overlay 활성화 시 모든 프레임(수천 장)을 PNG로 개별 저장합니다. PNG 기본 압축 레벨(6)은 CPU를 상당히 사용합니다.
개선 방안 1 — PNG 압축 레벨 낮추기 (즉시 적용 가능):
cv2.imwrite(str(out_path), img, [cv2.IMWRITE_PNG_COMPRESSION, 1])파일 크기가 다소 늘어나지만, 저장 속도 20~30% 단축 가능
개선 방안 2 — 저장 작업 스레드 병렬화:
from concurrent.futures import ThreadPoolExecutor
save_queue = [] # (path, img) 수집 후
with ThreadPoolExecutor(max_workers=4) as pool:
pool.map(lambda args: cv2.imwrite(args[0], args[1]), save_queue)현재 구조: 프레임을 한 장씩 순차 로딩 후 분석합니다.
for i, p in enumerate(paths):
img = cv2.imread(str(p)) # I/O 블로킹
result = _analyze_one(img) # CPU 연산개선 방안: 이미지 로딩을 비동기(스레드)로 미리 prefetch하면 I/O와 CPU 연산을 겹쳐서 실행할 수 있습니다.
from concurrent.futures import ThreadPoolExecutor
def load_img(p):
return cv2.imread(str(p))
with ThreadPoolExecutor(max_workers=4) as pool:
imgs = list(pool.map(load_img, paths))현재 구조: 영상 파일이 여러 개인 경우, 하나가 끝나야 다음 영상이 시작됩니다.
개선 방안: 영상 단위로 ProcessPoolExecutor 병렬 처리
from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor(max_workers=2) as pool:
pool.map(process_video_wrapper, videos)
⚠️ CPU/디스크 사용량이 급증할 수 있어max_workers=2~3이 안정적입니다.
| 우선순위 | 개선 방안 | 예상 효과 | 구현 난이도 |
|---|---|---|---|
| 🔴 1 | ffmpeg split 필터로 1회 실행 통합 |
추출 시간 ~50% 단축 | 중간 |
| 🟡 2 | PNG 압축 레벨 1로 낮추기 | 저장 시간 |
낮음 |
| 🟡 3 | 오버레이 저장 스레드 병렬화 | I/O 부하 감소 | 중간 |
| 🟡 4 | 이미지 로딩 prefetch 병렬화 | 分析 처리 시간 감소 | 중간 |
| 🟢 5 | 영상 단위 멀티프로세스 | 다수 영상 처리에 효과적 | 높음 |
코드를 변경하지 않고도 성능을 올릴 수 있는 방법:
--overlay옵션을 필요할 때만 사용 — 분석 자체와 오버레이 저장은 독립적이므로, 기본 분석 시에는 overlay 없이 실행하고 필요한 구간만 별도 재실행합니다.- 상태 변화 프레임만 저장하는 모드 추가 — L→N, N→R 등 전환이 일어나는 프레임만 저장하면 저장 파일 수를 대폭 줄일 수 있습니다.