반응형
라즈베리파이에 USB 카메라를 연결했는데 제대로 작동하지 않나요? 걱정 마세요! 단계별로 확인하고 설정하는 완벽한 가이드를 제공해드립니다. 📷✨
🎯 완료 목표
- USB 카메라 정상 연결 확인
- 다양한 해상도로 사진 촬영
- 실시간 웹 스트리밍 구현
- Node-RED 연동 설정
🔍 1단계: 기본 연결 확인
USB 장치 인식 확인
# USB에 연결된 모든 장치 확인
lsusb
# 비디오 장치 파일 확인
ls -la /dev/video*
# 시스템 로그에서 카메라 관련 메시지 확인
sudo dmesg | grep -i "video\|camera\|usb"
정상 연결 시 출력 예시:
/dev/video0 # 첫 번째 카메라
/dev/video1 # 두 번째 카메라 (있는 경우)
카메라 드라이버 확인
# UVC 드라이버 로드 상태 확인
lsmod | grep uvcvideo
# 드라이버가 없다면 다시 로드
sudo rmmod uvcvideo
sudo modprobe uvcvideo
🔧 2단계: 카메라 정보 상세 확인
v4l2 도구 설치 및 사용
# Video4Linux 유틸리티 설치
sudo apt update
sudo apt install v4l-utils
# 연결된 카메라 목록 확인
v4l2-ctl --list-devices
# 지원하는 해상도와 포맷 확인
v4l2-ctl --list-formats-ext -d /dev/video0
# 카메라의 모든 설정 정보 확인
v4l2-ctl --all -d /dev/video0
출력 예시:
📸 3단계: 테스트 촬영
fswebcam으로 간단 촬영
# fswebcam 설치
sudo apt install fswebcam
# 기본 해상도로 사진 촬영
fswebcam -d /dev/video0 -r 640x480 test.jpg
# HD 해상도로 고품질 촬영
fswebcam -d /dev/video0 \
--no-banner \
--resolution 1280x720 \
--frames 5 \
--delay 2 \
camera_test.jpg
# 촬영된 이미지 확인
ls -la *.jpg
배치 촬영 스크립트
#!/bin/bash
# batch_capture.sh
CAMERA_DEVICE="/dev/video0"
OUTPUT_DIR="./captures"
# 출력 디렉토리 생성
mkdir -p $OUTPUT_DIR
# 다양한 해상도로 테스트 촬영
resolutions=("640x480" "1280x720" "1920x1080")
for res in "${resolutions[@]}"; do
filename="${OUTPUT_DIR}/test_${res}.jpg"
echo "촬영 중: $res -> $filename"
fswebcam -d $CAMERA_DEVICE \
--no-banner \
--resolution $res \
--frames 3 \
$filename
done
echo "촬영 완료! 파일 확인:"
ls -la $OUTPUT_DIR/
🌐 4단계: 실시간 웹 스트리밍
mjpg-streamer 설치
# 필요한 개발 도구 설치
sudo apt install cmake libjpeg8-dev gcc g++ git
# mjpg-streamer 소스 다운로드
cd ~
git clone https://github.com/jacksonliam/mjpg-streamer.git
cd mjpg-streamer/mjpg-streamer-experimental
# 컴파일 및 설치
make
sudo make install
스트리밍 서버 시작
# 기본 스트리밍 (포트 8080)
./mjpg_streamer \
-i "input_uvc.so -d /dev/video0 -r 640x480 -f 30" \
-o "output_http.so -p 8080 -w www"
# HD 스트리밍 (고품질)
./mjpg_streamer \
-i "input_uvc.so -d /dev/video0 -r 1280x720 -f 15" \
-o "output_http.so -p 8080 -w www"
웹 브라우저 접속: http://라즈베리파이IP:8080
자동 시작 서비스 등록
# 서비스 파일 생성
sudo tee /etc/systemd/system/mjpg-streamer.service << EOF
[Unit]
Description=MJPG Streamer
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/mjpg-streamer/mjpg-streamer-experimental
ExecStart=/home/pi/mjpg-streamer/mjpg-streamer-experimental/mjpg_streamer -i "input_uvc.so -d /dev/video0 -r 640x480 -f 15" -o "output_http.so -p 8080 -w www"
Restart=always
[Install]
WantedBy=multi-user.target
EOF
# 서비스 활성화
sudo systemctl enable mjpg-streamer
sudo systemctl start mjpg-streamer
# 상태 확인
sudo systemctl status mjpg-streamer
🐍 5단계: Python으로 카메라 제어
OpenCV 설치 및 테스트
# OpenCV 설치
pip3 install opencv-python
# 추가 패키지 (선택사항)
pip3 install opencv-contrib-python
카메라 테스트 스크립트
#!/usr/bin/env python3
import cv2
import sys
import os
from datetime import datetime
def test_camera(device_id=0):
"""USB 카메라 종합 테스트"""
print(f"🔍 카메라 /dev/video{device_id} 테스트 시작...")
# 카메라 연결
cap = cv2.VideoCapture(device_id)
if not cap.isOpened():
print(f"❌ 카메라를 열 수 없습니다")
return False
# 카메라 정보 출력
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
print(f"✅ 카메라 연결 성공!")
print(f" 📐 해상도: {width}x{height}")
print(f" 🎬 FPS: {fps}")
# 해상도 변경 테스트
resolutions = [(640, 480), (1280, 720), (1920, 1080)]
for w, h in resolutions:
cap.set(cv2.CAP_PROP_FRAME_WIDTH, w)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, h)
ret, frame = cap.read()
if ret:
actual_h, actual_w = frame.shape[:2]
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"camera_test_{w}x{h}_{timestamp}.jpg"
cv2.imwrite(filename, frame)
print(f"📷 {w}x{h} 촬영 완료: {filename} (실제: {actual_w}x{actual_h})")
else:
print(f"❌ {w}x{h} 해상도 촬영 실패")
cap.release()
return True
def continuous_capture(device_id=0, duration=10):
"""연속 촬영 테스트"""
print(f"🎥 {duration}초간 연속 촬영 테스트...")
cap = cv2.VideoCapture(device_id)
if not cap.isOpened():
return False
# 비디오 저장 설정
fourcc = cv2.VideoWriter_fourcc(*'XVID')
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"video_test_{timestamp}.avi"
fps = 15
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
out = cv2.VideoWriter(filename, fourcc, fps, (width, height))
start_time = cv2.getTickCount()
frame_count = 0
while True:
ret, frame = cap.read()
if not ret:
break
# 프레임 저장
out.write(frame)
frame_count += 1
# 시간 확인
elapsed = (cv2.getTickCount() - start_time) / cv2.getTickFrequency()
if elapsed >= duration:
break
# 진행 상황 표시
if frame_count % (fps * 2) == 0: # 2초마다
print(f" 📹 진행: {elapsed:.1f}/{duration}초")
cap.release()
out.release()
print(f"✅ 비디오 저장 완료: {filename}")
print(f" 📊 총 프레임: {frame_count}")
print(f" ⏱️ 실제 FPS: {frame_count/duration:.1f}")
return True
if __name__ == "__main__":
print("🎬 라즈베리파이 USB 카메라 종합 테스트")
print("=" * 50)
# 사용 가능한 카메라 찾기
working_cameras = []
for i in range(4): # /dev/video0~3 테스트
if os.path.exists(f"/dev/video{i}"):
try:
if test_camera(i):
working_cameras.append(i)
print("-" * 40)
except Exception as e:
print(f"❌ /dev/video{i} 오류: {e}")
# 첫 번째 작동하는 카메라로 연속 촬영 테스트
if working_cameras:
print(f"\n🎯 /dev/video{working_cameras[0]}로 연속 촬영 테스트")
continuous_capture(working_cameras[0], 5) # 5초간
print("\n✅ 모든 테스트 완료!")
🔴 6단계: Node-RED 카메라 연동
카메라 노드 설치
# Node-RED 카메라 관련 노드 설치
cd ~/.node-red
npm install node-red-contrib-camerapi
npm install node-red-node-base64
# Node-RED 재시작
sudo systemctl restart nodered
간단한 촬영 플로우
Node-RED에서 exec 노드 설정:
// exec 노드 설정
Command: fswebcam
Arguments: -d /dev/video0 -r 640x480 --no-banner /tmp/camera_capture.jpg
// Function 노드로 파일 읽기
var fs = require('fs');
try {
var imageBuffer = fs.readFileSync('/tmp/camera_capture.jpg');
var base64Image = imageBuffer.toString('base64');
msg.payload = base64Image;
msg.filename = 'camera_capture.jpg';
return msg;
} catch (error) {
node.error("이미지 읽기 실패: " + error.message);
return null;
}
Dashboard 2 이미지 표시
// Function 노드에서 Dashboard용 형식 변환
msg.payload = "data:image/jpeg;base64," + msg.payload;
return msg;
🚨 문제 해결 가이드
권한 문제 해결
# 사용자를 video 그룹에 추가
sudo usermod -a -G video $USER
# 그룹 적용을 위해 재로그인 또는 재부팅
sudo reboot
# 수동 권한 설정 (임시)
sudo chmod 666 /dev/video*
카메라가 인식되지 않을 때
# USB 포트 변경 후 다시 확인
lsusb
# 드라이버 재로드
sudo rmmod uvcvideo
sudo modprobe uvcvideo
# 시스템 로그 확인
sudo dmesg | tail -n 20
성능 문제 해결
# GPU 메모리 할당 증가 (128MB 이상 권장)
sudo raspi-config
# Advanced Options → Memory Split → 128
# 또는 직접 편집
echo 'gpu_mem=128' | sudo tee -a /boot/config.txt
sudo reboot
🛠️ 종합 확인 스크립트
#!/bin/bash
# camera_full_check.sh
echo "🎬 라즈베리파이 USB 카메라 종합 진단"
echo "=================================="
# 1. USB 장치 확인
echo "1️⃣ USB 장치 확인:"
lsusb | grep -i "camera\|video\|webcam" || echo " ❌ 카메라 장치 없음"
echo
# 2. 비디오 장치 파일 확인
echo "2️⃣ 비디오 장치 파일:"
if ls /dev/video* 1> /dev/null 2>&1; then
ls -la /dev/video*
echo " ✅ 비디오 장치 파일 존재"
else
echo " ❌ /dev/video* 파일 없음"
fi
echo
# 3. 권한 확인
echo "3️⃣ 권한 확인:"
if groups $USER | grep -q video; then
echo " ✅ video 그룹 권한 있음"
else
echo " ❌ video 그룹 권한 없음"
echo " 💡 해결: sudo usermod -a -G video $USER"
fi
echo
# 4. 드라이버 확인
echo "4️⃣ UVC 드라이버 확인:"
if lsmod | grep -q uvcvideo; then
echo " ✅ uvcvideo 드라이버 로드됨"
else
echo " ❌ uvcvideo 드라이버 없음"
echo " 💡 해결: sudo modprobe uvcvideo"
fi
echo
# 5. 실제 촬영 테스트
echo "5️⃣ 촬영 테스트:"
if command -v fswebcam >/dev/null 2>&1; then
if fswebcam -d /dev/video0 -r 640x480 --no-banner test_camera.jpg 2>/dev/null; then
echo " ✅ 촬영 성공: test_camera.jpg"
ls -la test_camera.jpg
else
echo " ❌ 촬영 실패"
fi
else
echo " ⚠️ fswebcam 미설치"
echo " 💡 해결: sudo apt install fswebcam"
fi
echo
# 6. 카메라 정보 확인
echo "6️⃣ 카메라 상세 정보:"
if command -v v4l2-ctl >/dev/null 2>&1; then
v4l2-ctl --list-devices 2>/dev/null || echo " ❌ 카메라 정보 확인 실패"
else
echo " ⚠️ v4l2-ctl 미설치"
echo " 💡 해결: sudo apt install v4l-utils"
fi
echo
echo "🏁 진단 완료!"
실행 방법:
chmod +x camera_full_check.sh
./camera_full_check.sh
🎯 고급 활용 팁
타임랩스 촬영
#!/bin/bash
# timelapse.sh
INTERVAL=10 # 10초 간격
DURATION=3600 # 1시간 촬영
CAMERA="/dev/video0"
mkdir -p timelapse
cd timelapse
count=0
end_time=$(($(date +%s) + DURATION))
while [ $(date +%s) -lt $end_time ]; do
filename=$(printf "frame_%04d.jpg" $count)
fswebcam -d $CAMERA -r 1280x720 --no-banner $filename
echo "촬영: $filename"
((count++))
sleep $INTERVAL
done
echo "타임랩스 촬영 완료! 프레임 수: $count"
모션 감지 촬영
import cv2
import time
import os
def motion_detection_capture():
cap = cv2.VideoCapture(0)
# 첫 번째 프레임을 배경으로 설정
ret, background = cap.read()
background_gray = cv2.cvtColor(background, cv2.COLOR_BGR2GRAY)
background_gray = cv2.GaussianBlur(background_gray, (21, 21), 0)
while True:
ret, frame = cap.read()
if not ret:
break
# 현재 프레임 전처리
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)
# 차이 계산
frame_delta = cv2.absdiff(background_gray, gray)
thresh = cv2.threshold(frame_delta, 25, 255, cv2.THRESH_BINARY)[1]
# 윤곽선 찾기
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 모션 감지 시 촬영
for contour in contours:
if cv2.contourArea(contour) > 1000: # 임계값
timestamp = time.strftime("%Y%m%d_%H%M%S")
filename = f"motion_{timestamp}.jpg"
cv2.imwrite(filename, frame)
print(f"모션 감지! 촬영: {filename}")
time.sleep(2) # 2초 대기
break
time.sleep(0.1)
cap.release()
if __name__ == "__main__":
motion_detection_capture()
마무리하며 🎉
축하합니다! 이제 라즈베리파이 USB 카메라를 완벽하게 설정하고 활용할 수 있게 되었습니다!
간단한 사진 촬영부터 실시간 웹 스트리밍, Node-RED 연동까지 모든 것을 마스터하셨습니다. 이제 보안 카메라, 타임랩스, IoT 모니터링 시스템 등 무궁무진한 프로젝트를 시작할 수 있습니다! 💪
💬 카메라 프로젝트를 공유해주세요!
- 어떤 용도로 USB 카메라를 활용하고 계신가요?
- 가장 인상적이었던 촬영 결과는?
- 다음에 도전해보고 싶은 카메라 프로젝트가 있다면?
📋 빠른 체크리스트
✅ lsusb로 카메라 인식 확인
✅ /dev/video0 파일 존재 확인
✅ video 그룹 권한 설정
✅ fswebcam으로 테스트 촬영
✅ 웹 스트리밍 서버 실행
#라즈베리파이 #USB카메라 #OpenCV #웹스트리밍 #IoT #보안카메라 #타임랩스 #컴퓨터비전 #mjpg-streamer #fswebcam
'하드웨어' 카테고리의 다른 글
I2C와 UART 통신 프로토콜 가이드 (Part 1) - 기본 개념과 UART 통신 방식 (0) | 2025.07.01 |
---|---|
라즈베리파이 5 GPIO 문제 완전 해결: rpi-lgpio로 Node-RED 정상화하기 (1) | 2025.05.31 |
RS485 통신 완전 정복: 산업용 통신의 표준 (4) | 2025.05.30 |
라즈베리파이 GPIO 완전 정복: 기초부터 8채널 릴레이 제어까지 (0) | 2025.05.30 |
Node-RED로 XY-MD02 온습도 센서 실시간 모니터링하기 (1) | 2025.05.29 |