본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 05. 23. 23:39

고양이 두 마리를 구별하는 카메라 만들기 (1) ── Raspberry Pi 4 + Coral 환경 구축

요약

Raspberry Pi 4와 Coral USB Accelerator를 활용하여 고양이를 식별하고 녹화하는 AI 카메라 시스템 구축 과정을 다룹니다. 하드웨어 구성부터 OS 셋업, HDD를 루트 디스크로 설정하는 환경 구축 단계까지 상세히 설명합니다.

핵심 포인트

  • Raspberry Pi 4와 Coral USB Accelerator를 이용한 AI 환경 구축
  • Raspberry Pi OS Lite (Debian 13 기반) 설치 및 최적화 방법
  • SD 카드 수명 연장을 위한 HDD 루트 디스크 구성 가이드
  • Claude를 활용한 단계별 개발 프로세스 및 시행착오 공유

서론

Coral USB Accelerator의 용도를 고민하던 중, 고양이 두 마리 중 어느 쪽이 어떤 사료를 먹고 있는지 판별하여 녹화하는 시스템을 떠올렸습니다. 고양이의 식사 장소에는 사람의 발도 찍히기 때문에, 불필요한 프레임을 스킵하는 처리도 필요합니다.

최종적으로는 다음과 같은 구성이 됩니다.

Cat Monitor の Web UI

이 기사는 Claude와 채팅하며 절차를 구성한 내용을 기사화한 것입니다. AI가 출력한 절차를 그대로 전재하는 것이 아니라, 실제 기기에서 동작 확인을 하며 피드백을 주고 수정 과정을 거쳐, 최종적으로 동작한 구성만을 정리했습니다. 도중에 막혔던 부분도 "시행착오 메모"로 기재하였으므로, 같은 길을 걷는 분들에게 참고가 된다면 좋겠습니다.

참고로, Raspberry Pi 공식 HAT형 AI Accelerator (AI HAT+ 2 등)가 있지만, PCIe 연결 방식이기 때문에 Raspberry Pi 5 전용입니다. Coral USB Accelerator라면 USB 연결이므로 Raspberry Pi 4에서도 이용할 수 있습니다.

또한, Raspberry Pi AI Camera (IMX500 탑재)도 검토했으나, Pi 5용 설계라 Pi 4에서는 AI 기능을 충분히 활용할 수 없다는 이야기가 있어, 모델의 유연성을 우선하여 Coral USB를 선택했습니다.

시리즈 구성:

본 기사 (1): 환경 구축 (하드웨어, OS, Coral, Python 환경)

  • (2) 데이터 수집과 첫 번째 모델: 구현, 데이터 수집, Colab에서의 학습, 실전 운용
  • (3) 오판정을 수정하여 정밀도 향상: (추후 공개)
  • 번외편 Web App 코드 상세 해설

완성 이미지

기능내용
개체 식별카메라 영상에서 특정 고양이를 식별
...

하드웨어 구성

부품용도보충
Raspberry Pi 4 (8GB)본체4GB에서도 동작 가능
...

Raspberry Pi OS 셋업

사용한 OS 버전

Raspberry Pi OS Lite (64-bit)의 Trixie (Debian 13) 기반 버전을 사용했습니다. 집필 시점에서 공식적으로 제공되는 최신 버전입니다.

이전 버전 (Bookworm = Debian 12)을 사용할 경우, 시스템 Python이 3.11 또는 3.12가 되기 때문에, 본 기사의 절차 (시스템 Python 3.13에서 picamera2를 사용하는 전제)와 일부 다를 가능성이 있습니다.

OS 설치

Raspberry Pi Imager로 **Raspberry Pi OS (64-bit)**를 microSD에 씁니다. Lite 버전이든 Desktop 버전이든 상관없지만, 이번에는 Lite 버전 (콘솔 전용)으로 진행합니다.

쓰기 전에 톱니바퀴 아이콘을 통해 다음을 설정해 두면 편리합니다.

  • 호스트 이름
  • 사용자 이름·비밀번호
  • Wi-Fi
  • SSH 활성화

시스템 업데이트

sudo apt update && sudo apt upgrade -y

sudo 비밀번호 생략

빈번하게 sudo를 사용하므로 비밀번호 입력을 생략합니다.

sudo visudo -f /etc/sudoers.d/pi-nopasswd
pi ALL=(ALL) NOPASSWD: ALL

pi는 실제 사용자 이름으로 바꿔주세요.

HDD를 루트 디스크로 만들기

SD 카드는 쓰기 횟수가 많으면 열화되므로, 녹화 파일 등을 쓰는 곳은 HDD로 하고 싶지만, 이번에는 OS의 루트 디스크 자체를 HDD로 옮겨 SD 카드의 열화를 최소한으로 줄입니다.

파티션 생성

lsblk # 디바이스 이름 확인 (통상 /dev/sda)
sudo fdisk /dev/sda

fdisk 내에서 다음을 실행합니다.

g # GPT 파티션 테이블 생성
n # 신규 파티션
1 # 파티션 번호
...

포맷 및 UUID 확인

sudo mkfs.ext4 /dev/sda1
sudo blkid /dev/sda1
# UUID="a1b2c3d4-..." 를 메모

루트 파일 시스템 복사

sudo mkdir /mnt/hdd
sudo mount /dev/sda1 /mnt/hdd
sudo rsync -axv / /mnt/hdd/

용량에 따라 다르지만, 어느 정도 시간이 소요됩니다.

fstab 편집

sudo nano /mnt/hdd/etc/fstab

/ 행의 UUID를 HDD의 것으로 바꿔 씁니다. 다른 행(/boot/firmwareproc)은 변경할 필요가 없습니다.

UUID=<HDD의 UUID> / ext4 defaults,noatime 0 1
UUID=<원래의 bootUUID> /boot/firmware vfat defaults 0 2
proc /proc proc defaults 0 0

noatime을 추가하면 액세스 시간(access time) 기록이 생략되어 HDD의 부하를 줄일 수 있습니다.

cmdline.txt 편집 (스핀업(Spin-up) 대기 대책)

sudo nano /boot/firmware/cmdline.txt

root= 부분을 HDD의 UUID로 바꾸고, rootwait rootdelay=10을 추가합니다.

root=UUID=<HDD의 UUID> rootwait rootdelay=10
옵션역할
rootwait루트(root) 장치가 나타날 때까지 무기한 대기
rootdelay=10부팅을 10초 지연 (HDD의 스핀업(Spin-up) 대기)

systemd 타임아웃 조정

sudo nano /mnt/hdd/etc/systemd/system.conf
DefaultTimeoutStartSec=120s

재부팅 및 확인

sudo umount /mnt/hdd
sudo reboot
# 재부팅 후
...

HDD화 이후의 추가 설정

루트(root)를 HDD로 옮겼으므로, SD 카드 기준의 기본 설정을 재검토합니다.

swap 확장

Raspberry Pi OS의 기본 swap은 100MB입니다. 루트(root)가 HDD로 옮겨졌으므로 swap도 HDD 위에 생성됩니다. SD 카드와 달리 내구성을 걱정할 필요가 없으므로, 여유 있게 설정해 둡니다.

# 현재 swap 상태 확인
free -h
swapon --show

Lite 버전에는 dphys-swapfile이 설치되어 있지 않은 경우가 있으므로 설치합니다.

sudo apt install -y dphys-swapfile
sudo nano /etc/dphys-swapfile
CONF_SWAPSIZE=1024
sudo dphys-swapfile swapoff
sudo dphys-swapfile setup
sudo dphys-swapfile swapon
...

8GB라면 보통 충분하지만, AI 추론 중에는 tflite-runtime이나 OpenCV가 메모리를 사용하므로 swap이 있으면 안전합니다. HDD는 SD 카드와 달리 쓰기 내구성을 걱정할 필요가 없으므로, 여유 있게 설정해 둡니다.

tmpfs 확인

/tmp/run이 RAM 상(tmpfs)에 있는지 확인합니다.

mount | grep tmpfs

/tmp/runtmpfs로 표시되면 OK입니다. Raspberry Pi OS는 기본적으로 tmpfs가 설정되어 있으므로, 보통은 확인만 하면 됩니다.

HDD 스핀다운(Spin-down)은 설정하지 않음

장시간 액세스가 없을 때 HDD를 정지시키는 스핀다운(Spin-down) 설정이 있지만, 이번에는 설정이 필요 없습니다.

catmonitor 서비스가 카메라 루프를 통해 상시 동작하며 녹화 파일도 HDD에 쓰기 때문에, 실질적으로 HDD에 대한 액세스가 끊기지 않습니다. 스핀다운이 발생하더라도 즉시 스핀업(Spin-up)이 필요하게 되어, 오히려 모터에 가해지는 부하가 늘어납니다. 상시 가동되는 시스템에서는 스핀다운은 역효과입니다.

Coral USB Accelerator 셋업

EdgeTPU 런타임(Runtime) 설치

공식 문서의 절차는 오래되었으며, Bookworm 이후 버전에서는 apt-key가 폐지되었습니다. 새로운 서명 형식으로 진행합니다.

curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/coral-edgetpu-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/coral-edgetpu-archive-keyring.gpg] \
...

인식 확인

Coral USB를 USB 3.0 포트(가급적 셀프 파워 USB 허브 경유)에 연결하여 확인합니다.

lsusb
# "Global Unichip Corp." 또는 "Google Inc."가 표시되면 OK

lsusbの出力例

끝부분의 Global Unichip Corp.

행이 Coral USB Accelerator입니다. 초기화되지 않은 상태에서는 1a6e:089a,

추론을 한 번 실행한 후에는 18d1:9302 Google Inc.

로 표시가 바뀝니다.

Python 환경 구축

이 시스템은 두 개의 Python 환경을 구분하여 사용합니다.

용도Python이유
카메라 서버 (catcamera)시스템 3.13picamera2가 시스템에만 설치 가능하기 때문
추론·데이터 수집·각종 Web 앱venv 3.11tflite-runtime이 PyPI에 3.11용 wheel만 있기 때문

카메라와 추론 처리를 별도의 프로세스로 분리하고, MJPEG 스트림을 통해 프레임을 공유하는 설계입니다.

Python 3.11 소스 빌드

Raspberry Pi OS Trixie에는 python3.11 패키지가 없으므로, 소스에서 빌드합니다.

빌드 도구를 설치합니다.

sudo apt install -y build-essential zlib1g-dev libncurses5-dev \
libgdbm-dev libnss3-dev libssl-dev libreadline-dev \
libffi-dev libsqlite3-dev libcap-dev

소스를 다운로드하여 빌드합니다.

wget https://www.python.org/ftp/python/3.11.9/Python-3.11.9.tgz
tar xzf Python-3.11.9.tgz
cd Python-3.11.9
...

Raspberry Pi 4에서의 빌드는 30~60분이 소요됩니다. altinstall을 사용하여 시스템 표준 Python을 덮어쓰지 않도록 합니다.

python3.11 --version
# Python 3.11.9라고 표시되면 OK
# 공유 라이브러리가 보이는지 확인
...

시스템 Python 3.13용 패키지 설치

카메라 서버 (catcamera)는 시스템 Python 3.13에서 동작하므로, picamera2를 설치합니다.

sudo apt install -y python3-picamera2

확인합니다.

python3 -c "from picamera2 import Picamera2; print('ok')"
# → ok라고 표시되면 OK

uv 설치

3.11 측의 가상 환경과 패키지 관리에는 uv를 사용합니다. pip보다 빠르고 의존성 해결도 더 똑똑합니다.

curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env

프로젝트 구성 및 가상 환경

mkdir -p /home/pi/cat_project/{scripts,models,dataset,recordings,logs}
cd /home/pi/cat_project
uv venv --python python3.11
...

systemd 서비스는 User=pi로 동작하지만, sudo를 사용한 조작으로 디렉토리가 생성되면 root가 소유자가 되는 경우가 있습니다. 서비스 실행 전에 소유자(owner)를 확인해 두는 것이 안전합니다.

# 소유자가 pi인지 확인
ls -la /home/pi/cat_project/
# root인 경우 수정
...

라이브러리 설치

uv pip install "numpy<2" tflite-runtime opencv-python-headless pillow flask gdown imagehash

카메라 인식 확인

V1(OV5647)을 포함한 공식 카메라는 libcamera로 동작합니다.

# 카메라 인식 확인
rpicam-hello --list-cameras
# ov5647 [2592x1944]라고 표시되면 OK
...

ImageNet 표준 모델 다운로드

학습된 모델을 준비할 수 있을 때까지의 동작 확인용으로, Coral의 학습된 모델(ImageNet)을 다운로드해 둡니다. EdgeTPU 추론(Inference)이 동작하는지 확인하는 용도로 사용합니다.

cd /home/pi/cat_project/models
wget https://github.com/google-coral/edgetpu/raw/master/test_data/mobilenet_v2_1.0_224_quant_edgetpu.tflite
wget https://raw.githubusercontent.com/google-coral/edgetpu/master/test_data/imagenet_labels.txt

EdgeTPU 추론 동작 확인

tflite-runtime에서 libedgetpu 델리게이트(Delegate)를 불러와서, 다운로드한 모델로 추론할 수 있는지 확인합니다.

source /home/pi/cat_project/.venv/bin/activate
python -c "
import tflite_runtime.interpreter as tflite
...

Coral via tflite-runtime: OK라고 표시되면, EdgeTPU 추론이 동작하는 상태입니다.

Fan SHIM 설정

Pimoroni의 Fan SHIM을 사용하는 경우, 드라이버를 설치하지 않으면 팬이 항상 최대 속도로 회전합니다. CPU 온도에 따라 자동으로 ON/OFF 하도록 설정합니다.

라이브러리 설치

Fan SHIM 제어에는 GPIO 액세스가 필요하므로, 시스템 전체(venv 외부)에 설치합니다.

sudo apt install -y python3-rpi.gpio python3-pip git
pip install fanshim psutil --break-system-packages
# automatic.py를 사용하기 위해 리포지토리(Repository)를 클론
...

systemd 서비스 생성

sudo nano /etc/systemd/system/fanshim.service
[Unit]
Description=Fan SHIM Controller
After=local-fs.target
...
sudo systemctl daemon-reload
sudo systemctl enable fanshim
sudo systemctl start fanshim
...

온도 확인

# 현재 CPU 온도
vcgencmd measure_temp
# 2초마다 모니터링
...

온도 임계값(Threshold) 설정 방식

파라미터이유
--on-threshold65℃Pimoroni 권장값. AI 추론 중에도 안전 범위
--off-threshold55℃65℃에서 10℃ 내려가면 정지
--delay22초마다 온도 체크

Coral이 추론을 대신 수행하므로 CPU 온도는 그리 많이 올라가지 않지만, 데이터 수집 중이나 파일 전송 중 등 부하가 걸리는 상황도 있으므로 65/55℃가 적절합니다.

요약

여기까지 환경 구축이 완료되었습니다. 최종적인 디렉토리 구성은 다음과 같습니다.

cat_project/
├── .venv/ # uv의 가상 환경 (Python 3.11)
├── scripts/ # (다음 기사에서 배치)
...

다음 회차에서는 이 베이스 위에 「데이터 수집 (Data Collection) → 분류 (Sorting) → 학습 (Training) → 실운영 (Production)」을 구현해 나갈 예정입니다.

  • 다음 기사 (2) 데이터 수집과 첫 번째 모델
  • (3) 오판정을 수정하여 정밀도 향상하기: (추후 공개)
  • 번외편 Web App 코드 상세 해설

Discussion

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0