Python OpenCV

OpenCV를 활용한 모션 감지 및 보안 카메라 시스템 구축

PyExplorer 2025. 3. 18. 07:56

OpenCV를 활용한 모션 감지 및 보안 카메라 시스템 구축

1. 개요

이번 포스팅에서는 OpenCV를 활용하여 모션 감지 기능을 구현하고 이를 보안 카메라 시스템으로 확장하는 방법을 설명합니다. 실시간 영상에서 움직임을 감지하고, 특정 조건을 만족하면 경고를 출력하는 간단한 프로젝트를 진행합니다. 웹캠을 활용하여 실시간으로 감지할 수 있으며, 저장된 영상에서도 동일한 기법을 적용할 수 있습니다.

2. 필요한 라이브러리 및 환경 설정

본 프로젝트를 실행하기 위해 필요한 라이브러리는 다음과 같습니다.

pip install opencv-python numpy imutils

필요한 라이브러리:

  • opencv-python: 영상 처리 및 모션 감지
  • numpy: 행렬 연산
  • imutils: 편리한 이미지 처리 기능 제공

3. 기본 개념

모션 감지는 영상의 연속된 프레임 간 차이를 분석하여 움직임을 탐지하는 방식으로 이루어집니다. 기본적인 접근 방식은 다음과 같습니다.

  1. 초기 프레임(배경) 저장
  2. 현재 프레임과 초기 프레임 비교
  3. 차이가 일정 임계값을 초과하면 모션 감지
  4. 감지된 영역을 사각형으로 표시
  5. 일정 시간 이상 움직임이 지속되면 알림 제공 또는 녹화 시작

이를 위해 OpenCV에서 제공하는 cv2.absdiff(), cv2.threshold(), cv2.findContours() 등의 함수를 활용합니다.

4. 코드 구현

아래 코드에서는 웹캠을 활용하여 실시간으로 모션을 감지하는 프로그램을 작성합니다.

import cv2
import numpy as np
import imutils

# 웹캠 초기화
cap = cv2.VideoCapture(0)
first_frame = None

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # 프레임 크기 조정 및 흑백 변환
    frame = imutils.resize(frame, width=500)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (21, 21), 0)

    # 초기 프레임 설정
    if first_frame is None:
        first_frame = gray
        continue

    # 차이 계산
    frame_delta = cv2.absdiff(first_frame, gray)
    thresh = cv2.threshold(frame_delta, 25, 255, cv2.THRESH_BINARY)[1]

    # 노이즈 제거
    thresh = cv2.dilate(thresh, None, iterations=2)
    contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    motion_detected = False
    for contour in contours:
        if cv2.contourArea(contour) < 500:
            continue

        (x, y, w, h) = cv2.boundingRect(contour)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
        motion_detected = True

    # 모션 감지 여부 표시
    text = "Motion Detected" if motion_detected else "No Motion"
    cv2.putText(frame, text, (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

    # 화면 출력
    cv2.imshow("Security Feed", frame)
    cv2.imshow("Threshold", thresh)

    key = cv2.waitKey(1) & 0xFF
    if key == ord("q"):
        break

cap.release()
cv2.destroyAllWindows()

5. 코드 설명

  • 웹캠을 통해 프레임을 읽어오고 크기를 조정합니다.
  • cv2.cvtColor()를 이용해 흑백 변환 후, cv2.GaussianBlur()로 노이즈를 제거합니다.
  • 초기 프레임을 저장한 후, 새로운 프레임과 비교하여 차이를 구합니다.
  • cv2.threshold()를 이용해 임계값을 설정하고, cv2.findContours()를 활용하여 움직이는 영역을 감지합니다.
  • 감지된 움직임을 사각형으로 표시하며, 일정 크기 이상의 움직임만 감지하도록 필터링합니다.
  • cv2.putText()를 이용해 모션 감지 여부를 화면에 표시합니다.

6. 보안 카메라 시스템 확장

위 코드를 기반으로 다양한 기능을 추가하여 보안 카메라 시스템을 구축할 수 있습니다.

6.1 알람 기능 추가

모션이 감지되었을 때 이메일이나 푸시 알림을 보낼 수 있도록 확장할 수 있습니다. 예제 코드:

import smtplib

def send_alert():
    server = smtplib.SMTP("smtp.gmail.com", 587)
    server.starttls()
    server.login("your_email@gmail.com", "your_password")
    message = "Subject: Motion Alert!\n\nMotion detected in your security system."
    server.sendmail("your_email@gmail.com", "receiver_email@gmail.com", message)
    server.quit()

6.2 녹화 기능 추가

모션이 감지될 때 자동으로 녹화를 시작할 수도 있습니다.

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (500, 375))

if motion_detected:
    out.write(frame)

7. 결론

이번 포스팅에서는 OpenCV를 활용하여 모션 감지 시스템을 구현하는 방법을 설명하였습니다. 기본적인 모션 감지 원리를 이해하고, 이를 보안 카메라 시스템으로 확장하는 방법을 학습하였습니다. 이메일 알림과 녹화 기능을 추가하여 보다 강력한 보안 시스템을 구축할 수 있습니다. 실제 프로젝트에서 활용할 경우, 딥러닝 기반 객체 감지 모델(YOLO, SSD 등)과 결합하여 더욱 정교한 감지 시스템을 구축할 수도 있습니다.