意外と簡単!音を感知して録画する監視カメラをつくる(Python)

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、前回記事JavaScriptでレンダリングしてるページをスクレイピングする方法では、「ヘッドレスChrome」を使った関係から久しぶりNode.jsを使うことになりました。

そして、この記事を公開した後いつものPHPJavaScript以外のプログラムも面白かったので、今回の記事も久しぶりにPythonを使った内容をお届けします。

その内容とは・・・

音を感知して録画する監視カメラをつくる

です!

実をいうとこの機能はブラウザ側のJavaScriptで実装できれば、と考えていたのですが、ウェブ上を探してもうまくいきそうな情報が見つからなかったので開発せず「置いとく」機能になっていました。

そして、少し前にこれがPythonだと意外と簡単に実装ができることがわかったのでここで皆さんと共有したいと思います。

ぜひ皆さんのお役に立てると嬉しいです😊✨

開発環境: Python 2.7

パッケージをインストールする

以下2つの機能が必要なので、それぞれパッケージをインストールしておきます。

  • 録画する部分 ・・・ OpenCV2
  • 入力された音を監視する部分 ・・・ SoundDevice

パッケージはpipでインストールできます。
以下のコマンドを実行してください。

pip install opencv-python
pip install sounddevice

準備

今回はcamera.pyというファイルにコードを書いて以下のコマンドで実行します。

python camera.py

なお、今回のコードで作成する録画ファイルは同じフォルダ内に作成したmoviesというフォルダ内に保存されることになります。権限の関係でエラーが発生することも考えられるので、このフォルダも作成し書き込み権限を与えておいてください。

コードを書いていく

ではここからPythonのコードを書いていく部分になりますが、今回もコードは短めなので、基本コードの中に書かれている番号を後で紹介するコードに入れ替えていけば全て完成する「学習雑誌の付録」形式でお届けします😊✨

基本のコード

まずは基本コードですが、今回は独自クラスSoundSurveillanceを作って実装します。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import cv2
import time
from datetime import datetime
import numpy as np
import sounddevice as sd

class SoundSurveillance:

    # 定数と変数 ・・・ ①

    # コンストラクタ ・・・ ②

    # 音を監視する部分 ・・・ ③

    # 録画する部分 ・・・ ④

ss = SoundSurveillance()

定数と変数 ・・・ ①

では、クラス内で必要になる定数と変数を定義しておきましょう。

# 定数と変数 ・・・ ①
DURATION = 3
VOLUME_THRESHOLD = 100
recording = False

DURATIONは、音がなったときに録画する秒数になります。
そのため、例えば飼い犬や猫の様子を撮影したい場合はもう少し長い時間にするといいかもしれません。

そして、VOLUME_THRESHOLDは、いわゆる「しきい値」と呼ばれるもので、これと今鳴っている音の大きさを比べて録画するかどうかを判別することになります。

recordingは変数で、いま録画中かどうかが分かるようにTrueFalseが入ることになります。

コンストラクタ ・・・ ②

コンストラクタは、一番最初に実行されるメソッドですので、ここで次の項目でつくる「音を監視するメソッド」listen_sound()を呼び出しています。

# コンストラクタ ・・・ ②
def __init__(self):
    self.listen_sound()

音を監視する部分 ・・・ ③

音を監視する部分はメソッドが2つです。

# 音を監視する部分 ・・・ ③
def listen_sound(self):
    duration = 60  # 音声チェックを一時的に続ける秒数
    while True:
        with sd.InputStream(callback=self.detect_sound):
            sd.sleep(duration * 1000)

def detect_sound(self, indata, frames, time, status):
    if self.recording == False:
        volume = np.linalg.norm(indata) * 10
        if volume > self.VOLUME_THRESHOLD:
            self.recording = True
            self.start_recording()

まず、先ほどコンストラクタで呼び出していたlisten_sound()ですが、ここでは最初にインストールしたパッケージSoundDeviceを使って入力音声を取得してます。今回は60秒ごとに何度も音声をチェックするようにしています。

そして、取得した音声データから「大きい音がなったかどうか」をチェックして、録画を実行するかどうか判別しているのがdetect_sound()です。

この中では、indataと呼ばれる変数の中に音声データが入っているので、これを元にして鳴っている音の音量(volume)を取得、さらに①の項目で設定したVOLUME_THRESHOLDと比較して、それより大きな数値だったら録画を開始するという流れになります。

録画する部分 ・・・ ④

では最後に今回のメイン、録画する部分をつくっていきます。

# 録画する部分 ・・・ ④
def start_recording(self):

    self.recording = True
    save_path = './movies/'+ datetime.now().strftime('%Y%m%d%H%M%S') +'.avi'
    print('Recording...('+ save_path +')')

    cap = cv2.VideoCapture(0)

    # ウェブカメラのサイズを取得する
    f_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    f_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    video_writer = cv2.VideoWriter(save_path, fourcc, 25, (f_width, f_height))

    started_time = time.time()

    # ウェブカメラの映像を保存
    while(cap.isOpened()):
        ret, frame = cap.read()
        diff_time = time.time() - started_time
        if ret == False or diff_time >= self.DURATION:
            break
        else:
            video_writer.write(frame)

    cap.release()
    video_writer.release()
    cv2.destroyAllWindows()
    self.recording = False
    print('Recording finished.')

少しだけコードが長いですが、やっていることは、OpenCVでウェブカメラにアクセスし1コマずつ映像を保存しているだけです。

ただし、録画は①の作業て追加したDURATION(録画する秒数)を超えると自動的に終了するようになっていることに注意してください。

if ret == False or diff_time >= self.DURATION:
    break

テストしてみる

では、簡単にテストしてみた結果です。

ファイルを起動して音がなる度に以下のように「Recording…」と「Recording finished」が表示されmoviesに動画ファイルが作成されました。

成功です😊✨

ダウンロードする

今回実際に開発したソースコードを以下からダウンロードすることができます。

※ ただし、パッケージのインストールやフォルダの作成などはご自身で用意してください。

音を感知して録画する監視カメラ
開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、久しぶりPythonを使ってコードを書いてみました。

プログラマーあるあるかもしれませんが、function xxxx() { …. と書いたところで「違った!これPythonじゃない・・・😫」となってしまいました(笑)

ちなみに今回は私がメインで使っているUbuntu 18.04で実行しましたが、Pythonは様々なOSで実行できるので、小型PCのRaspberry Piなどで実装して監視カメラをつくることもできると思います。

ぜひ皆さんも活用してみてくださいね。

ではでは〜!

※ なお、今回の機能をつくりたくなったのは、実はテレビ番組で「絶滅した動物を見つけよう!」という企画で音声に反応する監視カメラを使っていたことが発端でした。

このエントリーをはてなブックマークに追加       follow us in feedly