前回の更新がまさかの2年前だと・・・時が経つのは早いもんだ。
ブログに載せずに更新してた部分もあるんだけどね。それでも低頻度だが。
前に動かせるブロックを作ってみたもののあまり使い道がないことに気づいた。
押してどかすだけでは面白味に欠けるので目的の場所に運ぶようにしたいと思って
作ったのが上の画像である。
まぁ・・・いわゆる"倉庫番"なんだよな。
作ったものをコッソリ載せる場所
始めに
ラズパイをWebサーバー化してPHPも使えるようにしたけど何も活用していなかった。
という訳で支出管理をする為のアプリを作ることにしました。
今まではPCからエクセルで記帳していたけどいかんせん育児に時間を取られて自分の時間が少ない為に自室で腰を据えてというわけにもいかないのが現状。
しかしこれならスマホからどこからでも記帳できるのだ。
財布にレシートが溜まることもないのだ。
いきなり完成
長々とありふれたコードを載せても需要はなさそうなので割愛。
書込ボタンを押すとテキストボックスに入力された値がcsvファイルに書き込まれる。
ファイルは月が替わるごとに新規作成。ファイル名にも年月を付ける(202203.csv等)
PHPは年月の取得とファイル操作のコードを書いているだけ。
後は標準的なHTMLフォームの記述ができれば作れてしまうのだ。
レイアウトにcssも使っているがさほど重要でもあるまい。
ちなみに「詳細」リンクはカテゴリの区分をメモしたhtmlに飛んでいるだけ。
どのカテゴリを選択すればいいのか忘れた時の所謂ヘルプ。
おわりに
ラズパイサーバーにデータが溜まっていくのはいいが、そこからどうしたものか。
集計やグラフ表示はWindowsからC#あたりでフォームアプリでも作ることになるかな。
それはまたそのうち。
理由
監視カメラとするにはやはりレスポンスは早くありたい。
空き巣が去った後に気づいても手遅れなのだ。
手順
LINEの登録はしているのを前提としてPCからLINE Notifyのサイトへアクセス。
自身のLINE-IDでログイン。
アクセストークンを発行する。
コード:
import requests #LINE-Notifyの設定 url = "https://notify-api.line.me/api/notify" token = "ここに発行したトークンを書く" headers = {"Authorization" : "Bearer "+ token} message = "動体検知しました。" payload = {"message" : message} #LINEに画像を送信 files = {"imageFile":open('capture.jpg','rb')} post = requests.post(url,headers = headers ,params = payload,files = files)
送信するファイル名は前記事の保存ファイル名と同じにしてある。
画像送信部分のプログラムを画像保存後に記述すればOK。
結果
終わりに
時間帯に寄っては通知が鳴り止まなかったり・・・(通勤・通学時間とか)
→対策としては時間帯によって閾値を変更させればある程度緩和できるかな。
暗視はできないので夜になると当然見づらい。そして車のライトで先に反応してしまう等の問題もある。
→暗視タイプを使う。暗い時間帯はタイマーを長く設定するとか。
玄関周辺だけ写せればいいんだけど電源の取り出しとか配置が難しかったり。
→これは頑張って電源引っ張ったり防水ケースで屋外に取り付けるしかないかも。
ともあれここまでできれば後はどうにでもできそうなのでこれにて了。
やりたいこと
動体検知して自動撮影。
動画だと容量喰うし、周期撮影で監視すると無駄な撮影が多くなる為。
方法
以前の記事でOpenCVは導入済みなのでOpenCVの便利な機能を利用する。
例によって同じことをやる人はたくさんいるので検索すればどうにかなる。
import cv2 import time def main(): #カメラのキャプチャを開始 cap = cv2.VideoCapture(0) #フレームの初期化 frame1 = frame2 = frame3 = get_img(cap) #閾値の設定 th = 300 timer = 0 while True: #Enterキーが押されたら終了 if cv2.waitKey(1) == 13: break #差分チェック diff = chk_img(frame1, frame2, frame3) cnt = cv2.countNonZero(diff) #差分がthの値以上なら動きがあったと判定 if cnt > th: print(str(cnt)+":"+str(timer)) timer += 1 cnt = 0 #閾値オーバーの状態が2秒くらい続いたら撮影 if timer > 20: print("動体検知しました") #cv2.imshow('PUSH ENTER KEY', frame3) cv2.imwrite('capture.jpg', frame3) #フレームリセット frame1 = frame2 = frame3 = get_img(cap) timer = 0 #連写防止の為10秒待機 time.sleep(10) #フレーム更新 frame1, frame2, frame3 = (frame2, frame3, get_img(cap)) else: #cv2.imshow('PUSH ENTER KEY', diff) #フレーム更新 frame1, frame2, frame3 = (frame2, frame3, get_img(cap)) cnt = 0 timer = 0 #停止処理 cap.release() cv2.destroyAllWindows() # 画像に動きがあったか調べる関数 def chk_img(frame1, frame2, frame3): # グレースケール変換 gray1 = cv2.cvtColor(frame1, cv2.COLOR_RGB2GRAY) gray2 = cv2.cvtColor(frame2, cv2.COLOR_RGB2GRAY) gray3 = cv2.cvtColor(frame3, cv2.COLOR_RGB2GRAY) # 絶対差分を調べる diff1 = cv2.absdiff(gray1, gray2) diff2 = cv2.absdiff(gray2, gray3) # 論理積を調べる diff_and = cv2.bitwise_and(diff1, diff2) # 白黒二値化 _, diff_wb = cv2.threshold(diff_and, 30, 255, cv2.THRESH_BINARY) # ノイズの除去 diff = cv2.medianBlur(diff_wb, 5) return diff # カメラから画像を取得する関数 def get_img(cap): img = cap.read()[1] img = cv2.resize(img, (600, 400)) return img main()
結果
検知直後に保存すると早すぎるのでタイマーで遅らせて撮影。
閾値を小さくすれば人や動物のような小さな動体も撮影できた。
あまり小さくすると降雪とかゴミが飛んできても検知してしまうかも。
上記のコードだとファイル名が固定なので撮影の度に上書きされる。
ファイル名に日付を付けてフォルダに分けて保存するのもいいかもしれない。
やりたいこと:
定点で何かを観測・観察・監視するとか。
理由:
ドラレコもそうだけどWebカメラを持て余していたから何かに使いたい。
手順:
コードを書く。
import cv2 cap = cv2.VideoCapture(0) ret,frame = cap.read() cv2.imwrite('img.jpg',frame) cap.release() cv2.destroyAllWindows()
最低限の記述でこんな感じかな。
任意のファイル(capture.py)をディレクトリに置いてpython capture.pyと実行すれば同じフォルダにimp.jpgが保存されているはず。
あとはプログラミングの知識さえ詰め込めばいろいろ応用できると思う。
・ラズパイのGPIOを使ってシャッターボタンを付ける。
・時刻を読み込んで一定周期で撮影する。
・rc.localやcronを使えば起動時に自動実行もできる。
・ファイル名に日付や連番を付ける。
・無制限に保存されないように枚数制限や容量制限の条件を付ける。
・以前作成したWebサーバーを保存先にすれば外出先から監視できる。etc...
【追記】
わざわざWebサーバーに保存して見に行かなくても自身のLINEへ送れば良いという結論に至る。(方法は別記事)
保存先もLINEサーバー上(1GB)なのでこれも気にしなくてよい。スマホから削除できる。
OpenCVの機能で画像内に日付を入れればファイル名も気にしなくて良い。LINEの通知時間でも分かるし。
しかし折角Webサーバー立てたので別のことに役立てるつもり。いい勉強になった。
終わりに:
上記の例を一通りやってみたけど中々楽しい。
動物や植物、空模様の観測なんかは一定周期でいいかな。
監視カメラは動体検知にしないと無駄に枚数が増える。
動体検知や文字認識はまだやったことがないのでやってみたい。
やりたいこと:
OpenCVを導入して画像・映像処理をしたい。
手順:
■スワップ領域の拡張(重要)
1.設定ファイルを開く
sudo nano /etc/dphys-swapfile2.編集・保存
CONF_SWAPSIZE=1024(#を外して100→1024に変更)3.反映
sudo /etc/init.d/dphys-swapfile restart4.確認
swapon -sスワップ領域を確保しておかないとメモリ不足で強制終了することがある。
■依存パッケージのインストール
sudo apt install -y build-essential cmake pkg-config sudo apt install -y libjpeg-dev libtiff5-dev libjasper-dev libpng-dev sudo apt install -y libavcodec-dev libavformat-dev libswscale-dev libv4l-dev sudo apt install -y libxvidcore-dev libx264-dev sudo apt install -y libgtk-3-dev sudo apt install -y libatlas-base-dev gfortran sudo apt install -y libgstreamer1.0-dev参考サイトで見たlibqtgui4だとか libqt4-testはパッケージが見つからないので無視。
■opencv-pythonとnumpyのインストール
sudo pip3 install numpy opencv-python
■放置して待つ
筆者の場合は約2時間半くらい。
Successfully installed opencv-python~・・・的なメッセージが出ればOK。
途中で真っ赤なエラー文字が流れたりしたら何かパッケージが足りないのかも。
おわりに:
OpenCVのインストールはラズパイユーザー最初の難関ではなかろうか。
数時間かかる上にエラーが出てやり直しする羽目になったり。
とりあえず上記の方法で上手くいったのでココに残しておく。
検索するとソースからビルドするほうがデバッグしやすいだとか最新の状態を導入できるだとかあるみたいだけど手初めにはこれでいいかなと。
無料のDDNSサービスに登録:
1.mydns.jp へアクセス。cronを用いたIPアドレスの自動通知:
cronとは指定した時間に指定のプログラムを実行してくれる常駐プログラムのこと。終わりに:
これで運用に必要な設定はほぼ終わりかな。