개요
공부 목적으로 프로젝트를 하나 고민하다가 라즈베리 파이를 이용해 스마트 CCTV를 만들고자 한다.
프로젝트 github :github.com/sive2045/smart_CCTV
주요 기능
1. 침입 감지
2. 피플카운트
3. 체류시간분석
4. 조견 별 영상 검색기 제공
5. 카메라 훼손 탐지
6. 스마트 영상 요약
Stack
이미지 프로세싱 : python환경의 openCV
백엔드 : flask (공부가 주된 목적이기에 선택)
카메라 스트리밍 : github.com/jacksonliam/mjpg-streamer
-> 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
결과 영상
다음 포스팅 때는 이 모션 감지를 API로 flask에 올리는 과정을 작성하겠다.