본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 29. 05:30

선반에서 도로까지: Raspberry Pi 5와 YOLOv8을 사용하여 와이드스크린 AI 블랙박스(Dashcam)를 구축하는 방법

요약

Raspberry Pi 5와 YOLOv8을 활용하여 실시간 객체 추적이 가능한 와이드스크린 AI 블랙박스를 구축하는 엔지니어링 가이드입니다. 하드웨어 선정부터 멀티스레딩 아키텍처 설계, 엣지 AI 통합 및 디버깅 과정을 상세히 다룹니다.

핵심 포인트

  • Raspberry Pi 5와 YOLOv8 Nano를 이용한 엣지 컴퓨팅 구현
  • 캡처, 추론, 서버 레이어를 격리한 3-트랙 멀티스레딩 아키텍처 설계
  • PiSP 포맷 및 시스템 리소스 잠금 문제 등 하드웨어 디버깅 노하우
  • 실시간 머신 비전 구현을 위한 최적화된 데이터 스트림 생성

서문
매일 전 세계의 작업실 선반 위에는 수천 개의 창의적인 아이디어들이 완전히 잠든 채 놓여 있습니다. 고성능 마이크로프로세서(microprocessor)는 정전기 방지 봉투 안에 들어 있고, 뛰어난 카메라 렌즈는 판지 상자 안에서 얇은 먼지 층을 쌓아가고 있으며, 몇 가닥의 점퍼 와이어(jumper wires)는 서랍 속에서 엉켜 있습니다. 우리는 그것들을 바라보며 생각합니다. “언젠가, 저것들로 놀라운 무언가를 만들어낼 거야.”

이 책은 그 "언젠가"에 대한 이야기입니다.

열정적인 두 창작자 사이의 가벼운 대화로 시작된 것은 빠르게 엄격한 엔지니어링 여정으로 진화했습니다. 우리의 과제는 단순하지만 매우 야심 찼습니다. 이미 선반에 가지고 있는 부품들을 사용하여 진정한 와이드스크린, 엣지 컴퓨팅(edge-computing) AI 블랙박스(Dashcam)를 구축하는 것이었습니다. 우리는 대량 생산된 하드웨어의 폐쇄적인 생태계에서 벗어나, 장치 자체에서 실시간 머신 비전(machine vision) 객체 추적(object tracking)이 가능한 모듈형의 스레드 안전(thread-safe) 플랫폼을 구축하고자 했습니다.

엔지니어링은 문제에서 해결책으로 가는 직선인 경우가 드뭅니다. 그것은 전략적 타협, 심도 있는 트러블슈팅(troubleshooting) 세션, 그리고 절대적인 명확함이 찾아오는 순간들의 연속입니다. 이어지는 장들에서 우리는 우리의 전체 프로세스를 공개합니다. 우리의 조달 전략, 아키텍처(architectural) 전환, 잠긴 리소스(locked resources)에 대한 좌절, 그리고 최악의 시각적 버그를 해결해 준 간단한 수학적 트릭들을 공유합니다.

우리는 호기심 많은 학생, 주말 메이커(makers), 그리고 업계 전문가 모두가 쉽게 접근할 수 있도록 의도적으로 이 가이드를 작성했습니다. 우리의 목표는 단순히 기능적인 코드를 제공하는 것이 아니라, 오픈 소스(open-source)를 만지는 철학, 지속 가능한 제품 선택, 그리고 복잡한 프로젝트를 한 걸음씩 앞으로 나아가게 하는 전염성 있는 추진력을 공유하는 것입니다.

페이지를 넘기고, 작업대를 정리하고, 함께 멋진 무언가를 만들어 봅시다.

— 개발 팀

차례
제1장: 인벤토리 감사 전략
1.1 선반 소싱 조달 마인드셋

1.2 핵심 스택 평가: Raspberry Pi 5 및 IMX219 렌즈

1.3 프로토타이핑 오버헤드 제로화 (Lowering Prototyping Overhead to Zero)

제2장: 구조적 아키텍처 및 멀티스레딩으로의 전환 (Structural Architecture & The Multithreaded Shift)
2.1 고성능 시스템에서 선형 스크립팅 (Linear Scripting)이 실패하는 이유

2.2 결합도가 낮고 스레드 안전한 (Thread-Safe) 공유 상태 설계

2.3 3-트랙 엔진 (Tri-Track Engine): 캡처, 추론 (Inference), 서버 레이어의 격리

제3장: 샌드박스에서의 기록: 하드웨어 장애물 극복하기 (Chronicles from the Sandbox: Overcoming Hardware Hurdles)
3.1 '장치 또는 리소스가 사용 중' (Device or resource busy) 시스템 잠금 현상 디버깅

3.2 "블루 룸" (Blue Room) 수수께끼: PiSP 포맷 요구 사항의 이해

3.3 NumPy 채널 반전 (Channel Reversal): 오버헤드 없이 색상 반전 배열 버그 해결하기

제4장: 엣지 AI 통합 및 실시간 컴퓨터 비전 (Edge AI Integration & Real-Time Computer Vision)
4.1 로컬 제약 사항에 맞춘 Ultralytics YOLOv8 (Nano) 컴파일

4.2 도로 상황을 위한 타겟 클래스 필터링 (Target-Class Filtering) 구축

4.3 멀티파트 MJPEG 라이브 방송 데이터 스트림 생성

제5장: 앞으로의 행보: 자동화 로드맵 (Marching Forward: The Automation Roadmap)
5.1 모터 구동 팬-틸트 마운트 (Pan-Tilt Mounts)를 위한 I2C 레지스터 명령 구조 설계

5.2 사고 분석을 위한 15초 롤링 RAM 링 버퍼 (Ring Buffer) 구축

5.3 결론: 오픈 하드웨어의 무한한 잠재력

다음은 우리의 엔지니어링 로드맵을 바탕으로 상세히 기술된 장별 도서 콘텐츠입니다. 이는 메이커, 학생, 그리고 시스템 아키텍트 모두를 위한 종합 가이드로서 Dev.to에 게시될 준비가 되었습니다.

제1장: 인벤토리 감사 전략 (The Inventory Auditing Strategy)

1.1 선반 소싱 조달 마인드셋 (The Shelf-Sourced Procurement Mindset)

현대적인 제품 개발에서 문제는 흔히 돈을 투입하여 해결하려는 본능으로 이어집니다. 새로운 프로젝트 컨셉이 등장하면, 우리는 즉시 전문적이고 니치한 부품을 찾기 위해 온라인 소매점을 검색합니다. 하지만 진정한 엔지니어링의 독창성은 의도적인 제약 조건 아래에서 꽃을 피웁니다.

선반에서 조달하는 사고방식은 당신의 작업실을 보물찾기 장소로 바꿉니다. 이는 당신이 기존의 부품 보관함을 단순히 남겨진 고철의 집합체가 아니라, 아직 활용되지 않은 잠재력을 가진 활성 재고로 바라보도록 도전 과제를 던집니다. 이러한 접근 방식은 상업적 판매업자가 제공하는 패키지 솔루션에 의존하는 대신, 이미 소유하고 있는 것들의 근본적인 역량을 이해하도록 강제합니다.

1.2 핵심 스택 평가: Raspberry Pi 5 및 IMX219 렌즈

사용 가능한 재고를 뒤져본 결과, 우리는 강력한 조합을 찾아냈습니다: 바로 Raspberry Pi 5와 IMX219 광각 카메라 렌즈 모듈입니다.

Raspberry Pi 5는 엣지 컴퓨팅 (Edge Computing) 분야에서 거대한 도약입니다. 이전 모델들과 달리, 이 제품은 **PiSP (Raspberry Pi Image Signal Processor)**를 탑재하고 있습니다. 이는 메인 CPU에 과부하를 주지 않으면서도 무거운 비디오 처리, 부동 소수점 연산 (Floating-point math), 그리고 빠른 이미지 데이터 포맷팅을 처리하도록 설계된 전용 하드웨어 파이프라인입니다. 이 처리 능력과 광각 렌즈를 결합함으로써, 우리는 높은 프레임 레이트 (High-frame-rate)를 가진 지능형 블랙박스 (Dashcam) 엔진을 위한 완벽한 물리적 플랫폼을 확보할 수 있었습니다.

1.3 프로토타이핑 오버헤드를 제로로 낮추기

이미 소유하고 있는 하드웨어 부품만을 중심으로 설계하기로 결정함으로써, 우리는 즉각적인 엔지니어링 승리를 거두었습니다. 바로 재무적 조달 오버헤드 (Procurement overhead)를 정확히 0달러로 낮춘 것입니다.

이러한 재정적 자유는 프로젝트의 정서적 역학을 변화시킵니다. 프로토타이핑에 비용이 들 때, 실수는 값비싼 실패로 느껴집니다. 하지만 프로토타이핑이 선반 위의 부품에 의존할 때, 모든 실수나 시스템 충돌, 혹은 단락 (Short circuit)은 비용이 들지 않는 학습 기회로 변모합니다. 우리는 회계 장부에 얽매이지 않고 마음껏 실험하고, 망가뜨리고, 다시 구축할 수 있는 완전한 자유를 얻었습니다.

제2장: 구조적 아키텍처 및 멀티스레드 전환

2.1 고성능 시스템에서 선형 스크립팅이 실패하는 이유

아마추어 개발자나 학생들이 컴퓨터 비전 (Computer Vision)에 처음 접근할 때, 보통 선형 스크립트 (linear script)를 작성합니다. 단순한 while True 루프가 프레임을 가져오고, 객체 탐지 (Object Detection) 모델을 실행하며, 화면에 박스를 그리고, 해당 이미지를 웹 브라우저로 전송하는 방식입니다.

이러한 선형적 접근 방식은 성능의 함정입니다. 비디오의 단일 프레임을 캡처하는 데 5밀리초 (ms), AI 모델이 분석하는 데 45밀리초, 스트리밍하는 데 10밀리초가 걸릴 수 있습니다. 선형 시퀀스에서는 AI가 생각하는 동안 카메라가 강제로 멈춰서 기다려야 합니다. 이는 엄청난 끊김 현상을 유발하고, 프레임 레이트 (Frame Rate)를 매우 느리게 만들며, 블랙박스 (Dashcam)와 같은 실시간 애플리케이션을 실제 도로 위에서 완전히 무용지물로 만듭니다.

2.2 디커플링된 스레드 안전 공유 상태 (Decoupled, Thread-Safe Shared State) 설계

높은 응답성을 가진 시스템을 구축하기 위해, 우리는 보는 행위와 생각하는 행위를 완전히 분리해야 했습니다. 우리는 중앙의 스레드 안전 (Thread-safe) 메모리 저장 컨테이너인 ServerState를 중심으로 하는 아키텍처를 설계했습니다.

class ServerState:
    def __init__(self):
        self.camera_driver = None
...

이미지 행렬 (Image Matrices)을 threading.Lock()으로 감싸줌으로써, 코드의 여러 독립된 부분들이 하위 소프트웨어 메모리 레지스터를 충돌시키지 않고 동시에 현재 프레임에 접근하고, 복사하고, 수정할 수 있습니다.

2.3 삼중 트랙 엔진 (The Tri-Track Engine): 캡처, 추론 및 서버 레이어의 격리

스레드 안전한 공유 상태를 갖춘 상태에서, 우리는 애플리케이션을 동시에 실행되는 세 개의 독립적이고 병렬적인 트랙으로 분리했습니다:

  • 캡처 스레드 (The Capture Thread): 이 워커 루프 (worker loop)는 카메라 하드웨어와 직접 통신하는 역할만 수행합니다. 초당 20 FPS 이상의 엄청난 속도로 프레임을 가져오며, 우리의 공유 상태 (shared state)를 즉각적으로 업데이트합니다.
  • 추론 스레드 (The Inference Thread): 완전히 독립적인 클록 (clock)에 따라 실행되는 이 스레드는 공유 상태를 확인하고, 최신 원본 프레임의 복사본을 가져와 객체 추적 (object tracking)을 위해 신경망 (neural network)에 전달한 뒤, 주석이 달린 (annotated) 결과를 저장합니다.
  • 서버 스레드 (The Server Thread (FastAPI)): 비동기 엔진 (asynchronous engine)에 의해 구동되는 이 레이어는 요청이 있을 때마다 네트워크를 통해 연결된 모든 대시보드 브라우저로 라이브 비디오 방송을 스트리밍합니다.

만약 AI 스레드가 매우 복잡한 교차로를 만나 장면을 처리하는 데 몇 밀리초(ms)가 더 소요되더라도, 비디오 캡처 루프는 절대 느려지지 않습니다. 카메라는 계속해서 부드럽게 녹화됩니다.

제3장: 샌드박스에서의 기록: 하드웨어 장애물 극복하기

3.1 Device or resource busy 시스템 차단의 디버깅

가장 좌절스러웠던 문제 중 하나는 신속한 배포 테스트 중에 발생했습니다. 코드를 수정하고 서버를 실행하면 즉시 다음과 같은 무시무시한 시스템 로그의 벽에 부딪히곤 했습니다:

ERROR V4L2 v4l2_device.cpp:412 'imx219': Unable to set controls: Device or resource busy
INFO Camera camera.cpp:1021 Pipeline handler in use by another process

우리는 개발자가 빠른 일시 중단 동작(Ctrl + Z)을 사용하여 실행 중인 터미널 프로세스를 종료할 때, 리눅스 (Linux)가 실제로 애플리케이션을 종료하는 것이 아니라 단순히 백그라운드에서 잠자기 상태로 만든다는 사실을 발견했습니다. 백그라운드 프로세스는 카메라 렌즈에 대한 열린 하드웨어 소켓을 완고하게 유지합니다. 해결책은 프로세스 관리 (process management)에 대한 빠른 교훈이었습니다. sudo killall -9 python을 실행하면 모든 유령 프로세스 (ghost processes)를 체계적으로 정리하고 다음 실행을 위해 하드웨어 레지스터 (hardware registers)를 깔끔하게 잠금 해제할 수 있습니다.

3.2 "블루 룸"의 수수께끼: PiSP 포맷 요구 사항 이해하기

리소스 잠금을 우회하자마자 우리는 다음 시각적 놀라움에 직면했습니다. 카메라가 켜지긴 했지만, 실험실 환경 전체가 완전히 잘못되어 보였습니다. 빨간색 물체는 짙은 파란색으로 빛났고, 파란색 물체는 이상한 노란색-빨간색 색조로 렌더링되었습니다.

이 문제는 현대적인 Raspberry Pi 5 하드웨어 아키텍처(architecture) 내에 존재합니다. 표준 카메라 설정은 종종 표준 BGR24 포맷 배열을 요청합니다. 하지만 Pi 5의 하드웨어 파이프라인 (PiSP)은 RGB888 레이아웃 구성(layout configuration)을 사용하여 데이터 스트림을 네이티브하게 처리합니다. 하드웨어 프로세서를 예상하지 못한 포맷으로 강제하면서 색 공간(color spaces)이 충돌했고, 이로 인해 실시간 환경 피드가 반전된 색상의 환상적인 모습으로 변해버렸습니다.

3.3 NumPy 채널 반전: 오버헤드 없이 색상 반전 배열 버그 해결하기

많은 개발자가 cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)와 같은 무거운 이미지 변환 도구를 실행하여 색상 왜곡을 수정하려고 시도합니다. 이 방법이 작동은 하지만, 초당 수십 번씩 고해상도 와이드스크린 프레임에 구조적 변환 작업을 실행하는 것은 엣지(edge) 환경의 귀중한 CPU 사이클을 낭비합니다.

대신, 우리는 네이티브 Python 배열 슬라이싱(array slicing)을 사용하여 오버헤드가 전혀 없는(zero-overhead) 영리한 트릭을 구현했습니다:

# NumPy 배열 미러 스왑 (Mirror Swap)
bgr_frame = raw_frame[:, :, ::-1]

Python에서 이미지 프레임은 다차원 NumPy 배열로 표현되기 때문에, 슬라이스 구문 ::-1은 컴퓨터에게 세 번째 차원(색상 채널)을 완전히 역순으로 읽으라고 지시합니다. 이는 실제 소프트웨어 계산을 수행하지 않고 메모리 포인터(memory pointers)를 사용하여 레이아웃을 [Red, Green, Blue]에서 [Blue, Green, Red]로 즉시 뒤집습니다. 파란색 색조는 완전히 사라졌고, 결점 없는 실제 색상이 드러났습니다.

4장: 엣지 AI 통합 및 실시간 컴퓨터 비전

4.1 로컬 제약 조건을 위한 Ultralytics YOLOv8 (Nano) 컴파일

안정적인 와이드스크린 비디오가 확보됨에 따라, 우리는 **Ultralytics YOLOv8 (Nano)**를 사용하여 컴퓨터 비전 레이어를 통합했습니다.

Raspberry Pi와 같은 임베디드 장치(embedded device)에 머신러닝 (ML) 모델을 배포할 때는 모델 크기의 선택이 전부입니다. 데이터 센터 서버를 위해 설계된 수 기가바이트 규모의 거대한 AI 모델은 소형 컴퓨터를 멈춰버리게 만들 것입니다. Nano (yolov8n.pt) 모델 설정은 활성 블랙박스 (dashcam) 엔진을 위한 완벽한 최적점 (sweet spot)을 제공합니다. 이 모델은 가벼운 RAM 점유율을 유지하면서도, Pi 5의 아키텍처 (architecture)를 활용하여 밀리초 단위로 복잡한 환경을 스캔합니다.

4.2 도로 주행을 위한 타겟 클래스 필터링 (Target-Class Filtering) 구축

표준 AI 비전 모델은 실내 식물, 휴대폰, 커피컵을 포함한 80가지의 서로 다른 일상적인 항목을 인식하도록 학습됩니다. 지능형 주행 보조 장치에게 이러한 데이터를 모두 분석하는 것은 처리 에너지의 낭비입니다.

우리는 명시적인 타겟 클래스 필터링 (target-class filtering)을 사용하도록 추론 루프 (inference loop)를 구성했습니다:

# 표준 교통 및 안전 도로 위험 요소에만 집중
results = self.yolo_model(raw_frame, verbose=False, classes=[0, 2, 3, 5, 7, 9])

0 (보행자), 2 (자동차), 3 (오토바이), 5 (버스), 7 (트럭), 9 (신호등)와 같이 엄격하게 제한된 클래스 배열을 전달함으로써, 신경망 (neural network)이 배경의 잡음은 완전히 무시하고 교통 객체에만 전적으로 집중하도록 설정했습니다.

4.3 멀티 파트 MJPEG 라이브 방송 데이터 스트림 생성

AI의 실시간 추론 과정을 운전자의 화면에 노출하기 위해, 우리는 효율적이고 범용적인 스트리밍 프로토콜 (streaming protocol)인 FastAPI 기반의 **MJPEG (Motion JPEG)**를 채택했습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0