임베디드/스마트 CCTV 클론

[IoT] 스마트 CCTV(1) - 모션 감지

개요

공부 목적으로 프로젝트를 하나 고민하다가 라즈베리 파이를 이용해 스마트 CCTV를 만들고자 한다.

 

프로젝트 github :github.com/sive2045/smart_CCTV

 

sive2045/smart_CCTV

Contribute to sive2045/smart_CCTV development by creating an account on GitHub.

github.com

 

주요 기능

1. 침입 감지

2. 피플카운트 

3. 체류시간분석

4. 조견 별 영상 검색기 제공

5. 카메라 훼손 탐지

6. 스마트 영상 요약 

 

Stack

이미지 프로세싱 : python환경의 openCV

 

백엔드 : flask (공부가 주된 목적이기에 선택)

 

카메라 스트리밍 : github.com/jacksonliam/mjpg-streamer

 

jacksonliam/mjpg-streamer

Fork of http://sourceforge.net/projects/mjpg-streamer/ - jacksonliam/mjpg-streamer

github.com

-> openCV로 여는 것보다 스트리밍 영상을 따오는 것이 더 빠름. 

 

DB : 아직 고민 중인 파트.. 영상을 실시간 처리해야 돼서 InfluxDB를 고민 중이다.

 

모션 감지

침입 감지 외에도 다양하게 활용하므로 맨 처음으로 구현해봤다.

 

원리 프레임픽셀 차이를 이용하면 된다. 

2 프레임 간 비교를 해도 정상적으로 작동하지만, 안정적인 구현을 위해 3 프레임 비교를 해서 판단했다.

코드 출처 : hyongdoc.tistory.com/410

 

 

import cv2 as cv
import numpy as np

thresh = 25 #픽셀 차
max_diff = 5

a, b, c = None, None, None

cap = cv.VideoCapture("http://개인스트리밍주소/?action=stream")

if cap.isOpened():
    ret, a = cap.read()
    ret, b = cap.read()
    while ret:
        ret, c = cap.read()
        draw = c.copy()
        if not ret:
            break

        a_gray = cv.cvtColor(a, cv.COLOR_BGR2GRAY)
        b_gray = cv.cvtColor(b, cv.COLOR_BGR2GRAY)
        c_gray = cv.cvtColor(c, cv.COLOR_BGR2GRAY)

        diff1 = cv.absdiff(a_gray, b_gray)
        diff2 = cv.absdiff(b_gray, c_gray)

        ret, diff1_t = cv.threshold(diff1, thresh, 255, cv.THRESH_BINARY)
        ret, diff2_t = cv.threshold(diff2, thresh, 255, cv.THRESH_BINARY)

        diff = cv.bitwise_and(diff1_t, diff2_t)

        k = cv.getStructuringElement(cv.MORPH_CROSS, (3, 3))
        diff = cv.morphologyEx(diff, cv.MORPH_OPEN, k)

        diff_cnt = cv.countNonZero(diff)
        if diff_cnt > max_diff:
            nzero = np.nonzero(diff)
            cv.rectangle(draw, (min(nzero[1]), min(nzero[0])), (max(
                nzero[1]), max(nzero[0])), (0, 255, 0), 2)

            cv.putText(draw, "Motion detected!", (10, 30),
                       cv.FONT_HERSHEY_DUPLEX, 0.5, (0, 0, 255))

        stacked = np.hstack((draw, cv.cvtColor(diff, cv.COLOR_GRAY2BGR)))
        cv.imshow('motion', stacked)

        # next frame
        a = b
        b = c

        if cv.waitKey(1) & 0xFF == 27:
            break

결과 영상

 

 

 

다음 포스팅 때는 이 모션 감지를 APIflask에 올리는 과정을 작성하겠다.