生産技術者サラリーマンの日々

社畜サラリーマンが生産技術やお金の悩みを徒然と書くブログです。私の備忘録が共有できるとうれしいです

【PYTHON+OPENCV】防犯カメラプログラム

防犯カメラ

1.防犯カメラプログラムの概要

■物体検出
以前作成したプログラムです。背景画像と現在の入力画像を差分から閾値以上差異があれば何かしらの物体が来たとして、録画を開始する

inusan0424.hatenablog.com

■時間計測
なにかしらの物体が来たと判断したら、録画を開始するが一定時間録画したら録画を終了する。dt_now = datetime.datetime.now()関数で時間情報を取得し、dif = dt_now - stack_todayにて差分を計算し、閾値以上の時間がたったら録画を終了する。

今回ラズベリーパイを使用するが、電源を切ると内部で時刻を記憶できず、時間が止まってしまうため、注意が必要です。

arakoki70.com

2.使用したカメラ

画像処理を行うカメラには、個人的にはオートフォーカスは使用せず、画像処理を実施する環境化で露光、ズーム(範囲)、焦点距離をマニュアルで調整し、固定します。

3.プログラム

import cv2
import numpy as np
import time
import datetime

# 画像取得の定義
cap = cv2.VideoCapture(0)
fps = int(cap.get(cv2.CAP_PROP_FPS))
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 変数の定義
global video_star
video_start = 0
before = None # 前回の画像を保存する変数
red = (0, 0, 255) # 枠線の色
kernel = np.ones((7, 7), np.uint8)#カーネルの指示
th = 60#背景差分の閾値
dif_sec = 0
dif_sec_th = 30#rec video time


if __name__ == '__main__':
    rec = 0
    while True:
        today =datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") 
        dt_now = datetime.datetime.now()
        yer = dt_now.year
        mon = dt_now.month
        day = dt_now.day
        hor = dt_now.hour
        min = dt_now.minute
        sec = dt_now.second

        #not detect camera
        if ret == False: break
        if video_start == 1:
            time.sleep(1/fps)
            video.write(frame)

        #gray scle
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        if before is None:
            before = gray.astype("float")
            continue

        #現在のフレームと移動平均との差を計算
        cv2.accumulateWeighted(gray, before, 0.5)
        mask = cv2.absdiff(gray, cv2.convertScaleAbs(before))

        mask[mask < th] = 0#二値化処理
        mask[mask >= th] = 255#二値化処理
        d_mask = cv2.dilate(mask, kernel)#膨張処理
        e_mask = cv2.erode(d_mask, kernel)#収縮処理

        #輪郭のデータを得る
        contours = cv2.findContours(e_mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[0]
        
        # 差分があった点を画面に描く
       for target in contours:

            if w < 30: continue # 小さな変更点は無視
            if rec == 0:
                print("video start" + today)
                video_start = 1
                file = "/home/pi/Videos/" + str(yer) +"_"+ str(mon) +"_"+ str(day) +"_"+ str(hor) +"_"+ str(min) +"_"+ str(sec) + ".mp4"

                stack_today = dt_now
                fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
                video = cv2.VideoWriter(file, fourcc, fps, (w, h))
                rec = 1
                
    # 録画開始
        if rec == 1:
            dif = dt_now - stack_today # 時間の差分
            dif_sec = dif.seconds # 秒を計算
            
            if dif_sec > dif_sec_th: # もし、閾値以上の時間がたったら
                vide_start = 0# 録画終了
                rec = 0
                video.release()
                print("video end")
                               
        cv2.imshow("Frame", frame)
        key = cv2.waitKey(1)
        if key == 27:
            break
        elif key == 0x73:#s key
            if rec == 0:
                print("video start" + today)
                video_start = 1
                file = "/home/pi/Videos/" + str(yer) + str(mon) + str(day) + str(hor) + str(min) + str(sec) + ".mp4"
                fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
                video = cv2.VideoWriter(file, fourcc, fps, (w, h))
                rec = 1
        elif key == ord("e"):
            if rec == 1:
                rec = 0
                video_start = 0
                print("video end")
                video.release()

    cap.release()
    cv2.destroyAllWindows()
https://blog.hatena.ne.jp/inusan0424/inusan0424.hatenablog.com/config/design/detail