Skip to main content
Summary

라즈베리파이에 눈과 귀를 달기

지금까지는 라즈베리파이가 센서 값을 읽고, LED나 부저 같은 장치를 제어하고, 웹 서버로 정보를 보여 주는 흐름을 익혔다. 이번 장에서는 여기에 카메라와 오디오 장치를 더한다. 카메라는 라즈베리파이에 "눈"을 달아 주고, 마이크와 스피커는 "귀"와 "입" 역할을 한다.

카메라 프로젝트는 결과가 바로 보인다는 장점이 있다. 명령어 하나로 사진 파일이 생기고, 짧은 코드로 일정 시간마다 장면을 기록할 수 있다. 움직임 센서를 연결하면 간단한 감시 장치도 만들 수 있다. 여기에 웹 서버나 파일 업로드를 붙이면 집 밖에서도 촬영 결과를 확인하는 구조로 확장된다.

이 장의 목표는 전문적인 CCTV를 만드는 것이 아니다. 사진 촬영, 영상 녹화, 자동 저장, 움직임 감지, 오디오 녹음의 기본 흐름을 이해하는 것이다. 작은 기능을 하나씩 붙이면 멀티미디어 IoT 프로젝트의 뼈대가 자연스럽게 보인다.

카메라와 멀티미디어 프로젝트AI 생성 이미지

카메라 연결은 전원을 끄고 천천히 한다

라즈베리파이 카메라 모듈은 보통 CSI 카메라 포트에 리본 케이블로 연결한다. 이 케이블은 얇고 방향이 중요하다. 연결할 때는 반드시 라즈베리파이 전원을 끈다. 전원이 들어온 상태에서 카메라 케이블을 꽂거나 빼면 카메라나 보드가 손상될 수 있다.

연결 순서는 단순하다.

  1. 라즈베리파이를 정상 종료한다.

  2. 전원 케이블을 뽑는다.

  3. 카메라 커넥터의 잠금 장치를 조심스럽게 연다.

  4. 리본 케이블의 금속 접점 방향을 확인해 끝까지 넣는다.

  5. 잠금 장치를 다시 닫는다.

  6. 카메라 모듈 쪽 케이블도 빠지지 않았는지 확인한다.

  7. 전원을 다시 연결해 부팅한다.

리본 케이블의 파란 보강판이나 금속 접점 방향은 보드 모델과 카메라 모듈에 따라 달라질 수 있다. 그래서 "항상 파란 면이 어느 쪽"이라고 외우기보다, 커넥터 안쪽 접점과 케이블의 금속 접점이 서로 맞닿는지 확인하는 습관이 안전하다. 케이블이 비스듬히 들어가거나 잠금 장치가 덜 닫히면 카메라가 인식되지 않는다.

최신 Raspberry Pi OS(Bookworm)에서는 예전 방식의 레거시 카메라 설정에 의존하지 않는 것이 좋다. 먼저 터미널에서 다음 명령으로 카메라가 정상 동작하는지 확인한다.1

rpicam-still -o image.jpg

미리보기 화면이 잠깐 나타나고 현재 폴더에 image.jpg가 저장되면 기본 연결은 성공이다. 이 단계에서 실패한다면 파이썬 코드를 고치기 전에 케이블 방향, 커넥터 잠금, 카메라 포트, OS 버전을 먼저 확인해야 한다.

명령어로 사진과 영상을 찍어 보기

카메라를 처음 사용할 때는 복잡한 코드보다 명령어가 좋다. 명령어는 문제가 하드웨어인지, 코드인지 빠르게 구분해 준다.

사진 촬영은 다음과 같이 실행한다.

rpicam-still -o test.jpg

-o는 출력 파일 이름을 지정하는 옵션이다. test.jpg 대신 원하는 이름을 넣을 수 있다.

영상 녹화는 다음처럼 실행할 수 있다.

rpicam-vid -t 10000 -o test.h264

여기서 -t 10000은 10000밀리초, 즉 10초 동안 녹화한다는 뜻이다. 결과 파일은 test.h264로 저장된다. H.264는 영상 압축 형식이다. 파일 크기를 줄이는 데 유리하지만, 재생 프로그램에 따라 바로 열리지 않을 수도 있다. 나중에 필요하면 ffmpeg 같은 도구로 MP4 형식으로 변환할 수 있다.

초보자는 촬영 파일을 한 폴더에 모아 두는 편이 좋다.

mkdir -p ~/camera-project/photos
cd ~/camera-project/photos
rpicam-still -o first.jpg

이렇게 하면 나중에 파일을 찾기 쉽고, 자동 촬영 프로젝트로 확장할 때도 정리하기 편하다.

Picamera2로 파이썬 촬영하기

명령어로 카메라가 확인되었다면 이제 파이썬에서 촬영해 보자. 최신 Raspberry Pi OS에서는 Picamera2가 기본적인 파이썬 카메라 도구로 사용된다. 예전 자료에 나오는 raspistill이나 옛 picamera 방식과 혼동하지 않는 것이 중요하다.1

다음 파일을 만든다.

mkdir -p ~/camera-project
cd ~/camera-project
nano take_photo.py

파일 내용은 다음과 같이 작성한다.

import time
from picamera2 import Picamera2

picam = Picamera2()
config = picam.create_still_configuration()
picam.configure(config)

picam.start()
time.sleep(2)
picam.capture_file("python-photo.jpg")
picam.close()

실행한다.

python3 take_photo.py

같은 폴더에 python-photo.jpg가 생기면 성공이다. 여기서 time.sleep(2)는 카메라가 빛과 초점을 안정적으로 잡을 시간을 주는 역할을 한다. 너무 급하게 촬영하면 첫 사진이 어둡거나 흐릿할 수 있다.

파일 이름을 매번 같게 쓰면 새 사진이 이전 사진을 덮어쓴다. 자동 기록 프로젝트에서는 날짜와 시간을 파일 이름에 넣는 편이 좋다.

from datetime import datetime
from picamera2 import Picamera2
import time

picam = Picamera2()
picam.configure(picam.create_still_configuration())
picam.start()
time.sleep(2)

now = datetime.now().strftime("%Y%m%d-%H%M%S")
filename = f"photo-{now}.jpg"
picam.capture_file(filename)

picam.close()
print(filename)

이제 파일 이름은 photo-20260522-143000.jpg처럼 만들어진다. 언제 찍은 사진인지 파일명만 봐도 알 수 있어 관리가 쉽다.

일정 시간마다 찍는 타임랩스 구조

타임랩스는 일정한 간격으로 사진을 찍어 변화를 기록하는 방식이다. 하늘 변화, 식물 성장, 작업 공간 변화처럼 천천히 바뀌는 장면을 관찰할 때 유용하다.

기본 구조는 반복문이다.

from datetime import datetime
from pathlib import Path
from picamera2 import Picamera2
import time

save_dir = Path("photos")
save_dir.mkdir(exist_ok=True)

picam = Picamera2()
picam.configure(picam.create_still_configuration())
picam.start()
time.sleep(2)

try:
    while True:
        now = datetime.now().strftime("%Y%m%d-%H%M%S")
        filename = save_dir / f"timelapse-{now}.jpg"
        picam.capture_file(str(filename))
        print("saved:", filename)
        time.sleep(60)
except KeyboardInterrupt:
    print("stop")
finally:
    picam.close()

이 코드는 60초마다 사진을 한 장씩 저장한다. Ctrl + C를 누르면 반복을 멈추고, finally에서 카메라를 닫는다. 장시간 실행하는 프로그램에서는 이렇게 종료 처리를 넣는 습관이 중요하다.

타임랩스를 오래 실행하면 저장 공간이 빠르게 줄어든다. 사진 한 장이 몇 MB만 되어도 하루, 이틀이 지나면 수백 장이 쌓인다. 다음 명령으로 저장 공간을 가끔 확인한다.

df -h

사진 폴더의 용량은 다음처럼 확인할 수 있다.

du -sh ~/camera-project/photos

자동 촬영은 "찍는 코드"보다 "쌓인 파일을 어떻게 관리할지"가 더 중요해지는 순간이 온다.

움직임이 감지되면 사진 찍기

카메라에 PIR 움직임 센서를 연결하면 간단한 감시 장치를 만들 수 있다. PIR 센서는 사람이나 동물이 움직일 때 변화를 감지하는 센서다. 앞에서 배운 GPIO 입력과 카메라 촬영을 연결하는 예제라고 생각하면 된다.

구조는 다음과 같다.

  1. PIR 센서가 움직임을 감지한다.

  2. 라즈베리파이가 GPIO 입력 변화를 읽는다.

  3. 카메라가 사진을 찍는다.

  4. 파일 이름에 시간을 붙여 저장한다.

  5. 필요하면 서버로 업로드한다.

  6. 업로드가 성공하면 로컬 파일을 정리한다.

이런 구조는 실제 IoT 보안 카메라 예제에서도 자주 사용된다. 라즈베리파이에서 Picamera2로 촬영하고, HTTP POST 방식으로 서버에 이미지를 보내며, 성공 후 로컬 파일을 삭제해 저장 공간을 관리하는 식이다.2

간단한 예제는 다음과 같다. PIR 센서 출력 핀을 BCM GPIO 17에 연결했다고 가정한다.

from datetime import datetime
from pathlib import Path
from gpiozero import MotionSensor
from picamera2 import Picamera2
from signal import pause
import time

motion = MotionSensor(17)
save_dir = Path("motion-photos")
save_dir.mkdir(exist_ok=True)

picam = Picamera2()
picam.configure(picam.create_still_configuration())
picam.start()
time.sleep(2)

def take_picture():
    now = datetime.now().strftime("%Y%m%d-%H%M%S")
    filename = save_dir / f"motion-{now}.jpg"
    picam.capture_file(str(filename))
    print("motion detected:", filename)

def all_clear():
    print("all clear")

motion.when_motion = take_picture
motion.when_no_motion = all_clear

try:
    pause()
finally:
    picam.close()

이 코드는 움직임이 감지될 때마다 사진을 저장한다. 실제로 사용할 때는 너무 많은 사진이 찍히지 않도록 몇 초 동안은 다시 찍지 않는 제한을 두는 것이 좋다. 예를 들어 마지막 촬영 시간과 현재 시간을 비교해 10초 안에는 다시 촬영하지 않게 만들 수 있다.

서버로 업로드하는 흐름 이해하기

촬영 파일을 라즈베리파이에만 저장하면 같은 네트워크 안에서만 확인하기 쉽다. 원격 확인이 필요하면 웹 서버나 원격 서버로 업로드하는 구조를 사용할 수 있다.

가장 단순한 흐름은 다음과 같다.

import requests

server_url = "https://example.com/upload"

with open("motion-photo.jpg", "rb") as f:
    files = {"file": f}
    response = requests.post(server_url, files=files, timeout=10)

if response.status_code == 200:
    print("upload success")
else:
    print("upload failed", response.status_code)

여기서 HTTP POST는 파일이나 데이터를 서버로 보내는 요청 방식이다. 웹 브라우저가 페이지를 받아 오는 것이 주로 GET이라면, POST는 서버에 무언가를 제출할 때 자주 쓰인다.

초보자 프로젝트에서는 처음부터 인터넷 공개 서버를 만들려고 하지 않아도 된다. 10장에서 만든 Flask 서버를 같은 로컬 네트워크 안에 두고, /upload 주소로 이미지를 받게 만들어도 충분하다. 단, 외부 인터넷에 공개할 때는 비밀번호, HTTPS, 업로드 용량 제한, 오래된 파일 삭제가 필요하다. 카메라 프로젝트는 사생활과 보안 문제가 생길 수 있으므로 촬영 장소와 저장 위치를 신중하게 정해야 한다.

오디오 장치 연결과 확인

라즈베리파이는 카메라뿐 아니라 소리도 다룰 수 있다. 스피커는 HDMI 모니터, USB 오디오 장치, 블루투스 스피커 등으로 연결할 수 있다. 마이크는 보통 USB 마이크를 사용하는 것이 쉽다. 라즈베리파이 보드에는 일반 PC처럼 아날로그 마이크 입력 단자가 기본으로 제공되지 않는 모델이 많기 때문이다.

오디오 장치를 연결한 뒤에는 설정 메뉴에서 입력과 출력을 확인한다. 터미널에서는 다음 명령으로 재생 장치를 확인할 수 있다.

aplay -l

녹음 장치는 다음 명령으로 확인한다.

arecord -l

간단한 녹음 테스트는 다음처럼 할 수 있다.

arecord -D plughw:1,0 -f cd -t wav -d 5 test.wav

5초 동안 녹음한 뒤 재생한다.

aplay test.wav

장치 번호는 환경마다 다를 수 있다. arecord -l 결과를 보고 plughw:1,0 부분을 맞춰야 한다. 소리가 녹음되지 않으면 마이크 권한, 장치 번호, 입력 볼륨을 차례로 확인한다.

영상과 오디오는 따로 녹음한 뒤 합칠 수 있다

카메라 영상과 마이크 소리를 하나의 파일로 만들고 싶을 때가 있다. 이때 초보자가 이해해야 할 핵심은 "영상 녹화"와 "오디오 녹음"이 별도 작업일 수 있다는 점이다. Picamera2로 영상을 녹화하고, 다른 도구나 라이브러리로 오디오를 녹음한 뒤, 마지막에 ffmpeg로 합치는 구조를 사용할 수 있다. 실제 프로젝트에서도 버튼으로 녹화를 시작·종료하고, LED로 상태를 표시하며, 녹화가 끝나면 오디오와 영상을 병합하는 방식이 사용된다.3

영상 녹화의 기본 파이썬 흐름은 다음과 같다.1

import time
from picamera2 import Picamera2
from picamera2.encoders import H264Encoder

picam = Picamera2()
picam.configure(picam.create_video_configuration())

encoder = H264Encoder(10000000)
picam.start_recording(encoder, "video.h264")
time.sleep(10)
picam.stop_recording()
picam.close()

오디오를 별도 파일로 녹음했다면 다음처럼 합칠 수 있다.

ffmpeg -i video.h264 -i audio.wav -c:v copy -c:a aac output.mp4

ffmpeg는 영상과 오디오를 변환하고 합치는 강력한 도구다. 처음에는 옵션이 복잡해 보이지만, 여기서는 "영상 파일과 오디오 파일을 입력으로 받아 MP4 하나로 만든다" 정도로 이해하면 된다. 영상과 오디오의 시작 시간이 어긋나면 싱크가 맞지 않을 수 있으므로, 실제 프로젝트에서는 버튼 하나로 녹화와 녹음을 동시에 시작하는 구조가 유리하다.

멀티미디어 프로젝트의 정리 습관

카메라와 오디오는 저장 공간을 많이 사용한다. 센서 값 몇 줄을 CSV로 저장하는 것과 다르다. 사진, 영상, 음성 파일은 금방 microSD 카드를 채운다. 그래서 멀티미디어 프로젝트에는 파일 관리 규칙이 필요하다.

좋은 습관은 다음과 같다.

  • 날짜별 폴더에 저장한다.

  • 파일 이름에 촬영 시간을 넣는다.

  • 업로드가 끝난 파일은 삭제하거나 별도 폴더로 옮긴다.

  • 오래된 파일을 자동 정리한다.

  • 중요한 파일은 PC나 NAS, 클라우드에 백업한다.

  • 촬영 위치와 대상의 사생활을 침해하지 않는다.

웹으로 확인하고 싶다면 10장에서 만든 작은 웹 서버와 연결할 수 있다. 예를 들어 photos 폴더를 웹 서버의 정적 파일 폴더로 두면 같은 네트워크 안의 다른 컴퓨터나 스마트폰에서 사진을 볼 수 있다. 더 나아가 Flask로 최근 사진 목록을 보여 주는 페이지를 만들 수도 있다.

이번 장에서 다룬 흐름은 모두 같은 구조로 정리된다.

카메라·마이크 입력 → 파이썬 처리 → 파일 저장 → 웹 표시 또는 서버 업로드 → 오래된 파일 정리

이 구조를 이해하면 라즈베리파이는 단순한 실습 보드가 아니라 작은 기록 장치가 된다. 움직임을 감지해 사진을 남기고, 일정 시간마다 풍경을 촬영하고, 소리와 영상을 함께 저장하고, 웹에서 결과를 확인할 수 있다. 다음 장에서는 이런 입력, 처리, 출력, 저장, 공유의 흐름을 더 넓은 IoT 자동화 프로젝트로 연결해 본다.

참고

1How to Use The Raspberry Pi Camera With Python in 2026

2IoT Security Camera With Raspberry Pi, Render and picamera2

3GitHub - Caaki/RaspberryCamera

책 목록

라즈베리파이 첫걸음: 설치부터 GPIO·서버·IoT 프로젝트까지

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기