Memo

メモ > 技術 > 開発: RaspberryPi

■Raspberry Pi
■概要 Raspberry Pi - Wikipedia https://ja.wikipedia.org/wiki/Raspberry_Pi ■OS OSはRaspberry Pi OSを利用できる(2020年5月にRaspbianから改名された) Raspberry Pi OSはDebianベースなので、同じくDebianベースであるUbuntuの操作は参考にできる CentOSとUbuntuの比較まとめ【2つのディストリビューションの違いとは?】 https://eng-entrance.com/linux-centos-ubuntu
■購入
■Raspberry Pi 3 Model b+ 2019年8月に購入 ABOX Raspberry Pi 3 Model b+ ラズベリーパイ 3 b+ MicroSDHCカード32G/NOOBSシステムプリインストール/カードリーダ /5V/3A スイッチ付電源/高品質HDMIケーブルライン/ヒートシンク /簡単に取り付けケース /日本語取扱説明書/24ヶ月保証 https://www.amazon.co.jp/gp/product/B07FQ9678G これ1冊でできる! ラズベリー・パイ 超入門 改訂第5版 Raspberry Pi 1+/2/3(B / B+)/Zero/Zero W対応 https://www.amazon.co.jp/dp/4800712246 性能は以下のとおり CPU: Broadcom BCM2837B0 CPUクロック: 1.4GHz メモリ: 1GB ■Raspberry Pi 4 4B-32GB 2020年9月に購入 LABISTS Raspberry Pi 4 4B-32GB(技適マーク入) MicroSDHCカード32G/Raspbianシステムプリインストール/カードリーダ /5.1V/3A Type-C スイッチ付電源/MicroHDMI-to-HDMIケーブルライン/三つヒートシンク/簡単に取り付けケース /日本語取扱説明書/24ヶ月保証 https://www.amazon.co.jp/gp/product/B082VVJCPT ゼロからよくわかる! ラズベリー・パイで電子工作入門ガイド Raspberry Pi 4 Model B対応[改訂2版] https://www.amazon.co.jp/gp/product/B08F74WBWS 性能は以下のとおり CPU: Broadcom BCM2711 CPUクロック: 1.5GHz メモリ: 4GB
■初期設定
■接続 ※書籍のとおりに進めて設定できた MicroSDカードを Raspberry Pi 本体にセット(読み取り金属部分がある方が上)し、 USBでキーボードとマウスを接続し、 HDMIでディスプレイ(TV)を接続し、 電源に接続した。 なお、Raspberry Pi 4 4B-32GB にはヒートシンクが付属していたので、最初に取り付けた Raspberry Pi 4の場合、用途によってはCPUを含んだ心臓部のチップの発熱が大きくなるため、取り付けておくといいらしい 趣味から仕事まで使える!Raspberry Pi(ラズパイ)の使い方とオススメキット | fabcross https://fabcross.jp/topics/beginner_guide/20200917_raspberrypi_guide.html ■初期設定(Raspberry Pi 3 Model b+) 電源に接続すると Raspberry Pi が起動する OSのインストーラが表示されるので、「Language」を「日本語」にする インストールするOSを選択する。特に理由がなければ、「RECOMMENDED」になっている「Raspbian」をインストールする インストールが完了して再起動すると、初期設定ウインドウが表示される。以下のように順次設定する Country: Japan Language: Japanese Timezone: Tokyo Password: (任意のパスワード) WiFi: (必要に応じて選択) Update Software の画面が表示されたら Next をクリックしてアップデートしておく アップデートは Skip できるが、日本語関連パッケージを導入するためにもアップデートしておくのが無難 アップデートが完了したら、Raspberry Pi を再起動して完了 セットアップ完了画面にIPアドレスが 192.168.1.114 と表示された(DHCP) 今回は有線LANで接続しているので、WiFiは選択しなかった 書籍にはコンソールでは日本語が正しく表示されないとあるが、問題なく表示された ■初期設定(Raspberry Pi 4 4B-32GB) 電源に接続すると、初期設定ウインドウが表示される。以下のように順次設定する Country: Japan Language: Japanese Timezone: Tokyo Password: (任意のパスワード) WiFi: (必要に応じて選択) Update Software の画面が表示されたら Next をクリックしてアップデートしておく アップデートは Skip できるが、日本語関連パッケージを導入するためにもアップデートしておくのが無難 アップデートが完了したら、Raspberry Pi を再起動して完了 WiFiアイコン部分にマウスオーバーすると、IPアドレスが 192.168.1.104 と表示された(DHCP) ■初期設定(Raspberry Pi 5) 未検証だが、以下は参考になりそう 「Raspberry Pi 5」にOSをインストールして超小型デスクトップPCとして使えるようにする手順を初心者にも分かりやすくまとめてみた - GIGAZINE https://gigazine.net/news/20231102-raspberry-pi-5-install-boot/ ■固定IPアドレス設定 上メニューのWiFiアイコンを右クリックし、「Wireless & Wired Network Setting」を選択 Configureで「interface」の「eth0」を選択し、以下のように設定 IPv4 Address: 192.168.1.201/32 (固定したいIPアドレスを入力) Router: 192.168.1.253 (デフォルトゲートウェイを入力) DNS Servers: 192.168.1.253 (デフォルトゲートウェイを入力) 設定したら「適用」をクリックし、その後 Raspberry Pi を再起動するとIPアドレスが設定される 今回の場合、IPアドレスは 192.168.1.201 になる DHCPに戻したい場合、上記の設定をすべて空欄にして再起動する ※IPアドレスの固定が難しい場合、ホスト名を設定してその名前でアクセスするのも有効 ■無線LANで固定IPアドレス設定 有線LANで接続していたが、LANケーブルが邪魔になってきたので無線LANでの接続に変更 無線LANの場合でもIPアドレスを固定しておく WiFiアイコンアイコンをクリックし、アクセスポイントを選択して無線LANに接続する WiFiアイコンアイコンを右クリックし、「Wireless & Wired Network Setting」を選択 Configureで「interface」の「wlan0」を選択し、「固定IPアドレス設定」のときと同様に設定 設定したら「適用」をクリックし、その後 Raspberry Pi を再起動するとIPアドレスが設定される DHCPに戻したい場合、上記の設定をすべて空欄にして再起動する ※IPアドレスの固定が難しい場合、ホスト名を設定してその名前でアクセスするのも有効 ■SSHでアクセス デスクトップ左上のラズベリーパイアイコンがメインメニュー。以下「メインメニュー」と表記 メインメニュー → 設定 → Raspberry Pi の設定 → インターフェイス → SSH で「有効」を選択して「OK」をクリック これでSSHで接続できるようになる 一例だが、以下の情報でSSH接続できる Poderosaで接続できない場合、Poderosaを最新版にする(Ver4でも最新版なら接続できた) 接続先:192.168.1.201 ポート:22 ユーザ名:pi パスワード:raspberry ■VNCでアクセス メインメニュー → 設定 → Raspberry Pi の設定 → インターフェイス → VNC で「有効」を選択して「OK」をクリック 画面の右上に「VNC」アイコンが表示される これでVNCで接続できるようになる Download VNC Viewer | VNC Connect https://www.realvnc.com/en/connect/download/viewer/ 上のサイトから「Windows」「EXE x86/x64」が選択されていることを確認して「Download VNC Viewer」をクリック ダウンロードしたファイルを実行すると、インストーラーが起動する 「Select the language to use during the installation」で言語を選択できるが、「English」のまま「OK」をクリック ウィザードが開始されるので「Next」をクリック ライセンスが表示されるので「I accept the terms in the License Agreement」にチェックを入れて「Next」をクリック カスタムセットアップが表示されるので「Desctop Shortcut」の左にあるアイコンをクリックし、「Will be installed on local hard drive」を選択して「Next」をクリック インストールの確認が表示されるので「Install」をクリック 完了画面が表示されたら「Finish」をクリック デスクトップに作成された「VNC Viewer」を実行 画面上部の入力欄に、対象 Raspberry Pi のIPアドレスを入力してEnter 対象 Raspberry Pi のユーザ名とパスワードを入力し、「Remember password」にチェックを入れて「OK」をクリック Raspberry Pi のGUI画面が表示されれば成功 画面が表示されない場合、Raspberry Pi にディスプレイを接続した状態で Raspberry Pi を再起動する その後、再度接続を試してみる また、VNC Viewerで画面を表示できるのは、起動時にディスプレイが接続されていた場合のみ…かもしれない 以下に対処方法が書かれてはいるが、解消はできなかった 「初心者のラズパイ勉強日記その3.5」Cannot currently show the desktopの解決法 https://white-sesame.jp/archives/blog/2472 ラズパイのVNC接続で「Cannot currently show the desktop」エラーに対応する https://blog.ko31.com/202004/respond-to-cannot-currently-show-the-desktop-error-for-vnc-connection-i... ■ホスト名を変更 以下は raspberrypi から myserver に変更する場合
$ sudo vi /etc/hostname
raspberrypi ↓ myserver
$ sudo vi /etc/hosts
127.0.1.1 raspberrypi ↓ 127.0.1.1 myserver
$ sudo shutdown -r now
Raspberry Piのホスト名を変更する - Qiita https://qiita.com/naoyukisugi/items/66fd21512da75b437465 ■Cronを使用 Raspberry Pi でCronを使用する場合、若干の準備が必要 初期設定ではログが記録されないので、以下の設定を行う
$ sudo vi /etc/rsyslog.conf
#cron.* /var/log/cron.log ↓ cron.* /var/log/cron.log
$ sudo service rsyslog restart
これでログが記録されるが、 エラーがあっても以下のように「MTAが無いので通知できない」となる
$ vi /var/log/cron.log
Sep 8 15:25:01 raspberrypi CRON[2346]: (pi) CMD ( /home/pi/shoot.py) Sep 8 15:25:01 raspberrypi CRON[2342]: (CRON) info (No MTA installed, discarding output)
以下のようにして、postfixをインストールする 用途を確認されるが、Cronを使うだけなら「ローカルのみ」で名前もデフォルトのままで良さそう
$ sudo apt-get install postfix
Cronにエラーがあると、以下のように通知される
$ cd 新しいメールが /var/mail/pi にあります $ vi /var/mail/pi
/bin/sh: 1: /home/pi/shoot.py: Permission denied
一例だが以下のように設定することで、Cronで定期処理ができる
$ sudo vi /etc/crontab
* * * * * pi python /home/pi/shoot.py
RaspberryPi3で初めてcrontabを使う前に - Qiita https://qiita.com/Higemal/items/5a579b2701ef7c473062 Raspberry Piでcronを使った時の話し - Qiita https://qiita.com/ha_ru_ma_ki/items/44e1976ddf82533ba73d ■再起動
$ sudo reboot
もしくは以下
$ sudo shutdown -r now
■シャットダウン
$ sudo poweroff
もしくは以下
$ sudo shutdown -h now
Raspberry Piをできるだけ楽にシャットダウンする方法まとめ - Qiita https://qiita.com/takeaship/items/17187673a5a0125e5811
■ファイル共有
書籍を参考に作業 後から書かれた記事だが、以下も参考になりそう ラズパイで自宅ファイルサーバを作る (1/2) - ITmedia NEWS https://www.itmedia.co.jp/news/articles/2002/09/news012.html Sambaをインストール インストール途中に「DHCP から WINS 設定を使うよう smb.conf を変更しますか?」と表示されるが、 最新のWindows10では不要らしいのでデフォルトのまま「いいえ」で進める
$ sudo apt-get update $ sudo apt install samba samba-common-bin $ sudo mkdir /var/samba
共有フォルダへアクセスするユーザを作成
$ sudo useradd smbuser $ sudo passwd smbuser YiM3Na9BdT
外部からRaspberry Piにアクセスするユーザを作成 ここでは、先に作成した smbuser を利用するものとする
$ sudo chown smbuser:smbuser /var/samba $ sudo pdbedit -a smbuser YiM3Na9BdT
設定すると以下が表示される
Unix username: smbuser NT username: Account Flags: [U ] User SID: S-1-5-21-1144376702-3029869049-2651620308-1000 Primary Group SID: S-1-5-21-1144376702-3029869049-2651620308-513 Full Name: Home Directory: \\raspberrypi\smbuser HomeDir Drive: Logon Script: Profile Path: \\raspberrypi\smbuser\profile Domain: RASPBERRYPI Account desc: Workstations: Munged dial: Logon time: 0 Logoff time: never Kickoff time: never Password last set: 日, 29 9月 2019 14:37:01 JST Password can change: 日, 29 9月 2019 14:37:01 JST Password must change: never Last bad password : 0 Bad password count : 0 Logon hours : FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
設定ファイルの末尾に以下を追加
$ sudo vi /etc/samba/smb.conf
[Share] comment = Share Directory browseable = yes path = /var/samba writable = yes valid users = smbuser force user = smbuser
Sambaを再起動して完了
$ sudo service smbd restart
■Windows10からアクセス エクスプローラのアドレス入力欄に「\\192.168.1.201」と入力してEnterを入力する 認証ダイアログが表示されるので、ユーザ名とパスワードを入力して「OK」をクリックする 表示したいボリューム(「Share」など)を開く Sambaのインストールと設定と接続 https://www.hiramine.com/physicalcomputing/raspberrypi3/samba_installconfigconnect.html 「Sambaの有効化」「ネットワークドライブの割り当て」 などをしないとアクセスできない…と紹介されている記事もあるが、上記手順のみでアクセスできた ■MacOSXからアクセス Finderの「移動 → サーバへ接続」を選択 「サーバアドレス」に「smb://」とともにRaspberry Pi のIPアドレスを入力して「OK」をクリックする 具体的には「smb://192.168.1.201」のように入力する 認証ダイアログが表示されるので、「ユーザの種類」を「登録ユーザ」にし、ユーザ名とパスワードを入力して「接続」をクリックする 表示したいボリューム(「Share」など)を選択して「OK」をクリックする
■Webサーバ
■HTTPDでアクセス
$ sudo apt-get install apache2 ... Apacheをインストール $ apache2 -v ... Apacheのバージョンを確認 $ sudo service apache2 start ... Apacheを起動 $ sudo service apache2 stop ... Apacheを停止させる場合 $ sudo service apache2 restart ... Apacheを再起動させる場合
完了後 http://127.0.0.1/ にアクセスすると /var/www/html/index.html が表示される http://localhost/ もしくは http://raspberrypi/ でもアクセスできる Raspberry Pi 3 に Apache 2.4 + PHP 7.0 をインストール | スモールサーバ開発部 https://blog.smallserver.jp/raspberry-pi-3-%E3%81%AB-apache-2-4-php-7-0-%E3%82%92%E3%82%A4%E3%83%B3%... Apacheの設定は以下も参考になる RaspbianにおけるApache2の設定 - Qiita https://qiita.com/takey/items/75e6984468f0f6870a97 ■PythonをCGIとして実行 【Python 3.6】Linux+AnacondaでCGIを動かそう | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト https://www.sejuku.net/blog/62938
# ln -s /etc/apache2/mods-available/cgi.load /etc/apache2/mods-enabled/cgi.load # service apache2 restart # cd /usr/lib/cgi-bin # vi sample.py
#!/usr/bin/env python # -*- coding: utf-8 -*- import cgi import cgitb cgitb.enable() print("Content-Type: text/html") # HTML is following print("") # blank line, end of headers print("<TITLE>CGI script output</TITLE>") print("<H1>This is my first CGI script</H1>") print("Hello, world!")
chmod +x /usr/lib/cgi-bin/sample.py
以下のようにアクセスすると、「This is my first CGI script」と表示される http://raspberrypi/cgi-bin/sample.py ■CGI置き場を /var/www/cgi-bin に変更
# mkdir /var/www/cgi-bin # vi /etc/apache2/conf-enabled/serve-cgi-bin.conf
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ ↓ ScriptAlias /cgi-bin/ /var/www/cgi-bin/
# service apache2 restart
これで /var/www/cgi-bin に置いたものが /cgi-bin に反映される ■基本的なCGIプログラム
# vi /var/www/cgi-bin/test.py
#!/usr/bin/env python3.7 # coding: utf-8 # -*- coding: utf-8 -*- import sys,io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') print("Content-Type: text/html; charset=UTF-8\n") print("<!DOCTYPE html>") print("<html>") print("<head>") print("<meta charset=\"utf-8\">") print("<title>Python</title>") print("</head>") print("<body>") print("<h1>Python</h1>") print("<p>これはPythonの実行結果です。</p>") print("</body>") print("</html>")
# chmod 755 /var/www/cgi-bin/test.py
※2〜6行目は無くても表示された ※FTPソフトで転送する場合、アスキーモードで転送する
■GPIO
■LEDの点灯 「time.sleep(1)」が無いと、「GPIO.cleanup()」によってLEDの状態がすぐに初期化されてしまうみたい
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) GPIO.setup(4, GPIO.OUT) GPIO.output(4, GPIO.HIGH) time.sleep(1) GPIO.cleanup() print("Hello! LED!")
■LEDの点滅
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) GPIO.setup(4, GPIO.OUT) while True: GPIO.output(4, GPIO.HIGH) time.sleep(1) GPIO.output(4, GPIO.LOW) time.sleep(1)
■ファイルの内容に従ってLEDを点灯
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) GPIO.setup(4, GPIO.OUT) try: while True: led_status = open("led_status.txt", "r") status = led_status.read() led_status.close() if status == "1": GPIO.output(4, GPIO.HIGH) time.sleep(1) GPIO.output(4, GPIO.LOW) time.sleep(1) except KeyboardInterrupt: GPIO.cleanup()
以下のようにすると、プログラムをバックグラウンドで実行&停止できる
$ python led_loop.py & [1] 2646 $ ps aux | grep python pi 2646 0.8 0.5 8596 5292 pts/1 S 23:12 0:00 python led_loop.py pi 2648 0.0 0.0 3916 584 pts/1 S+ 23:12 0:00 grep --color=auto python $ kill 2646
Linuxコマンド(Bash)でバックグラウンド実行する方法のまとめメモ - Qiita https://qiita.com/inosy22/items/341cfc589494b8211844
■写真の撮影
ラズパイで写真を撮る! カメラモジュールを接続してカスタマイズするには (1/2) - ITmedia NEWS https://www.itmedia.co.jp/news/articles/1907/13/news009.html 上の記事を参考に、以下のカメラモジュールを購入した Raspberry Pi Camera Module V2 カメラモジュール (Daylight - element14) https://www.amazon.co.jp/gp/product/B01ER2SKFS 以下、カメラで撮影するまでの手順 CSI端子(カメラ用の端子)の両端にある突起を上に持ち上げると、カメラモジュールのフィルムケーブルを差し込めるようになる フィルムケーブルの端子側をHDMI端子側に向けて、斜めにならないように奥まで差し込む CSI端子の持ち上げた部分を押し込んでもとに戻せば接続完了 次に Raspberry Pi でカメラモジュールを使用できるようにする 以下のコマンドを実行して、Raspberry Pi のファームウェアをアップデートする
$ sudo rpi-update
アップデートが完了したら、Raspberry Pi を再起動する 起動したら Raspberry Pi の設定を変更して、カメラモジュールを使えるようにする メインメニュー → 設定 → Raspberry Pi の設定 → インターフェイス → カメラ を「有効」に設定し、「OK」をクリックする Raspberry Pi も再起動を求められるので再起動する これでカメラでの撮影ができる。撮影は以下のコマンドで行う 以下で detected が 1 になっていればカメラを認識している 0 になっている場合、カメラを正しく取り付けられているかなどを確認する (奥まで差し込まれているか、表裏が逆になっていないか、など)
$ vcgencmd get_camera supported=1 detected=1 $ raspistill -o photo.jpg
以下のコマンドで画像を表示できる。画像はGUIで表示される (GUIから画像をダブルクリックで開いても問題ない)
$ gpicview photo.jpg
■プログラムでの撮影
$ cd $ mkdir camera $ vi shoot.py
import picamera import time camera = picamera.PiCamera() camera.resolution = (640,480) camera.capture("./camera/" + time.strftime("%Y%m%d%H%M%S") + ".jpg")
以下のように実行するたびに撮影ができる
$ python shoot.py
一例だが以下のように設定することで、定期的に自動撮影ができる
$ sudo vi /etc/crontab
* * * * * pi python /home/pi/shoot.py
■動画の撮影
$ raspivid -o movie.h264 -t 5000
movie.h264 に5秒の動画ファイルが保存される Raspberry Piカメラモジュールで動画撮影・PCで見られるようにmp4に変換する方法 - Qiita https://qiita.com/karaage0703/items/48b48680a35936ab83f3 ■h264形式をmp4形式に変換
$ sudo apt-get update $ sudo apt-get install -y gpac $ MP4Box -fps 30 -add movie.h264 movie.mp4
movie.h264 をもとに movie.mp4 が作成される ■プログラムでの撮影
$ cd $ mkdir camera $ vi record.py
import picamera import time camera = picamera.PiCamera() camera.resolution = (640,480) camera.start_preview() time.sleep(2) camera.start_recording("./camera/" + time.strftime("%Y%m%d%H%M%S") + ".h264") camera.wait_recording(5) camera.stop_recording() camera.stop_preview()
以下のように実行すると、5秒の動画が保存される
$ python record.py
必要に応じて、h264形式をmp4形式に変換する
$ MP4Box -fps 30 -add ./camera/20200926131549.h264 ./camera/20200926131549.mp4
Raspberry pi とカメラモジュールを使った画像保存(とおまけに動画) - Qiita https://qiita.com/luren/items/ab3700394faab7422bb3
■動画のストリーミング配信
$ sudo apt-get update $ sudo apt-get upgrade $ sudo apt-get install -y cmake libv4l-dev libjpeg-dev imagemagick $ git clone https://github.com/jacksonliam/mjpg-streamer.git $ cd mjpg-streamer/mjpg-streamer-experimental $ make $ sudo make install $ sudo /usr/local/bin/mjpg_streamer -i "input_uvc.so -f 30 -r 640x480 -d /dev/video0 -q 80" -o "output_http.so -p 8080 -w /usr/local/share/mjpg-streamer/www" MJPG Streamer Version: git rev: 85f89a8c321e799fabb1693c5d133f3fb48ee748 i: Using V4L2 device.: /dev/video0 i: Desired Resolution: 640 x 480 i: Frames Per Second.: 30 i: Format............: JPEG i: TV-Norm...........: DEFAULT UVCIOC_CTRL_ADD - Error at Pan (relative): Inappropriate ioctl for device (25) UVCIOC_CTRL_ADD - Error at Tilt (relative): Inappropriate ioctl for device (25) UVCIOC_CTRL_ADD - Error at Pan Reset: Inappropriate ioctl for device (25) UVCIOC_CTRL_ADD - Error at Tilt Reset: Inappropriate ioctl for device (25) UVCIOC_CTRL_ADD - Error at Pan/tilt Reset: Inappropriate ioctl for device (25) UVCIOC_CTRL_ADD - Error at Focus (absolute): Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Pan (relative): Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Tilt (relative): Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Pan Reset: Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Tilt Reset: Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Pan/tilt Reset: Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Focus (absolute): Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at LED1 Mode: Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at LED1 Frequency: Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Disable video processing: Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Raw bits per pixel: Inappropriate ioctl for device (25) o: www-folder-path......: /usr/local/share/mjpg-streamer/www/ o: HTTP TCP port........: 8080 o: HTTP Listen Address..: (null) o: username:password....: disabled o: commands.............: enabled
「UVCIOC_CTRL_ADD - Error」が表示されているが、動作には問題ないみたい 以下にアクセスし、左メニューから「Stream」を選択するとカメラの動画を表示できる http://192.168.1.202:8080/ もしくは、以下にアクセスすれば動画を直接取得できる http://192.168.1.202:8080/?action=stream Raspberry Pi ×カメラモジュールで動画配信(ストリーミング)してみる - 自作のいろいろ https://garchiving.com/streamed-on-raspberry-pi/ Raspberry Pi3にmjpg-streamerを入れる - Qiita https://qiita.com/lobmto/items/c31e0c8136c16f75b1cd ■動画の回転 以下のように「-rot 180」を指定すれば、上下回転して表示できる
$ sudo /usr/local/bin/mjpg_streamer -i "input_uvc.so -f 30 -r 640x480 -rot 180 -d /dev/video0 -q 80" -o "output_http.so -p 8080 -w /usr/local/share/mjpg-streamer/www"
Raspberry Pi B で監視カメラ | n10の個人的なメモ https://mirahouse.jp/n10/blog/2019/raspberry-pi-b-camera/ 終了させたい場合、Ctrl+C を入力する ■JavaScriptで動画を表示 ※未検証 RasPi:MJPG-streamer動画配信で遊んでみた - Qiita https://qiita.com/MuAuan/items/b3abd4cff2f39aa1f2d0 ■トラブル 以下はパスを間違えて起動できない例
$ sudo /usr/local/bin/mjpg_streamer -i "./input_uvc.so -f 30 -r 640x480 -d /dev/video0 -q 80" -o "output_http.so -p 8080 -w ./www" MJPG Streamer Version: git rev: 85f89a8c321e799fabb1693c5d133f3fb48ee748 ERROR: could not find input plugin Perhaps you want to adjust the search path with: # export LD_LIBRARY_PATH=/path/to/plugin/folder dlopen: ./input_uvc.so: cannot open shared object file: No such file or directory
■OpenCV
Raspberry Pi + Python 3 に OpenCV 3 をなるべく簡単にインストールする - Qiita https://qiita.com/masaru/items/658b24b0806144cfeb1c 以下でライブラリをインストール(それぞれ、すぐに完了した)
$ sudo apt-get install -y libhdf5-dev libhdf5-serial-dev $ sudo apt-get install -y libqtgui4 libqtwebkit4 libqt4-test python3-pyqt5 $ sudo apt-get install -y libatlas-base-dev $ sudo apt-get install -y libjasper-dev
以下でOpenCVをインストール(1時間15分ほどかかった)
$ sudo pip3 --default-timeout=1000 install opencv-python
この時点で、拡張モジュール群である opencv-contrib-python も一緒にインストールしておくといい(これはすぐにインストールできる) opencv-contrib-python をインストールして「import cv2」でエラーになる場合、後述の「opencv-contrib-python をインストールするとエラーになる」を参照
$ sudo pip3 --default-timeout=1000 install opencv-contrib-python
以下で動作確認 あらかじめ test.jpg は配置しておく canny.jpg に加工済みの画像が書き出される
$ python3 Python 3.7.3 (default, Apr 3 2019, 05:39:12) [GCC 8.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> cv2.__version__ '3.4.3' >>> bgr = cv2.imread('./test.jpg', cv2.IMREAD_COLOR) >>> gray = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY) >>> canny = cv2.Canny(gray, 200, 50) >>> cv2.imwrite('./canny.jpg', canny) True >>> exit()
2019年9月に試すと、上記のとおり3.4.3がインストールされた 2020年9月に試すと、4.4.0がインストールされた ■ライブラリインストール時のエラー 「ライブラリをインストール」で参考URLと同じコマンドを実行すると、以下のエラーになった 単純に、エラーになった libhdf5-100 を省くとインストールできたが、正しい方法かどうかは不明
$ sudo apt-get install libhdf5-dev libhdf5-serial-dev libhdf5-100 パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 注意、'libhdf5-serial-dev' の代わりに 'libhdf5-dev' を選択します パッケージ libhdf5-100 は使用できませんが、別のパッケージから参照されます。 これは、パッケージが欠落しているか、廃止されたか、または別のソース からのみ利用可能であることを意味します。 しかし、以下のパッケージが置き換えます: libhdf5-103 E: パッケージ 'libhdf5-100' にはインストール候補がありません
■opencv-contrib-python をインストールするとエラーになる ラズパイでpython3にopencvを入れたらエラーが出た【対処法】 - Qiita https://qiita.com/XM03/items/48463fd910470b226f22 必要なライブラリをインストール
$ sudo pip3 --default-timeout=1000 install opencv-contrib-python
インストールすると、「import cv2」でエラーになるようになった
>>> import cv2 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python3.7/dist-packages/cv2/__init__.py", line 3, in <module> from .cv2 import * ImportError: /usr/local/lib/python3.7/dist-packages/cv2/cv2.cpython-37m-arm-linux-gnueabihf.so: undefined symbol: __atomic_fetch_add_8
以下で対処する
$ LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1 $ vim.tiny .bashrc
export LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1 … 最終行に追加
$ source .bashrc $ python3 Python 3.7.3 (default, Jul 25 2020, 13:03:44) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> cv2.__version__ '4.1.1' >>> exit()
■プログラムを作成して実行
$ vi test.py
import cv2 bgr = cv2.imread('./camera/test.jpg', cv2.IMREAD_COLOR) gray = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY) canny = cv2.Canny(gray, 200, 50) cv2.imwrite('./camera/test_canny.jpg', canny)
$ python3 test.py
■画像をウインドウに表示 opencv - Python で cv2.imshow としても画像が表示されない - スタック・オーバーフロー https://ja.stackoverflow.com/questions/31537/python-%E3%81%A7-cv2-imshow-%E3%81%A8%E3%81%97%E3%81%A6...
import cv2 img = cv2.imread('lena.png', 0) cv2.imshow('image',img) cv2.waitKey(0) cv2.destroyAllWindows()
SSH経由で実行しても以下のエラーになる(Raspberry Pi 内のターミナルからなら表示できる) Unable to init server: Could not connect: 接続を拒否されました (image:9950): Gtk-WARNING **: 00:46:48.398: cannot open display: ■カメラの映像をリアルタイムに表示 Python, OpenCVで動画を読み込み(ファイル・カメラ映像) | note.nkmk.me https://note.nkmk.me/python-opencv-videocapture-file-camera/
import sys import cv2 # カメラ camera_id = 0 # ウインドウ名 window_name = 'frame' # カメラの映像を取得 cap = cv2.VideoCapture(camera_id) if not cap.isOpened(): sys.exit() # リアルタイムにウインドウへ表示 while True: ret, frame = cap.read() cv2.imshow(window_name, frame) # 「q」が入力されたら終了 if cv2.waitKey(1) & 0xFF == ord('q'): break # ウインドウを閉じる cv2.destroyWindow(window_name)
白黒化とぼかしを適用
import cv2 import sys # カメラ camera_id = 0 # ウインドウ名 window_name = 'frame' # カメラの映像を取得 cap = cv2.VideoCapture(camera_id) if not cap.isOpened(): sys.exit() # リアルタイムにウインドウへ表示 while True: ret, frame = cap.read() # 白黒化とぼかしを適用 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (0, 0), 5) cv2.imshow(window_name, blur) # 「q」が入力されたら終了 if cv2.waitKey(1) & 0xFF == ord('q'): break # ウインドウを閉じる cv2.destroyWindow(window_name)
ffmpegで配信する方法もあるみたい リモートの環境のPythonからOpenCVを使い、手元のWebカメラの映像を読みたい - Qiita https://qiita.com/fukasawah/items/32ebef9cd646a1eb3e3a 引き続き、リアルタイムでの顔認識なども試したい Pythonで画像処理: Pillow, NumPy, OpenCVの違いと使い分け | note.nkmk.me https://note.nkmk.me/python-image-processing-pillow-numpy-opencv/ 画像処理をマスターしよう!PythonでOpenCVを使う方法を紹介! | TechTeacher Blog https://www.tech-teacher.jp/blog/python-opencv/ ■画像の変化を確認 ※動いているようだが、それぞれの意味は要勉強 ※定点カメラでの変化を検知できるかは要懸賞 カメラの僅かなブレなどで差分を検知してしまうか。画像を縮小してから差分を取れば、僅かな差は吸収できるか python - Pythonを使ったOpenCVでの背景差分の数値化の方法 - スタック・オーバーフロー https://ja.stackoverflow.com/questions/48019/python%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9Fopencv%E3%81%... 画像処理入門講座 : OpenCVとPythonで始める画像処理 | POSTD https://postd.cc/image-processing-101/
import cv2 import numpy as np import matplotlib.pyplot as plt # 画像を読み込み img_src1 = cv2.imread("./test/test1.jpg", cv2.IMREAD_GRAYSCALE) img_src2 = cv2.imread("./test/test2.jpg", cv2.IMREAD_GRAYSCALE) # 画像の差分を算出 img_diff = cv2.absdiff(img_src1, img_src2) # 画像の差分を二極化 img_diffm = cv2.threshold(img_diff, 20, 255, cv2.THRESH_BINARY)[1] # グレースケール画像をRGB化 img_diff = cv2.cvtColor(img_diff, cv2.COLOR_GRAY2RGB) img_diffm = cv2.cvtColor(img_diffm, cv2.COLOR_GRAY2RGB) # 画像の差分を数値化 diff_sum = np.sum(img_diffm) print(diff_sum) # 以降は結果表示 plt.subplot(1, 2, 1) # 1行に分割、2列に分割、そのうちの1つめに描画 plt.title("Diff image") plt.imshow(img_diff) plt.subplot(1, 2, 2) # 1行に分割、2列に分割、そのうちの2つめに描画 plt.title("Mask image") plt.imshow(img_diffm) plt.show()
以下も確認したい subplot | Python で一枚のプロットに複数グラフを描く方法 https://stats.biopapyrus.jp/python/subplot.html ラズパイ4 動体検知する(PYTHON+OPENCV) | KatsEye https://kats-eye.net/info/2020/06/09/motion-detect/ Python/OpenCVで動体検知!動画の動いている部分を検出 | WATLAB -Python, 信号処理, AI- https://watlab-blog.com/2019/09/26/motion-detection/ OpenCV-Pythonで似たような画像の差分を検出する - Qiita https://qiita.com/kikuyan8540/items/0c92a8ab47e84ec79652 Python+OpenCVとWebカメラを使って動体検知する話 - EnsekiTT Blog https://ensekitt.hatenablog.com/entry/2018/06/11/200000 OpenCVを利用して動画(カメラ)から動体検知をする方法について | CyberAgent Developers Blog https://developers.cyberagent.co.jp/blog/archives/12666/ 画像処理入門講座 : OpenCVとPythonで始める画像処理 | POSTD https://postd.cc/image-processing-101/ ■画像の変化をリアルタイムに確認(動体検知)
import cv2 import numpy as np import sys # カメラ camera_id = 0 # ウインドウ名 window_name = 'frame' # カメラの映像を取得 cap = cv2.VideoCapture(camera_id) if not cap.isOpened(): sys.exit() # リアルタイムにウインドウへ表示 buf_img = None while True: # 画像を取得 ret, cap_img = cap.read() # 画像をグレースケール化 gray_img = cv2.cvtColor(cap_img, cv2.COLOR_BGR2GRAY) # 初回はバッファがないので作成 if buf_img is None: buf_img = gray_img # 画像の差分を算出 img_diff = cv2.absdiff(gray_img, buf_img) # 画像の差分を二極化 img_diffm = cv2.threshold(img_diff, 20, 255, cv2.THRESH_BINARY)[1] # 画像の輪郭を抽出 contours, hierarchy = cv2.findContours(img_diffm, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) # グレースケール画像をRGB化 img_diff = cv2.cvtColor(img_diff, cv2.COLOR_GRAY2RGB) img_diffm = cv2.cvtColor(img_diffm, cv2.COLOR_GRAY2RGB) # 画像の差分を数値化 diff_sum = np.sum(img_diffm) #print(diff_sum) # 画像データを保持 buf_img = gray_img # 矩形検出された数(デフォルトで0を指定) detect_count = 0 # 各輪郭に対する処理 for i in range(0, len(contours)): # 輪郭の領域を計算 area = cv2.contourArea(contours[i]) # ノイズ(小さすぎる領域)と全体の輪郭(大きすぎる領域)を除外 if area < 100 or 10000 < area: continue # 外接矩形 if len(contours[i]) > 0: rect = contours[i] x, y, w, h = cv2.boundingRect(rect) cv2.rectangle(cap_img, (x, y), (x + w, y + h), (0, 255, 0), 2) # 外接矩形毎に画像を保存 #cv2.imwrite('test/' + str(detect_count) + '.jpg', src[y:y + h, x:x + w]) detect_count = detect_count + 1 #print(detect_count) # テキストを描画 cv2.putText( cap_img, # 描画対象 'Detected: ' + str(detect_count), # テキスト (20, 50), # 座標 cv2.FONT_HERSHEY_SIMPLEX, # フォント 1, # フォントサイズ (255,255,255), # フォントカラー 2, # フォントウェイト cv2.LINE_AA # 線の種類 ) # 画像を表示 cv2.imshow(window_name, cap_img) # 「q」が入力されたら終了 if cv2.waitKey(1) & 0xFF == ord('q'): break # ウインドウを閉じる cv2.destroyWindow(window_name)
以下のようにして通常実行できる
$ python3 camera_detection.py
以下のようにすれば、バックグラウンドで実行し続けることができる この場合、処理の停止は kill を使用する
$ nohup python3 camera_detection.py & [1] 4078 $ ps aux | grep python3 $ kill 4078
Raspberry Piで室内カメラを作る? - Qiita https://qiita.com/henjiganai/items/b491e498d7d367306cd5 Raspberry Piで最強の防犯カメラを作ってみる(動画記録・配信、動体検知・Line通知、顔検知・顔認証、Alexa搭載)[1/6] | 育児×家事×IoT https://dream-soft.mydns.jp/blog/developper/smarthome/2020/01/649/ Raspberry Piで最強の防犯カメラを作ってみる(動画記録・配信、動体検知・Line通知、顔検知・顔認証、Alexa搭載)[3/6] | 育児×家事×IoT https://dream-soft.mydns.jp/blog/developper/smarthome/2020/02/678/ RasPiCamera/Camera.py at master - naka-kazz/RasPiCamera https://github.com/naka-kazz/RasPiCamera/blob/master/camera_step3/Camera.py RaspberryPi4にYOLOv3-Tinyを実装してリアルタイム画像認識をしながら物体を自動追尾するカメラを作ってみた - Qiita https://qiita.com/daiarg/items/3da30c93b05496522acb カラー図解 Raspberry Piではじめる機械学習 補足情報: Raspberry Pi で YOLO v3-Tiny / YOLO v3 による物体検出を試してみよう https://mlbb1.blogspot.com/2019/12/raspberry-pi-yolo-v3-tiny-yolo-v3.html RaspberryPiでWEBカメラを使ってOpenCVで動体検知な監視カメラをつくってみた - Qiita https://qiita.com/hasekou_tech/items/acd0d9159a9001ebfbd3 ■画像の変化を確認(動かない) ※謎エラーのため実行できていない
$ vi test.py
import cv2 beforeImage = cv2.imread('./test/test.png', cv2.IMREAD_COLOR) beforeImage = cv2.cvtColor(beforeImage, cv2.COLOR_BGR2GRAY) grayImage = cv2.imread('./test/test.png', cv2.IMREAD_COLOR) grayImage = cv2.cvtColor(grayImage, cv2.COLOR_BGR2GRAY) cv2.accumulateWeighted(grayImage, beforeImage, 0.00001)
$ python3 test.py Traceback (most recent call last): File "test.py", line 33, in <module> cv2.accumulateWeighted(grayImage, beforeImage, 0.00001) cv2.error: OpenCV(4.4.0) /tmp/pip-wheel-frffvd08/opencv-python/opencv/modules/imgproc/src/accum.cpp:635: error: (-215:Assertion failed) func != 0 in function 'accumulateWeighted'
以下なら何かしらの結果を得られているようだが、詳細は要勉強
$ vi test.py
import cv2 import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt test1 = cv2.imread('./test/test1.jpg', cv2.IMREAD_COLOR) test1 = cv2.cvtColor(test1, cv2.COLOR_BGR2GRAY) test1= test1.astype(np.float32) test2 = cv2.imread('./test/test2.jpg', cv2.IMREAD_COLOR) test2 = cv2.cvtColor(test2, cv2.COLOR_BGR2GRAY) test2 = test2.astype(np.float32) cv2.accumulateWeighted(test1, test2, 0.01) delta = cv2.absdiff(test1, test2) thresh = cv2.threshold(delta, 50, 255, cv2.THRESH_BINARY)[1] #image, contours, h = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) #print(test1.dtype) #print(test2.dtype) #print(delta) plt.figure(figsize=(4, 4), dpi=72) plt.plot(delta) plt.savefig('test/graph.png')
ただし、findContours は引数が間違っているのかエラーになる グレースケール画像を読み込む必要がある?
Traceback (most recent call last): File "diff.py", line 18, in <module> image, contours, h = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cv2.error: OpenCV(4.4.0) /tmp/pip-wheel-frffvd08/opencv-python/opencv/modules/imgproc/src/contours.cpp:197: error: (-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function 'cvStartFindContours_Impl'
[Q&A] 二値化画像の輪郭抽出について - Qiita https://qiita.com/yutapuu/questions/c1981051051c76cede08 以降はその他メモ OpenCVで手っ取り早く動体検知してみた - Qiita https://qiita.com/K_M95/items/4eed79a7da6b3dafa96d Raspberry Piで最強の防犯カメラを作ってみる(動画記録・配信、動体検知・Line通知、顔検知・顔認証、Alexa搭載)[3/6] | 育児×家事×IoT https://dream-soft.mydns.jp/blog/developper/smarthome/2020/02/678/ 動体検知とトラッキングを組み合わせて動いてた物体を見失わないようにする話 - EnsekiTT Blog https://ensekitt.hatenablog.com/entry/2018/06/13/200000 c++ - Assertion failed with accumulateWeighted in OpenCV - Stack Overflow https://stackoverflow.com/questions/7059817/assertion-failed-with-accumulateweighted-in-opencv opencv/accum.cpp at master - opencv/opencv https://github.com/opencv/opencv/blob/master/modules/imgproc/src/accum.cpp OpenCVのチャンネルエラー対処: (-215:Assertion failed) (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1) in function 'binary_op' | 404 motivation not found https://tech-blog.s-yoshiki.com/entry/75 ■カメラの画像を取得して加工して保存
import picamera import picamera.array import cv2 camera = picamera.PiCamera() camera.resolution = (640, 480) stream = picamera.array.PiRGBArray(camera) camera.capture(stream, 'bgr', use_video_port=True) gray = cv2.cvtColor(stream.array, cv2.COLOR_BGR2GRAY) cv2.imwrite('./camera/stream.jpg', gray)
■画像の差分を抽出 背景差分で物体抽出(画像比較) - Qiita https://qiita.com/goodboy_max/items/71a3b804d14f961c0d91 以下で test1.jpg と test2.jpg の差分が diff.jpg に出力される
import cv2 # 画像の読み込み img_src1 = cv2.imread("test/test1.jpg", 1) img_src2 = cv2.imread("test/test2.jpg", 1) fgbg = cv2.bgsegm.createBackgroundSubtractorMOG() fgmask = fgbg.apply(img_src1) fgmask = fgbg.apply(img_src2) # 検出画像 bg_diff_path = 'test/diff.jpg' cv2.imwrite(bg_diff_path,fgmask) cv2.waitKey(0)
■画像を認識する Raspberry PiとOpenCVによる画像認識で人の顔を判別する | パソコン工房 NEXMAG https://www.pc-koubou.jp/magazine/19205 ■顔を検出するプログラム 【入門者向け解説】openCV顔検出の仕組と実践(detectMultiScale) - Qiita https://qiita.com/FukuharaYohei/items/ec6dce7cc5ea21a51a82
import cv2 # 分類器ディレクトリ(以下から取得) # https://github.com/opencv/opencv/blob/master/data/haarcascades/ # モデルファイル cascade_path = "haarcascade_frontalface_default.xml" # 使用ファイルと入出力ディレクトリ image_file = "face.jpg" output_file = "face_output.jpg" # ディレクトリ確認用(うまく行かなかった時用) #import os #print(os.path.exists(image_file)) #ファイル読み込み image = cv2.imread(image_file) #グレースケール変換 image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #カスケード分類器の特徴量を取得する cascade = cv2.CascadeClassifier(cascade_path) #物体認識(顔認識)の実行 #image - CV_8U 型の行列.ここに格納されている画像中から物体が検出されます #objects - 矩形を要素とするベクトル.それぞれの矩形は,検出した物体を含みます #scaleFactor - 各画像スケールにおける縮小量を表します #minNeighbors - 物体候補となる矩形は,最低でもこの数だけの近傍矩形を含む必要があります #flags - このパラメータは,新しいカスケードでは利用されません.古いカスケードに対しては,cvHaarDetectObjects 関数の場合と同じ意味を持ちます #minSize - 物体が取り得る最小サイズ.これよりも小さい物体は無視されます facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30)) #print(facerect) color = (255, 255, 255) #白 # 検出した場合 if len(facerect) > 0: #検出した顔を囲む矩形の作成 for rect in facerect: cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]), color, thickness=2) #認識結果の保存 cv2.imwrite(output_file, image)
■顔を検出するプログラム(調整+CGI版)
#!/Users/refirio/Anaconda3/python # coding: utf-8 # -*- coding: utf-8 -*- import sys import io import cv2 # 使用ファイルと入出力ディレクトリ IMAGE_FILE = "daughter.png" INPUT_PATH = "./inputs/" + IMAGE_FILE OUTPUT_PATH = "./outputs/" + IMAGE_FILE # ラインの色 COLOR_WHITE = (255, 255, 255) COLOR_RED = (0, 0, 255) # 画像ファイル読み込み image = cv2.imread(INPUT_PATH) # 画像をグレースケール変換 image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # カスケード分類器の特徴量を取得 face_cascade = cv2.CascadeClassifier("./haarcascades/haarcascade_frontalface_alt.xml") eye_cascade = cv2.CascadeClassifier("./haarcascades/haarcascade_eye.xml") # 画像の中から顔を検出 faces = face_cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=2, minSize=(50, 50)) if len(faces) > 0: # 検出した顔の座標を取得 for (face_x,face_y,face_w,face_h) in faces: # 検出した顔を囲む矩形の作成 cv2.rectangle(image, (face_x,face_y),(face_x + face_w,face_y + face_h), COLOR_WHITE, 2) # 検出した顔画像を取得 face_image = image[face_y : face_y + face_h, face_x : face_x + face_w] # 検出した顔画像をグレースケール変換 face_image_gray = image_gray[face_y : face_y + face_h, face_x : face_x + face_w] # 顔画像の中から目を検出 eyes = eye_cascade.detectMultiScale(face_image_gray, scaleFactor=1.1, minNeighbors=2, minSize=(20, 20)) if len(faces) > 0: # 検出した目の座標を取得 for (eye_x,eye_y,eye_w,eye_h) in eyes: # 検出した目を囲む矩形の作成 cv2.rectangle(face_image,(eye_x, eye_y),(eye_x + eye_w,eye_y + eye_h), COLOR_RED, 2) # 認識結果の保存 cv2.imwrite(OUTPUT_PATH, image) # 結果画面を表示 sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') print("Content-Type: text/html; charset=UTF-8\n") print("<!DOCTYPE html>") print("<html>") print("<head>") print("<meta charset=\"utf-8\">") print("<title>Python</title>") print("</head>") print("<body>") print("<h1>Python</h1>") print("<img src=\"" + OUTPUT_PATH + "\" style=\"max-width: 500px; max-height: 500px;\">") print("</body>") print("</html>")
■リアルタイムに顔認識
import cv2 import numpy as np import sys # カメラ camera_id = 0 # ウインドウ名 window_name = 'frame' # 画像の上下左右反転 flip_image = 1 # モデルファイル cascade_path = "haarcascade_frontalface_default.xml" #カスケード分類器の特徴量を取得する cascade = cv2.CascadeClassifier(cascade_path) # カメラの映像を取得 cap = cv2.VideoCapture(camera_id) if not cap.isOpened(): sys.exit() # リアルタイムにウインドウへ表示 buf_img = None while True: # 画像を取得 ret, cap_img = cap.read() if flip_image == 1: cap_img = cv2.flip(cap_img, -1) # 画像をグレースケール化 gray_img = cv2.cvtColor(cap_img, cv2.COLOR_BGR2GRAY) # 初回はバッファがないので作成 if buf_img is None: buf_img = gray_img # 画像の差分を算出 img_diff = cv2.absdiff(gray_img, buf_img) # 画像の差分を二極化 img_diffm = cv2.threshold(img_diff, 20, 255, cv2.THRESH_BINARY)[1] # 画像の輪郭を抽出 contours, hierarchy = cv2.findContours(img_diffm, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) # グレースケール画像をRGB化 img_diff = cv2.cvtColor(img_diff, cv2.COLOR_GRAY2RGB) img_diffm = cv2.cvtColor(img_diffm, cv2.COLOR_GRAY2RGB) # 画像の差分を数値化 diff_sum = np.sum(img_diffm) #print(diff_sum) # 画像データを保持 buf_img = gray_img # 矩形検出された数(デフォルトで0を指定) detect_count = 0 # 各輪郭に対する処理 for i in range(0, len(contours)): # 輪郭の領域を計算 area = cv2.contourArea(contours[i]) # ノイズ(小さすぎる領域)と全体の輪郭(大きすぎる領域)を除外 if area < 100 or 10000 < area: continue # 外接矩形 if len(contours[i]) > 0: rect = contours[i] x, y, w, h = cv2.boundingRect(rect) cv2.rectangle(cap_img, (x, y), (x + w, y + h), (0, 255, 0), 2) # 外接矩形毎に画像を保存 #cv2.imwrite('test/' + str(detect_count) + '.jpg', src[y:y + h, x:x + w]) detect_count = detect_count + 1 #print(detect_count) # テキストを描画 cv2.putText( cap_img, # 描画対象 'Detected: ' + str(detect_count), # テキスト (20, 50), # 座標 cv2.FONT_HERSHEY_SIMPLEX, # フォント 1, # フォントサイズ (255,255,255), # フォントカラー 2, # フォントウェイト cv2.LINE_AA # 線の種類 ) # 顔を検出 facerect = cascade.detectMultiScale(gray_img, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30)) if len(facerect) > 0: #検出した顔を囲む矩形の作成 for rect in facerect: cv2.rectangle(cap_img, tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]), (0, 0, 255), thickness=2) # 画像を表示 cv2.imshow(window_name, cap_img) # 「q」が入力されたら終了 if cv2.waitKey(1) & 0xFF == ord('q'): break # ウインドウを閉じる cv2.destroyWindow(window_name)
■分類器 OpenCVで顔認識とそれ以外の物体認識(カスケード分類機まとめ) https://www.tech-tech.xyz/haar-cascade.html https://github.com/opencv/opencv/blob/master/data/haarcascades/ 内のファイルメモ haarcascade_eye.xml … 人の目 Stump-based 20x20 frontal eye detector. haarcascade_eye_tree_eyeglasses.xml … めがねを付けた目 Tree-based 20x20 frontal eye detector with better handling of eyeglasses. haarcascade_frontalcatface.xml … 猫の顔(正面) A frontal cat face detector using the basic set of Haar features, haarcascade_frontalcatface_extended.xml … 猫の顔(正面) A frontal cat face detector using the full set of Haar features, haarcascade_frontalface_alt.xml … 顔検出(正面) Stump-based 20x20 gentle adaboost frontal face detector. haarcascade_frontalface_alt2.xml … 顔検出(正面) Tree-based 20x20 gentle adaboost frontal face detector. haarcascade_frontalface_alt_tree.xml … 顔検出(正面) Stump-based 20x20 gentle adaboost frontal face detector. haarcascade_frontalface_default.xml … 顔検出(正面) Stump-based 24x24 discrete(?) adaboost frontal face detector. haarcascade_profileface.xml … 証明写真の顔 20x20 profile face detector. haarcascade_smile.xml … 笑顔 Smile detector. haarcascade_lefteye_2splits.xml … 左目 Tree-based 20x20 left eye detector. haarcascade_righteye_2splits.xml … 右目 Tree-based 20x20 right eye detector. haarcascade_fullbody.xml … 全身 14x28 fullbody detector. haarcascade_upperbody.xml … 上半身 22x18 upperbody detector. haarcascade_lowerbody.xml … 下半身 19x23 lowerbody detector. haarcascade_licence_plate_rus_16stages.xml … ロシアの車ナンバープレート(全体) haarcascade_russian_plate_number.xml … ロシアの車ナンバープレート(数字部分) ■scaleFactor 物体検出(detectMultiScale)をパラメータを変えて試してみる(scaleFactor編) | Workpiles http://workpiles.com/2015/04/opencv-detectmultiscale-scalefactor/
■skimage
以下でskimageをインストール(10分ほどかかった)
$ sudo pip3 install scikit-image
■画像の色の違いの部分を切り分け
import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import cv2 from skimage import data, segmentation, color from skimage.future import graph # 画像を読み込み img = cv2.imread('lena.png', 1) #画像の色の違いの部分を切り分け labels = segmentation.slic(img, compactness=30, n_segments=400, start_label=0) out = color.label2rgb(labels, img, kind='avg', bg_label=0) plt.plot() plt.imshow(out) plt.savefig('rag.png')
■Pythonをバージョンアップ
$ python3 --version Python 3.7.3
現在のバージョンは3.7 https://www.python.org/ftp/python/ 3.8 は 3.8.7 が最新 以下を参考に、3.8.7 をインストールしてみる Raspberry PiでPythonをアップデートする方法 - 知的好奇心 https://intellectual-curiosity.tokyo/2019/12/07/raspberry-pi%E3%81%A7python%E3%82%92%E3%82%A2%E3%83%...
$ wget https://www.python.org/ftp/python/3.8.7/Python-3.8.7.tgz $ tar zxvf Python-3.8.7.tgz $ cd Python-3.8.7 $ ./configure $ make $ sudo make install $ python3 -V Python 3.7.3 $ python3.8 Python 3.8.7 (default, Feb 6 2021, 16:45:49) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> exit()
再起動して3.8を認識させる
$ sudo reboot
以下で確認する
$ python3 -V Python 3.8.7
■エラー対応メモ 上記でインストールできたが、OpenCVが使えなくなった
ImportError: No module named cv2
OpenCVをインストールしようとすると、以下のエラーになった
ModuleNotFoundError: No module named '_ctypes'
pipでのuWSGIのインストールが"ModuleNotFoundError: No module named '_ctypes'"で失敗する - かつおのお刺身 https://katsuwosashimi.com/archives/371/python-pip-uwsgi-ctypes-not-found/ いったん以下でインストール
$ sudo apt install libffi-dev
Pythonを再度インストール OpenCVを再度インストール これでOpenCVが使えるようになった matplotlib も使えなくなっていた
No module named 'matplotlib'
ModuleNotFoundError: No module named 'matplotlib'が出ても慌てずにmatplotlibをインストールしよう | ITを使っていこう https://it-ojisan.tokyo/python-no-module-named-matplotlib/ 以下でインストール
$ sudo pip3 install matplotlib
動体検知を実行すると以下のエラーになった
Traceback (most recent call last): File "/var/samba/detection/camera_detection.py", line 93, in <module> cv2.imshow(window_name, cap_img) cv2.error: OpenCV(4.5.1) /tmp/pip-install-klk8hgxy/opencv-contrib-python/opencv/modules/highgui/src/window.cpp:651: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'
以下に一応対処法があるが、またOpenCVをインストールしなおす必要があるみたい opencvのインストール - ディープラーニングなるものを始めるブログ http://tozensou32.blog76.fc2.com/blog-entry-17.html OpenCVをCondaで簡単にインストール - Qiita https://qiita.com/yhyhyhjp/items/ea5ad55736e3e9470b6a いったんは以下のように、Pythonのバージョンを指定して実行すると大丈夫だった
$ python3.7 /var/samba/detection/camera_detection.py
■カードリーダー
※未検証 Raspberry PiにNFCリーダを接続してSuicaを読み取る - Qiita https://qiita.com/undo0530/items/89540a03252e2d8f291b Raspberry Piでスマートロックをつくった - Qiita https://qiita.com/undo0530/items/669b6ee6b2277ea64b33 勤怠打刻機をRaspberry Pi 14台で本気で作ってみた - Speee DEVELOPER BLOG https://tech.speee.jp/entry/2017/06/06/100000 Raspberry Piで出退勤システムを作ろう(PaSoRi、Python、音声出力編) | GROUP DEV BLOG | TECHNO MOBILE https://www.tcmobile.jp/dev_blog/programming/raspberry-pi%E3%81%A7%E5%87%BA%E9%80%80%E5%8B%A4%E3%82%...
■無線LAN
一般的なルーターはLinuxをベースとして作られているらしい Raspberry Pi をルータとして動作させることが可能らしい ラズパイを無線LANルーター化する 〜アクセスポイント編〜 (1/2) - ITmedia NEWS https://www.itmedia.co.jp/news/articles/2008/14/news042.html ラズパイを無線LANルーター化する 〜ブリッジモード編〜 - ITmedia NEWS https://www.itmedia.co.jp/news/articles/2008/28/news018.html Raspberry Pi で無線ルータを自作する - Qiita https://qiita.com/hoto17296/items/2e638fa28597b18505cd Raspberry Pi 4 をCentOSでルーター化する | GRAPHO https://grapho.jp/raspberrypi4/router/ 以下は直接関係ないが、参考程度にメモしておく BuffaloルータをPCディスプレイにつなげた。 - Zopfcode https://www.zopfco.de/entry/2016/02/02/211740
■その他参考
Ubuntu をインストールしたら設定すること 13 ヶ条 https://zenn.dev/sprout2000/articles/112116c4edb265 電子工作ファン向けのRaspberry Pi・セットアップ(Ubuntu 20編) - Qiita https://qiita.com/myasu/items/5b122c782c5a616d8b60 Raspberry Piを極限まで無駄なくバックアップする | Developers.IO https://dev.classmethod.jp/articles/raspberry-pi-dump-and-restore/ 8GBメモリ版のRaspberry Pi 4 Model Bが登場 - PC Watch https://pc.watch.impress.co.jp/docs/news/1255463.html Raspberry Pi4 単体で TensorFlow Lite はどれくらいの速度で動く? - Qiita https://qiita.com/terryky/items/243000fcfcb89af11510 ラズベリーパイZERO-WHで監視カメラ(動体検知と動画保存)を作成する - Qiita https://qiita.com/ochiai_t/items/db7e2393c3a6cb9bb902 ラズパイの拡張ボード「Sense HAT」で遊んでみよう - ITmedia NEWS https://www.itmedia.co.jp/news/articles/2010/09/news015.html Raspberry Piは本当に壊れやすいのか https://zenn.dev/su_/articles/97b9e25d0ae41c ラズパイでタイムラプス作り - Qiita https://qiita.com/horoyoi3/items/86394408644f03bc252a 電車の運行情報をOLEDディスプレイでチェックする:名刺サイズの超小型PC「ラズパイ」で遊ぶ(第51回) - ITmedia NEWS https://www.itmedia.co.jp/news/articles/2111/26/news013.html Raspberry Pi(ラズパイ)のローカル環境でLLMを動かす https://zenn.dev/karaage0703/articles/5fd411a9358898
■2017年に試したときのメモ
■購入 本体 Raspberry Pi3 Model B ボード&ケースセット 3ple Decker対応 https://www.amazon.co.jp/gp/product/B01CSFZ4JG 電源 Raspberry Pi用電源セット(5V 3.0A) https://www.amazon.co.jp/gp/product/B01N8ZIJL8 ディスプレイ OSOYOO HDMI 3.5インチLCDディスプレイ モニター タッチスクリーン 1920x1280ハイビジョン https://www.amazon.co.jp/gp/product/B01N5HW3BP microSDカード Samsung microSDHCカード 32GB EVO Plus Class10 UHS-I対応 https://www.amazon.co.jp/gp/product/B06XSV23T1 書籍 カラー図解 最新 Raspberry Piで学ぶ電子工作 作って動かしてしくみがわかる https://www.amazon.co.jp/gp/product/4062579774 Raspberry Piで学ぶ電子工作 パーツセット http://akizukidenshi.com/catalog/g/gK-10852/ OSOYOO(オソヨー) Raspberry Pi 学ぶ電子工作キット 初心者演習用パーツセット https://www.amazon.co.jp/gp/product/B01M6ZFNSS ■準備 https://www.raspberrypi.org/downloads/ 「NOOBS」をクリック 「NOOBS」の「Download ZIP」をクリック サイズが大きいので、自宅のネットワークだとダウンロードに3時間ほどかかった ダウンロードしたファイルを展開 展開したファイルをすべてMicroSDカードにコピー(MicroSDカード直下に、複数のファイルとフォルダがある状態) MicroSDカードを Raspberry Pi 本体にセット(読み取り金属部分がある方が上)し、 USBでキーボードとマウスを接続し、 HDMIでディスプレイ(TV)を接続し、 電源に接続した。 ※最初OSOYOOのディスプレイを接続したが表示されなかった 電源に接続していないからだった Amazonのレビューに「Pi3だとモニター電源もpi3本体から供給できる」とあったが、電源への接続が不要というわけではないみたい ■インストール 電源コードにあるボタンを押すと、Raspberry Pi 本体のLED(緑と赤)が点滅した TVにインストール画面が表示された 「Language」から「日本語」を選択して日本語表示にした(あくまでもインストール時に使用する言語みたい) 「Raspbian [RECOMMENDED]」を選択し、画面上部の「インストール(i)」ボタンを押す SDカードのデータが上書きされる旨の警告が表示されるので、「はい(Y)」を押す インストールが始まるのでしばらく待つ 10分ほどでインストールが完了し、デスクトップが表示された ■設定 デスクトップ左上のラズベリーパイアイコンがメインメニュー。以下「Menu」と表記 「Menu → Preferences → Raspberry Pi Configuration」を選択 「Localisation」タブの「Set Timezone...」ボタンを押す 「Area」を「Asia」、「Location」を「Tokyo」にして「OK」ボタンを押す 「Set Keyboard...」ボタンを押す 「Country」を「Japan」、「Variant」を「Japanese(OADG 109A)」にして「OK」ボタンを押す 「Set Locale...」ボタンを押す インストール時に日本語を選択したからか、はじめから 「Language」が「ja(Japanese)」 「Cuntry」が「JP(Japan)」 「Charactor Set」が「UTF-8」 になっていた。OKで閉じた デスクトップ右上のネットワークアイコンをクリックし、 一覧から普段使用しているWi-fiを選択し、 パスワードを入力すると接続できた Googleから日本語ページを検索してみたが、文字化けせずに表示された この時点で一度再起動した 「Menu → Shutdown → Reboot」とすると再起動され、この時点でメニューなどが日本語表示になっていた ただし日本語入力には標準では対応していないみたい 追加でソフトウェアのインストールが必要になるみたい ■本体をアップデート
$ sudo apt-get update ... パッケージリストの更新 $ sudo apt-get upgrade ... パッケージ構成を変えない範囲で、インストールされてるパッケージを更新 $ sudo apt-get dist-upgrade ... パッケージ構成の変更に追随して、インストールされてるパッケージを更新
※完了後、本体を再起動しておく ※本体をアップデートせずにApacheをインストールしようとするとエラーになった(ファイル入手時に404エラー) ファイルの入手先が更新されていないためだと思われる Raspberry Pi のファームウェアのアップデート https://raspberrypi.akaneiro.jp/archives/1431 apt-get upgradeとdist-upgradeの違い http://qiita.com/ryosy383/items/ac450750e9419b5bcf75 [Ubuntu] apt-get まとめ http://qiita.com/white_aspara25/items/723ae4ebf0bfefe2115c ■httpdをインストール
$ sudo apt-get install apache2 ... Apacheをインストール $ apache2 -v ... Apacheのバージョンを確認 $ sudo service apache2 start ... Apacheを起動 $ sudo service apache2 stop ... Apacheを停止させる場合 $ sudo service apache2 restart ... Apacheを再起動させる場合
完了後 http://127.0.0.1/ にアクセスすると /var/www/html/index.html が表示される http://localhost/ もしくは http://raspberrypi/ でもアクセスできる ApacheとPHPのインストール | Raspberry Pi用ソケットサーバーフレームワーク「HAL」 http://www.feijoa.jp/work/hal/apacheAndPhp/ Webサーバーの構築方法(Apache+PHP) http://www.raspberrypirulo.net/entry/2016/08/23/Web%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E6%... ■同一LAN内の他PCからアクセス
$ ifconfig ... 自身のIPアドレスを確認
例えば 192.168.1.8 だった場合 http://192.168.1.8/ でアクセスできる ■SSHでアクセス
$ sudo touch /boot/ssh ... SSHを有効化(要再起動)
※2016-11-25版のセキュリティアップデートにより、デフォルトでSSHは無効となった 上記コマンド実行後OSを再起動すると、SSHでアクセスできるようになった(OS起動時に警告が表示される) 「メニュー → 設定 → Raspberry Piの設定 → インターフェイス」からもSSHを有効にできるみたい Raspberry Pi 3を初回起動してからSSH接続まで http://ykubot.com/raspberry-pi-3-initialize/ 一例だが、以下の情報でSSH接続できる Poderosaで接続できない場合、Poderosaを最新版にする 接続先:192.168.1.8 ポート:22 ユーザ名:pi パスワード:raspberry Poderosaでopensshに接続できない http://dragstar.hatenablog.com/entry/2015/06/19/110854

Advertisement