Ubuntu22.04 で ラズパイゼロWからのダイレクト TCP ストリーミングでの配信されている画像を OpenCV で再生 その1

Ubuntu22.04 で
ラズパイゼロWからのダイレクト TCP ストリーミングでの配信されている画像を
OpenCV
で再生する

VOICEVOX REST-APIを使えるようにする

とりあえずOpenCV から入れる

https://monobook.org/wiki/Ubuntu_22.04_LTSにVoiceVoxをインストールする
でvoiceboxを入れる

sudo apt install fuse libfuse2

を入れておく

https://voicevox.hiroshiba.jp
から
OS Linux
対応モード CPU
インストーラタイプをダウンロード

cd Downloads
scp VOICEVOX-CPU.Installer.0.14.7.Linux.sh snowpool@192.168.1.69:/home/snowpool/

でM1MacbookAir からscp で転送する

bash VOICEVOX-CPU.Installer.0.14.7.Linux.sh 

を実行したが

* curl コマンドが見つかりません。

以下のコマンドを実行してください。

Ubuntu/Debian:
    sudo apt install curl

CentOS/Fedora:
    sudo dnf install curl
もしくは
    sudo yum install curl

となるので

sudo apt install curl

の後に実行したら

+-+-+-+-+-+-+-+-+
|V|O|I|C|E|V|O|X|
+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |I|n|s|t|a|l|l|e|r|
+-+-+-+-+-+-+-+-+-+-+-+-+-+
|f|o|r| |L|i|n|u|x|
+-+-+-+-+-+-+-+-+-+
[+] Checking installer prerequisites...
[!] Command '7z', '7zr' or '7za' not found

Required to extract compressed files

Ubuntu/Debian:
    sudo apt install p7zip

CentOS (Enable EPEL repository):
    sudo dnf install epel-release && sudo dnf install p7zip
Or
    sudo yum install epel-release && sudo yum install p7zip

Fedora:
    sudo dnf install p7zip
Or
    sudo yum install p7zip

Arch Linux:
    sudo pacman -S p7zip

MacOS:
    brew install p7zip

となるので

sudo apt install p7zip

の後に

bash VOICEVOX-CPU.Installer.0.14.7.Linux.sh 

でインストール成功

起動は

~/.voicevox/VOICEVOX.AppImage

だと

configMigration014: /home/snowpool/.config/voicevox-cpu/config.json not exists, do nothing
[26521:0923/052732.856278:ERROR:ozone_platform_x11.cc(247)] Missing X server or $DISPLAY
[26521:0923/052732.856458:ERROR:env.cc(226)] The platform failed to initialize.  Exiting.
Segmentation fault (コアダンプ)

となってしまう

普通にubuntu へログインし
GUIから起動すれば問題なく動くが

https://qiita.com/uezo/items/7e476147ec6312ad8a2c

.runで実行
M1Macでも動作したので
同様にubuntu でもできると思ったがコマンドが見つからない

https://ponkichi.blog/voicevox-python-curl#st-toc-h-7
を参考に

とりあえず

sudo find / -name ".run"

を実行したが

[sudo] snowpool のパスワード: 
find: ‘/run/user/1000/doc’: 許可がありません
find: ‘/run/user/1000/gvfs’: 許可がありません
find: ‘/run/user/127/doc’: 許可がありません
find: ‘/run/user/127/gvfs’: 許可がありません

となる

なおFWは関係なかった
https://server-network-note.net/2022/07/ubuntu-server-22-04-lts-firewall-ufw/
を参考にsudo ufw status で確認したが
無効になっていた

とりあえず保留してopencvを先に進める

https://www.kkaneko.jp/tools/ubuntu/ubuntu_opencv.html#S1
を参考に

まず cmakeのインストール

sudo apt -y install build-essential gcc g++ make libtool texinfo dpkg-dev pkg-config
sudo apt -y install qt5-qmake
sudo apt -y install git cmake cmake-curses-gui cmake-gui curl
sudo apt -y install zlib1g-dev libcurl4-gnutls-dev

cd /tmp
git clone https://github.com/Kitware/CMake.git
cd CMake/
./configure --system-curl --system-zlib
Make
Sudo make install

次にpython3 関連

sudo apt -y install python-is-python3 python3-dev python-dev-is-python3 python3-pip python3-setuptools python3-venv build-essential

次に
OpenCV, opencv_contrib のインストール

sudo mkdir -p /usr/local/opencv
sudo chown -R $USER /usr/local/opencv
cd /usr/local/opencv
curl -O https://github.com/opencv/opencv/archive/4.x.zip
cp 4.x.zip opencv.zip
curl -O https://github.com/opencv/opencv_contrib/archive/4.x.zip
cp 4.x.zip opencv_contrib.zip

unzip opencv.zip 
Archive:  opencv.zip
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of opencv.zip or
        opencv.zip.zip, and cannot find opencv.zip.ZIP, period.

となるので

https://www.kkaneko.jp/tools/ubuntu/ubuntu_opencv_buildout.html

https://toolatescrap.hatenablog.com/entry/2022/11/29/003848
を参考に
https://opencv.org/releases/
からmacでダウンロードしたが展開される

https://github.com/opencv/opencv/tree/4.7.0
からzipダウンロードしたが同じ
どうやらMacでzipダウンロードすると展開されるらしい

sudo apt install libgtk2.0-dev

で先にインストールしておく

https://www.kkaneko.jp/tools/ubuntu/ubuntu_opencv_buildout.html#S2
を参考に
Ceres Solver のインストール

sudo apt -y install  libceres-dev libceres2

次にpython3関連

https://www.kkaneko.jp/tools/man/python.html#systempython
によれば

Ubuntu では,システム Python は,Ubuntu システムの動作に関わっている. システム Python をバージョンアップしたり,アンインストールを行ったりするのは良くない

と言うことなので
Pyenvを使うようにする

sudo apt -y install --no-install-recommends make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
cd /tmp
curl https://pyenv.run | bash
echo 'export PYENV_ROOT="${HOME}/.pyenv"' >> ~/.bashrc
echo 'if [ -d "${PYENV_ROOT}" ]; then' >> ~/.bashrc
echo '    export PATH=${PYENV_ROOT}/bin:$PATH' >> ~/.bashrc
echo '    eval "$(pyenv init -)"' >> ~/.bashrc
echo '    eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
echo 'fi' >> ~/.bashrc
exec $SHELL -l

他の必要なものもインストールするので
https://www.kkaneko.jp/tools/ubuntu/ubuntu.html#Se
を参考に

sudo apt -y install git cmake cmake-curses-gui cmake-gui curl wget p7zip-full

次にpython関連

python-is-python3 python3-dev python-dev-is-python3 python3-pip python3-setuptools python3-venv build-essential

sudo apt -y install python-is-python3 python3-dev python-dev-is-python3 python3-pip python3-setuptools python3-venv build-essential

sudo pip3 uninstall ptyprocess sniffio terminado tornado jupyterlab jupyter jupyter-console jupytext nteract_on_jupyter spyder

を実行したら

do tornado jupyterlab jupyter jupyter-console jupytext nteract_on_jupyter spyder
Found existing installation: ptyprocess 0.7.0
Not uninstalling ptyprocess at /usr/lib/python3/dist-packages, outside environment /usr
Can't uninstall 'ptyprocess'. No files were found to uninstall.
WARNING: Skipping sniffio as it is not installed.
WARNING: Skipping terminado as it is not installed.
WARNING: Skipping tornado as it is not installed.
WARNING: Skipping jupyterlab as it is not installed.
WARNING: Skipping jupyter as it is not installed.
WARNING: Skipping jupyter-console as it is not installed.
WARNING: Skipping jupytext as it is not installed.
WARNING: Skipping nteract_on_jupyter as it is not installed.
WARNING: Skipping spyder as it is not installed.
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

となった

おそらく競合しないため念のためアンインストールしてるっぽい

sudo apt -y install jupyter jupyter-qtconsole spyder3
sudo apt -y install python3-ptyprocess python3-sniffio python3-terminado python3-tornado
sudo pip3 install -U jupyterlab jupyter jupyter-console jupytext nteract_on_jupyter

これで
JupyterLab, spyder, nteract
をインストール

sudo apt -y install python3-numpy python3-sklearn


numpy, scikit-learn のインストール

次に
TensorFlow 2.11,Keras,MatplotLib, Python 用 opencv-python のインストール

トラブルの可能性を減らすため
アンインストールをしておく

sudo apt -y remove python3-keras
sudo pip3 uninstall -y tensorflow tensorflow-cpu tensorflow-gpu tensorflow-intel tensorflow-text tensorflow-estimator tf-models-official tf_slim tensorflow_datasets tensorflow-hub keras keras-tuner keras-visualizer

クリーンインストール状態なので

WARNING: Skipping tensorflow as it is not installed.
WARNING: Skipping tensorflow-cpu as it is not installed.
WARNING: Skipping tensorflow-gpu as it is not installed.
WARNING: Skipping tensorflow-intel as it is not installed.
WARNING: Skipping tensorflow-text as it is not installed.
WARNING: Skipping tensorflow-estimator as it is not installed.
WARNING: Skipping tf-models-official as it is not installed.
WARNING: Skipping tf_slim as it is not installed.
WARNING: Skipping tensorflow_datasets as it is not installed.
WARNING: Skipping tensorflow-hub as it is not installed.
WARNING: Skipping keras as it is not installed.
WARNING: Skipping keras-tuner as it is not installed.
WARNING: Skipping keras-visualizer as it is not installed.
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

となった

TensorFlow の前提パッケージのインストール

sudo pip3 uninstall -y six wheel astunparse tensorflow-estimator numpy keras-preprocessing absl-py wrapt gast flatbuffers grpcio opt-einsum protobuf termcolor typing-extensions google-pasta h5py tensorboard-plugin-wit markdown werkzeug requests-oauthlib rsa cachetools google-auth google-auth-oauthlib tensorboard tensorflow
sudo apt -y install python3-six python3-wheel python3-numpy python3-grpcio python3-protobuf python3-termcolor python3-typing-extensions python3-h5py python3-markdown python3-werkzeug python3-requests-oauthlib python3-rsa python3-cachetools python3-google-auth

次に
TensorFlow, numpy, pillow, pydot, matplotlib, keras, opencv-python のインストール

sudo apt -y update
sudo apt -y install python3-numpy python3-pil python3-pydot python3-matplotlib
sudo apt -y install libopencv-dev libopencv-core-dev python3-opencv libopencv-contrib-dev opencv-data
sudo pip3 install -U tensorflow tf-models-official tf_slim tensorflow_datasets tensorflow-hub keras keras-tuner keras-visualizer
sudo pip3 install git+https://github.com/tensorflow/docs
sudo pip3 install git+https://github.com/tensorflow/examples.git
sudo pip3 install git+https://www.github.com/keras-team/keras-contrib.git

インストール完了後

python3 -c "import tensorflow as tf; print( tf.__version__ )"

でバージョン確認

2023-09-26 06:14:43.998359: I tensorflow/tsl/cuda/cudart_stub.cc:28] Could not find cuda drivers on your machine, GPU will not be used.
2023-09-26 06:14:44.053113: I tensorflow/tsl/cuda/cudart_stub.cc:28] Could not find cuda drivers on your machine, GPU will not be used.
2023-09-26 06:14:45.376154: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT
2.13.0

となった

とりあえずここまで
次にPyTorch などをインストールする

Fibit の web API

Fibit の web API

Fibit Inspire3 を購入しAPIで情報を取得してみたかったので
その時のメモ

FitbitのWeb APIを実行する方法
https://www.zenryoku-kun.com/post/fitbit-api
を参考に

Web APIを利用するアプリを登録
https://dev.fitbit.com/login
から行う

Register new app
をクリック

Redirect URL以外のURL項目はhttp://localhostでOK

Application Name: アプリ名
今回はtest

Description: 10文字以上でアプリの説明
ヘルスケア関連のデータを取得して表示したい
とした

Organization *
はサイトを参考に無職とした

OAuth2.0 Application Type: 個人データを取得するのでPersonal

Redirect URL: 初回のアクセス・トークンはここに送られる
http://localhost:8000にしておく

Default Access Type:
APIでデータの書込みをしたい場合はRead & Writeを選択
Read Onlyなら読み込みのみ

これで
I have read and agree to the terms of serviceをチェックしてピンクのRegisterボタンを押す

これで登録ができた

この時に

OAuth 2.0 Client ID

Client Secret

Redirect URL
http://localhost:8000
OAuth 2.0: Authorization URI
https://www.fitbit.com/oauth2/authorize
OAuth 2.0: Access/Refresh Token Request URI
https://api.fitbit.com/oauth2/token

というように
Client ID
Client Secret
が表示される

OAuth 2.0 Tutorial
をクリックすると
アクセストークンなどの発行ができる

チュートリアルの画面では
ClientIDはそのままセットされているので
タイプを
サーバーか Client を選ぶ

エンドポイントにより認証方法が異なる

今回はclient を選択

Access Token 発行のため

PKCE Code Verifier
State

 GENERATE
をクリック

Display Authorization Page

取得を認めない情報があればチェックを外しておく

とりあえず全て取得してみるのでこれはそのままにしておく

下に認証ページへのリンクが出るのでクリック

HTTPSでない警告が出てるけど
許可をクリック

サーバーに接続できません
と表示されるけど
ブラウザのURLをコピペ

これを
Handle the Redirect
へコピペすると
Authorization Code
などが表示される

次に
Get Tokens

SUBMIT REQUEST
をクリック

これで
Response
の部分に
JSONでAccess Token が表示される

Refresh Token
も発行されているのでメモしておく

なお
Refresh Token を実行すると
Access Token
Resresh Token も両方更新されるので注意

また
Access Token は
八時間で執行するため
Refresh token で再取得する処理が必要

Githubへの公開とライセンス関連を調べた

Githubへの公開とライセンス関連を調べた

https://github.com/Snowpooll/face_weather
が今回作成したもの

顔を認識するとVOICEVOXで今日の天気を教えてくれる

コンセプトは操作しないこと
アレクサでもいいけど
声が出せないと使えないし

以下は作業ログ

リポジトリ名を
face_weather

publicで公開

Add a README file

readmeを追加

ライセンスはMITライセンスを選択

これでリポジトリを作成すれば
ライセンスの英文は自動で作成してくれる

Readmeを編集してから

git clone https://github.com/Snowpooll/face_weather.git


ローカル環境にリポジトリをクローン

この中にプログラムをコピーしていくが

__pycache__

があった

これは
ChatGPTによれば
__pycache__ は、
Pythonがソースコードをコンパイルした後のバイトコードを格納するディレクトリ

バージョン管理システム(例:Git)を使用している場合は、
通常、__pycache__ ディレクトリを
無視リストに追加することが一般的

なので

 vim .gitignore

でファイルを作成

__pycache__/

として保存

git add .gitignore

で追加

git commit -m "Add __pycache__ to .gitignore"

を実行したら

Author identity unknown

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'snowpool@snowpool-Prime-Series.(none)')

となった

そういえば再インストールした時に設定を忘れていたので
git config –global user.name “Githubユーザ名”
git config –global user.email “メールアドレス”


再度

git commit -m "Add __pycache__ to .gitignore"

を実行

あと

query.json
test_audio.wav
weather.txt

も無視リストに加えるので

vim .gitignore

でファイルを開き
追記

git add .gitignore
git commit -m "Update .gitignore to include specific files"

で追加

次に
requirements.txt
の作成

これでライブラリ関連のインストールが簡単になる

requests
deepl
pygame
opencv-python
configparser

というようにライブラリを書いておけばOK

git push origin main

でエラー。

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Snowpooll/face_weather.git/'

調べたら
GitHubでパスワード認証が廃止されたため、HTTPSを使ってリモートリポジトリにアクセスする際にはパーソナルアクセストークン(PAT)を使用するか、SSHキー認証を使用する必要があるらしい

とりあえずPATを使うことにする

GitHubでPATを生成する:
* GitHubにログインし、右上のアカウントアイコンから「Settings」を選択します。
* 左側のサイドバーから「Developer settings」を選択し、「Personal access tokens」に移動します。
* 「Generate new token」をクリックし、必要な権限を選択してトークンを生成します。生成されたトークンは安全な場所にコピー

で作成しようとしたら
New personal access token (classic)
の設定でつまづくので検索

https://dev.classmethod.jp/articles/github-personal-access-tokens/
によれば

Noteにはトークンの使用用途
code maintenanceとした

Expirationにはトークンの有効期限
デフォルトは30だが短いので90にする

Select scopesではトークンが利用可能なGitHub権限を設定
git cloneやgit pullをしたい場合は、repoにチェック

これで
Generate token
をクリックすれば
トークンが表示される

これで再度

git push origin main

実行したら

 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/Snowpooll/face_weather.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

となる

原因は
リモートリポジトリにあなたのローカルリポジトリにはない変更が含まれているために発生

思い当たることとして
READMEを
Githubで編集した後に

git pull origin main

していなかったこと

他の変更はなかったため

git push origin main --force

で強制プッシュ

とりあえずはこれで公開できた

ちなみに後で聞いたのだが
–force は、remoteのものを完全に上書きするので、使わないほうがベター
必要なcommitが消える可能性があるらしい

認証も、SSHキーを使うのがベター
とのこと

ubuntu22.04 Live USB 作成

ubuntu22.04 Live USB 作成

【簡単】balenaEtcherを使ってUbuntuのLive USBを作成する方法
を参考に

USB3.0対応の64GBのUSBメモリを購入

なお MacBook Airには
Usb type C しかないので
変換アダプターを購入し使用

OSがダウンロードできたら
balenaEtcherをダウンロード

https://etcher.balena.io
へアクセスし
Download Etcher
をクリック

しかし
Mac のx64形式しかないので
M1Macだとできない

このため
【M1】 M1 Mac で UbuntuをUSBに焼く

を参考に進める

これには
Rosetta
を使う必要があるらしいが既に入っていた

Finder を開き
ユーティリティ > ターミナルを右クリックで開く

ちなみにMacBook Airの場合
トラックパッドを2本指でタップするとできる

Macの「右クリック」4つのやり方|キーボードでもできます

を参考に

これで右クリックができるので
情報を見る

Rosettaを利用して開く
にチェックを入れる

これでUSBメモリを差し込み
Finder からターミナルを開く

diskutil list


USBをどのように認識しているか調べる

結果は

/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *251.0 GB   disk0
   1:             Apple_APFS_ISC Container disk2         524.3 MB   disk0s1
   2:                 Apple_APFS Container disk3         245.1 GB   disk0s2
   3:        Apple_APFS_Recovery Container disk1         5.4 GB     disk0s3

/dev/disk3 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +245.1 GB   disk3
                                 Physical Store disk0s2
   1:                APFS Volume Macintosh HD            9.1 GB     disk3s1
   2:              APFS Snapshot com.apple.os.update-... 9.1 GB     disk3s1s1
   3:                APFS Volume Preboot                 4.6 GB     disk3s2
   4:                APFS Volume Recovery                797.2 MB   disk3s3
   5:                APFS Volume Data                    145.8 GB   disk3s5
   6:                APFS Volume VM                      6.4 GB     disk3s6

/dev/disk4 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +2.7 GB     disk4
   1:                        EFI EFI                     209.7 MB   disk4s1
   2:                  Apple_HFS VOICEVOX 0.14.7         2.3 GB     disk4s2

/dev/disk5 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +2.7 GB     disk5
   1:                        EFI EFI                     209.7 MB   disk5s1
   2:                  Apple_HFS VOICEVOX 0.14.7         2.3 GB     disk5s2

/dev/disk6 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +2.7 GB     disk6
   1:                        EFI EFI                     209.7 MB   disk6s1
   2:                  Apple_HFS VOICEVOX 0.14.7         2.3 GB     disk6s2

/dev/disk7 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +1.5 GB     disk7
   1:                  Apple_HFS Blender                 1.4 GB     disk7s1

/dev/disk8 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *62.5 GB    disk8
   1:             Windows_FAT_32 KIOXIA                  62.5 GB    disk8s1

上にあるものはOS関連
フォーマットを見ると1つだけ
/dev/disk8

Windows_FAT_32_KIOXIA
となっているので

diskutil eraseDisk MS-DOS UNTITLED /dev/disk8

を実行

Started erase on disk8
Unmounting disk
Creating the partition map
Waiting for partitions to activate
Formatting disk8s2 as MS-DOS (FAT) with name UNTITLED
512 bytes per physical sector
/dev/rdisk8s2: 121576384 sectors in 1899631 FAT32 clusters (32768 bytes/cluster)
bps=512 spc=64 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=411648 drv=0x80 bsec=121606144 bspf=14841 rdcl=2 infs=1 bkbs=6
Mounting disk
Finished erase on disk8

となって
中身が消去される

次にディスクのアウンマウント
これをやらないとISOを書き込む時にエラーになるらしい

diskutil unmountDisk /dev/disk8

を実行すると

Unmount of all volumes on disk8 was successful

となり成功

次に書き込み
ISOファイルのパスを取得するには
FinderでISOファイルをクリックし
青くなっている状態で
Command + option + c
を押すとファイルパスが取得できる

私の場合だと

/Users/snowpool/Downloads/ubuntu-ja-22.04-desktop-amd64.iso

これを
Ddコマンドの
If で指定し ofへUSBデバイスを指定する

約8分程度で

850993+1 records in
850993+1 records out
3427803136 bytes transferred in 480.772592 secs (7129781 bytes/sec)

となり書き込みが終わる

ラズパイドラレコ作成

ラズパイドラレコ作成

ssh
でアクセスし

sudo apt-get update
sudo apt-get upgrade

のあと

sudo raspi-config


最初のメニューの5番目の項目
Interfacing Optionsを開くと1番上にカメラの項目があるのでこれを有効化

ここまでできたら

v4l2-ctl --list-devices

使用するカメラのデバイスファイルを調べる
通常は

/dev/video0

となる

デバイスファイルを特定しておくと
下記のコマンドでサポートしている動画のフォーマットを表示することが可能

v4l2-ctl -d /dev/video0 --list-formats

ラズパイで動画を撮影する方法として
FFmpegを使用してリアルタイムでハードウェアエンコードする方法がよく紹介されていますが
特にRaspberry Pi Zeroだと
フレームレートがあまり出ないのでドラレコには不向き

しかしハードウェアエンコードなんてしなくても
H.264をサポートしているカメラモジュールを使用すれば
専用の動画撮影コマンドraspividを実行することで
簡単にH.264動画を撮影することが可能

安価なUSB接続のWebカメラだと
H.264をサポートしていなかったりしますが
ズパイ向けのカメラモジュールは
どれもH.264をサポートしているので
基本的にraspividで録画する

raspividで動画を撮影するには
もっともシンプルに書くなら
-oで出力ファイル名のみを指定してこのように記述
なお指定した名前のファイルが既に存在する場合は
実行に失敗するので注意

raspivid -o test.h264

このように何も指定せずに実行すると5秒の動画ファイルが生成される

拡張子がH.264と扱いにくい形式ですが
一応このままでもVLCなどの動画プレーヤーで再生することが可能 

撮影してみてカメラの向きが上下反転していた場合は-vf
左右反転していた場合は-hfを付け加えることで
正常な向きに補正されるはず

また-rotで角度を指定して回転させることもできる
shell]
raspivid -o test.h264 -rot 180[/shell]

正しい方向で撮影できるようになったら-wと-hで解像度、
-tで撮影時間、-fpsでフレームレート、-bでビットレートを指定

raspivid -o test.h264 -rot 180 -w 1280 -h 720 -t 10000 -fps 30 -b 2000000

撮影時間はミリ秒で指定するため、-t 10000だと10秒の動画を生成

ただし-t 0で時間を指定しなければずっと録画し続けることが可能

Ctrl+Cで録画を停止

解像度やビットレートを上げれば高画質な動画を撮影できますが
それに比例してファイルサイズも大きくなるので注意

raspividの実行中にWi-Fiから切断されると
コマンドラインが閉じられるために録画も停止してしまう
車内にWi-Fi環境が整っている場合はともかく、
そうでないならもう一工夫が必要

Raspberry Pi Zeroがネットワークから切断されても
raspividを停止しないようにするために、
まずコマンドを実行するシェルスクリプトを作成

sudo nano test.sh

中身は

#!/bin/sh

raspivid -o `date '+%Y%m%d-%H%M'`.h264 \
-rot 180 -w 1280 -h 720 -t 10000 -fps 30 -b 2000000

あとは

sh test.sh

で録画できればok

次は
作成したスクリプトをサービスとしてシステム管理デーモンのsystemdに登録

まずは自動実行させたいスクリプトを/optに作成

sudo nano /opt/test.sh

今回は録画時間を指定しない

#!/bin/sh

raspivid -o `date '+%Y%m%d-%H%M'`.h264 \
-rot 180 -w 1280 -h 720 -t 0 -fps 30 -b 2000000

次は

sudo chmod 0755 /opt/test.sh

で実行権限付与

このスクリプトをサービスとしてsystemdに登録するため、ユニットファイルを作成

sudo nano /etc/systemd/system/test.service

中身は

[Unit]
Description = test

[Service]
ExecStart = /opt/test.sh
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target

解説
Descriptionはユニットファイルの説明です。これは自由に記述

ExecStartに登録したいスクリプトを記述

Restartはalwaysを設定しておくことで、
プロセスが不意に終了しても再起動させることが可能です。
再起動する条件として異常終了した場合のみ、
あるいは逆に正常終了した場合のみなどを設定することも可能ですが、
通常はalwaysで良い

例外として後述するsystemctlコマンドで停止した場合のみ再起動されない

Typeはプロセスの起動タイプを設定するオプションです。
simpleがデフォルトで、メインプロセスとして登録

WantedByは弱く依存するユニットを記述します。
噛み砕いて説明すると、
multi-user.targetの起動時にtest.serviceの起動も試みてほしい、
ということです。
多くのサービスがmulti-user.targetに紐付いていて、
OS起動時にまとめて実行されます。

ユニットを定義できたら、サービスを有効化するために下記のコマンドを実行

sudo systemctl enable test.service

正常に有効化されていれば、下記のコマンドを入力するとバックグラウンドでサービスが実行されます。

サービスの状態は下記のコマンドで確認

sudo systemctl status test.service

しかし

Loaded: loaded (/etc/systemd/system/test.service; enabled; vendor preset: > Active: inactive (dead)

と表示されて固まる

Systemd を利用してサービスを追加・登録する
を参考に

systemctl list-unit-files --type=service |grep test

を実行し

glamor-test.service                        enabled         enabled
gldriver-test.service                      enabled         enabled
test.service                               enabled         enabled

で稼働しているのを確認

またサービスを手動で停止したい場合は下記のコマンドを実行

sudo systemctl stop test.service

とりあえず止めておく
理由は

ただし普通にraspividコマンドを実行すると
1つの巨大な動画ファイルが生成されてしまうので、
特にWi-Fi経由でデータを取り出そうとするとかなり時間がかかります

解決策として
FFmpegへパイプ入力して動画ファイルの分割&変換処理を自動的に実行させることで対策

https://gadget-live.net/raspberry-pi-raspivid-ffmpeg-pipe-input/
を参考に

あとは
Raspberry Pi Zeroをシャットダウンして安全に電源を切る方法

スマートフォンのテザリングでSSH接続
これだと
Bluetoothテザリング
https://gadget-live.net/raspberry-pi-bluetooth-tethering/
があるが
問題は複数のペアリングが可能かということ

Alexaを利用してハンズフリーで操作
これもありだけど
スマホでテザリングしてる状態で
Alexaが使えるのか?

とりあえずSSHでログインしてシャットダウンがベスト
あとはBluetoothボタンが候補
あとは人感センサーか音声でシャットダウンが候補

動画については
raspividからFFmpegへパイプ入力して
FFmpegのsegmentオプションで分割すれば、これらの問題がすべて簡単に解決
この方法なら録画した動画を一定時間毎に分割することも、
ファイルの名前をそれぞれの録画を開始した時間にすることも、
さらに拡張子をH.264からMP4に変換するのもすべて自動的に実行することが可能

例えば解像度1280×720、ビットレート2000kbps、
フレームレート30fpsで録画して1分単位で分割すれば
ファイルサイズは1つあたり約15MBなので、
ピンポイントで転送すればWi-Fiでもそれほど時間をかけずに取り出せます。

ようやく実際に手を動かしてraspividからFFmpegへパイプ入力するスクリプトを実装
既にドラレコとしてraspividコマンドを実行するスクリプトを組んであるなら、
それを書き換えるだけなのですごく簡単

#!/bin/sh

raspivid -o - -w 1280 -h 720 -t 0 -fps 30 -b 2000000 |
ffmpeg -r 30 -i - -vcodec copy \
-f segment -strftime 1 -segment_time 60 \
-segment_format_options movflags=+faststart -segment_format mp4 \
-reset_timestamps 1 \
/home/pi/%Y-%m-%d_%H-%M.mp4

スクリプトの完成系はこんな感じです。
これをサービスとしてsystemdに登録しておけば、ラズパイが起動すると自動的に録画を開始

raspividのオプション
オプション 説明
-o 出力ファイル名
-w,-h 解像度
-t 録画時間
-fps フレームレート
-b ビットレート

取得した動画データはFFmpegに渡すので-oでは出力ファイル名を指定しません。
録画時間に上限を設けないなら0で良いでしょう。
解像度やビットレート等はお好みで。

必要なオプションを記述したら、|でFFmpegにパイプ入力

FFmpegのオプション
オプション 説明
-r フレームレート
-i 入力ファイル
-vcodec 動画のコーデック
-strftime 出力ファイル名に日時を使用するためのオプション
-segment_time 分割時間
-segment_format_options movflags=+faststart 動画のメタデータ情報を先頭に付与する
-segment_format 分割する動画のフォーマット
-reset_timestamps セグメントのタイムスタンプのリセット

4行目以降はFFmpegについての記述になります。
見やすくするために適宜改行してありますが、もちろん不要なら改行しなくてもOK

フレームレートはraspividコマンドで指定した数字に合わせましょう。
入力ファイルについては、今回はパイプ入力するので指定しません。
動画の拡張子は変換しますがコーデックは変わらないのでcopyです。

-strftimeは出力ファイル名に日時を使用するためのオプションです。
-segment_timeで何秒毎に分割するのか時間を指定します。

-segment_format_options movflags=+faststartを記述しておくと、
動画の読み込みにかかる時間が短縮されて再生開始が早くなります。
-segment_formatはそのままです

タイムスタンプをリセットせずにセグメントファイルとして保存すると、
再生時に早送りやシークができなかったり何かと不便なことになります。
リセットしておけば普通の独立した動画として再生することが可能なので、
リセットしておきました。

最後に出力ファイル名の指定についてですが、
今回使用しているのはDATEコマンドではないので書式が異なることに注意してください。
-や_の区切り方などについては自由に書き換えて大丈夫

これをもとにファイルパスを変更し
角度を調整したのが以下のスクリプト

raspivid -o - -rot 270  -w 1280 -h 720 -t 0 -fps 30 -b 2000000 | ffmpeg -r 30 -i - -vcodec copy -f segment -strftime 1 -segment_time 60 -segment_format_options movflags=+faststart -segment_format mp4 -reset_timestamps 1 /home/snowpool/Videos/%Y-%m-%d_%H-%M.mp4

これで Videosディレクトリに1分ごとの動画が保存される

あとはこれを

sudo nano /opt/record.sh

へ記述して

問題がなければ、ラズパイの起動と同時に録画を開始するためにスクリプトをサービスとしてsystemdに登録

sudo nano /etc/systemd/system/record.service

中身は

[Unit]
Description = Drive Recorder

[Service]
ExecStart = /opt/record.sh #スクリプトのパス
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target

登録が完了したらサービスを有効化、起動

sudo systemctl enable record.service

sudo systemctl start record.service

サービスが正常に起動してスクリプトが実行されたらひとまずOK

gmail読み上げ (タイトル取得まで)

gmail読み上げ (タイトル取得まで)

ダウンロードしたファイルをコピーしてリネームする
詳細は
https://developers.google.com/gmail/api/quickstart/python?hl=ja
にあるが
とりあえず
credentials.json
にしておく

cd Downloads
cp client_secret_336287491272-faqvqnb4hjrg4ragurjh8nfhn2s3ujkg.apps.googleusercontent.com.json credentials.json

のあと作業ディレクトリ作成

mkdir -p mail_auto

ここへ認証ファイルの credentials.json をコピーする

あとはライブラリのインストール

pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

次に
quickstart.py
を作成し
コピペして動作確認

from __future__ import print_function

import os.path

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']


def main():
    """Shows basic usage of the Gmail API.
    Lists the user's Gmail labels.
    """
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    try:
        # Call the Gmail API
        service = build('gmail', 'v1', credentials=creds)
        results = service.users().labels().list(userId='me').execute()
        labels = results.get('labels', [])

        if not labels:
            print('No labels found.')
            return
        print('Labels:')
        for label in labels:
            print(label['name'])

    except HttpError as error:
        # TODO(developer) - Handle errors from gmail API.
        print(f'An error occurred: {error}')


if __name__ == '__main__':
    main()

保存したら

python3 quickstart.py

で実行

この時に認証画面が出るが
セキュリティの危険があるような警告が出る
これはサーバーのオレオレ証明書の時のようなものなので
気にせず続ける

認証が終わると
メールのラベル一覧が表示される

M1MacBookAir でVOICEVOX

Windows/Macに入れたVOICEVOXをPython経由で使う方法

ラズパイ等の非力なPCからPythonやcurlで呼び出し使う方法
が載っていた

残念ながら
NVIDIA製のGPUを持っていないので
とりあえずM1Mac で動かしてみて
できるようならラズパイ4から実行してみる

まずはM1Mac で実行

https://voicevox.hiroshiba.jp/how_to_use/
でダウンロードをクリック

OSの選択をするときにMac にすると
CPUのみの選択になる

パッケージは
インストーラを選択

ダウンロード後に起動しようとしたけど
VOICEVOX”は、開発元を検証できないため開けません。
となるため

https://voicevox.hiroshiba.jp/how_to_use/
を参考に
アップルメニューから「システム環境設定」を選択して「セキュリティとプライバシー」 をクリックしこのまま開くをクリックすることで起動

もしくは
Finder で ctrを押しながら開くことでも可能

使い方の細かい説明は
https://voicevox.hiroshiba.jp/how_to_use/
を参考に

とりあえずインストールはできたので
Voicevox core を使うようにする

Raspberry PiでVOICEVOXに可愛くしゃべってもらおう
では
ラズパイで実行しているけど
M1macで実行してるのを調べたら

VOICEVOX ENGINE(API)のスループット検証

インストール先のディレクトリに移動して、以下のコマンドを実行
とあるので
まずはインストール先ディレクトリを探す

https://voicevox.hiroshiba.jp/qa/
によれば
Mac 版

/Applications/VOICEVOX もしくは /Users/(ユーザー名)/Applications/VOICEVOX

とあったけど
Ls コマンドで調べたら

ls -a /Applications/VOICEVOX.app/Contents/MacOS/

でこの中のディレクトリに
Run が入っていた

cd /Applications/VOICEVOX.app/Contents/MacOS 

で移動し

./run

を実行したけど
VOICEVOXを動かしている状態だとエラーになる

以下エラーログ

Warning: cpu_num_threads is set to 0. ( The library leaves the decision to the synthesis runtime )
INFO:     Started server process [43567]
INFO:     Waiting for application startup.
reading /Users/snowpool/Library/Application Support/voicevox-engine/tmpjvxkxzht ... 64
emitting double-array: 100% |###########################################| 

done!
INFO:     Application startup complete.
ERROR:    [Errno 48] error while attempting to bind on address ('127.0.0.1', 50021): address already in use
INFO:     Waiting for application shutdown.
INFO:     Application shutdown complete.

一度VOICEVOXを終了し再度実行

Warning: cpu_num_threads is set to 0. ( The library leaves the decision to the synthesis runtime )
INFO:     Started server process [43611]
INFO:     Waiting for application startup.
reading /Users/snowpool/Library/Application Support/voicevox-engine/tmpnlpnbr_w ... 64
emitting double-array: 100% |###########################################| 

done!
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:50021 (Press CTRL+C to quit)
    

となり起動したので
http://127.0.0.1:50021
へアクセスしたけど

{"detail":"Not Found"}

となってしまう

chmod 755 run
./run --host 0.0.0.0

の後に
https://0.0.0.0:50021
でアクセスすると
ページを開けません
0.0.0.0:50021はアドレスが無効なため開けません
となる

よく調べたら
http://127.0.0.1:50021/docs
が正解だった

これでAPIドキュメントが表示される

Yolov8 を M1 Mac で使う

Yolov8 を M1 Mac で使う

YOLOv8導入まとめ
を参考に

pip install ultralytics

を実行

物体検出

yolo predict model=yolov8n.pt source='https://ultralytics.com/images/bus.jpg'

というように
Source に画像ファイルを指定すればOKみたい

物体検出ではなくセグメンテーションしたい場合は、yolov8n.ptではなくyolov8n-seg.ptを使う

yolo predict model=yolov8n-seg.pt source='https://ultralytics.com/images/bus.jpg'

これもsourceで画像ファイルを指定する

コマンドを実行すると

runs/detect/predict/

に指定したファイル名と同じファイル名で検出結果が作成される
とあるが

Results saved to runs/detect/predict

でどこに保存されているかわからないため

更新日が最近のファイルを見つける(findコマンド)
を参考に

find . -mtime -1 -ls | top

で検索し

ls ./runs/detect/predict 

でファイルができているのを確認

Finder から開くと面倒なので

MacでターミナルからFinderを開くコマンド「open」
を参考に

open .

でカレントディレクトリを Finder で開いて確認

ちなみに
yolov8n.pt
yolov8n-seg.pt

Nはモデルのサイズで
x > l > m > s > n
の順に大きなモデルになっている

xが最も大きいモデルで、nが最も小さいモデル

大きいモデルは検出にパワーが必要になるものの、検出精度が高くなる

xサイズのモデルで検出なら

yolo predict model=yolov8x.pt source='https://ultralytics.com/images/bus.jpg'

M1Mac 16GB で22秒ほどで処理できた

ポーズ検出には
yolov8x.ptの代わりにyolov8x-pose.ptを使う

yolo predict model=yolov8x-pose.pt source='https://ultralytics.com/images/bus.jpg'

これで
首から上が緑、腕が青、体がパープル、足がオレンジ色で、それぞれポーズが検出される

大体20秒くらいで処理

yolov8n.pt、yolov8n-seg.pt、yolov8n-pose.ptなどについての情報は、YOLOv8 Modelsにある

なおGPUを活用するには
Google Colaboratory
を使う

ちなみに興味があったんで
maMacbookAir 16GBでどのくらいかかるか実験

yolo predict model=yolov8x-seg.pt source='https://youtu.be/Zgi9g1ksQHc'

を実験したけど

Ultralytics YOLOv8.0.132 🚀 Python-3.10.6 torch-2.0.1 CPU
YOLOv8x-seg summary (fused): 295 layers, 71797696 parameters, 0 gradients

ERROR: Unable to extract uploader id; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see  https://yt-dl.org/update  on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.
Traceback (most recent call last):
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/youtube_dl/YoutubeDL.py", line 815, in wrapper
    return func(self, *args, **kwargs)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/youtube_dl/YoutubeDL.py", line 836, in __extract_info
    ie_result = ie.extract(url)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/youtube_dl/extractor/common.py", line 534, in extract
    ie_result = self._real_extract(url)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/youtube_dl/extractor/youtube.py", line 1794, in _real_extract
    'uploader_id': self._search_regex(r'/(?:channel|user)/([^/?&#]+)', owner_profile_url, 'uploader id') if owner_profile_url else None,
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/youtube_dl/extractor/common.py", line 1012, in _search_regex
    raise RegexNotFoundError('Unable to extract %s' % _name)
youtube_dl.utils.RegexNotFoundError: Unable to extract uploader id; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see  https://yt-dl.org/update  on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/pafy/backend_youtube_dl.py", line 40, in _fetch_basic
    self._ydl_info = ydl.extract_info(self.videoid, download=False)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/youtube_dl/YoutubeDL.py", line 808, in extract_info
    return self.__extract_info(url, ie, download, extra_info, process)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/youtube_dl/YoutubeDL.py", line 824, in wrapper
    self.report_error(compat_str(e), e.format_traceback())
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/youtube_dl/YoutubeDL.py", line 628, in report_error
    self.trouble(error_message, tb)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/youtube_dl/YoutubeDL.py", line 598, in trouble
    raise DownloadError(message, exc_info)
youtube_dl.utils.DownloadError: ERROR: Unable to extract uploader id; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see  https://yt-dl.org/update  on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/snowpool/.pyenv/versions/3.10.6/bin/yolo", line 8, in <module>
    sys.exit(entrypoint())
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/ultralytics/yolo/cfg/__init__.py", line 407, in entrypoint
    getattr(model, mode)(**overrides)  # default args from model
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context
    return func(*args, **kwargs)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/ultralytics/yolo/engine/model.py", line 255, in predict
    return self.predictor.predict_cli(source=source) if is_cli else self.predictor(source=source, stream=stream)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/ultralytics/yolo/engine/predictor.py", line 195, in predict_cli
    for _ in gen:  # running CLI inference without accumulating any outputs (do not modify)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 35, in generator_context
    response = gen.send(None)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/ultralytics/yolo/engine/predictor.py", line 222, in stream_inference
    self.setup_source(source if source is not None else self.args.source)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/ultralytics/yolo/engine/predictor.py", line 203, in setup_source
    self.dataset = load_inference_source(source=source, imgsz=self.imgsz, vid_stride=self.args.vid_stride)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/ultralytics/yolo/data/build.py", line 159, in load_inference_source
    dataset = LoadStreams(source, imgsz=imgsz, vid_stride=vid_stride)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/ultralytics/yolo/data/dataloaders/stream_loaders.py", line 48, in __init__
    s = get_best_youtube_url(s)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/ultralytics/yolo/data/dataloaders/stream_loaders.py", line 386, in get_best_youtube_url
    return pafy.new(url).getbest(preftype='mp4').url
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/pafy/pafy.py", line 124, in new
    return Pafy(url, basic, gdata, size, callback, ydl_opts=ydl_opts)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/pafy/backend_youtube_dl.py", line 31, in __init__
    super(YtdlPafy, self).__init__(*args, **kwargs)
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/pafy/backend_shared.py", line 97, in __init__
    self._fetch_basic()
  File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/pafy/backend_youtube_dl.py", line 43, in _fetch_basic
    raise IOError(str(e).replace('YouTube said', 'Youtube says'))
OSError: ERROR: Unable to extract uploader id; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see  https://yt-dl.org/update  on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.

で終了してしまった

とりあえず静止画像はここまででできそうなので
【やってみた】YOLOv8の機能試す&Webカメラでリアルタイム推論
を参考に
リアルタイムでできるようにする

ラズパイゼロで ダイレクト TCP ストリーミングでの配信と opencv で MacBookAir で再生

ラズパイゼロで
ダイレクト TCP ストリーミングでの配信と
opencv で MacBookAir で再生

とりあえずラズパイゼロWをセット

sudo apt-get update
sudo apt-get upgrade

のあと

sudo raspi-config


最初のメニューの5番目の項目、Interfacing Optionsを開くと1番上にカメラの項目があるのでこれを有効化

再起動になるので
再度SSHで接続する

ラズパイゼロだと非力なので画像処理などは難しそうだけど
とりあえず
v4l2-ctl –list-devices
使用するカメラのデバイスファイルを調べる

結果は

bcm2835-codec-decode (platform:bcm2835-codec):
	/dev/video10
	/dev/video11
	/dev/video12
	/dev/video18
	/dev/video31
	/dev/media2

bcm2835-isp (platform:bcm2835-isp):
	/dev/video13
	/dev/video14
	/dev/video15
	/dev/video16
	/dev/video20
	/dev/video21
	/dev/video22
	/dev/video23
	/dev/media0
	/dev/media1

mmal service 16.1 (platform:bcm2835_v4l2-0):
	/dev/video0

次に

v4l2-ctl -d /dev/video0 --list-formats


サポートしている動画のフォーマットを表示

結果は

ioctl: VIDIOC_ENUM_FMT
	Type: Video Capture

	[0]: 'YU12' (Planar YUV 4:two:0)
	[1]: 'YUYV' (YUYV 4:two:2)
	[2]: 'RGB3' (24-bit RGB 8-8-8)
	[3]: 'JPEG' (JFIF JPEG, compressed)
	[4]: 'H264' (H.264, compressed)
	[5]: 'MJPG' (Motion-JPEG, compressed)
	[6]: 'YVYU' (YVYU 4:two:2)
	[7]: 'VYUY' (VYUY 4:two:2)
	[8]: 'UYVY' (UYVY 4:two:2)
	[9]: 'NV12' (Y/UV 4:two:0)
	[10]: 'BGR3' (24-bit BGR 8-8-8)
	[11]: 'YV12' (Planar YVU 4:two:0)
	[12]: 'NV21' (Y/VU 4:two:0)
	[13]: 'RX24' (32-bit XBGR 8-8-8-8)

ラズパイで動画を撮影する方法として、FFmpegを使用してリアルタイムでハードウェアエンコードする方法がよく紹介されていますが、特にRaspberry Pi Zeroだとフレームレートがあまり出ないのでドラレコには不向き

しかしハードウェアエンコードなんてしなくても、H.264をサポートしているカメラモジュールを使用すれば、専用の動画撮影コマンドraspividを実行することで簡単にH.264動画を撮影することが可能

安価なUSB接続のWebカメラだとH.264をサポートしていなかったりしますが、私が確認した限りではラズパイ向けのカメラモジュールはどれもH.264をサポートしているので、基本的にraspividで録画することをおすすめ

raspividで動画を撮影するには
もっともシンプルに書くなら、-oで出力ファイル名のみを指定してこのように記述
なお指定した名前のファイルが既に存在する場合は実行に失敗するので注意

raspivid -o test.h264

このように何も指定せずに実行すると5秒の動画ファイルが生成される

とりあえず動画撮影はできたので
UDP配信をしてみる

これにはUDPストリーミング配信先のIPアドレスが必要
MacbookAir でまずは実験するので
LanScanでネットワークのIPアドレスを表示

192.168.1.137がアドレスなのが判明したので

RaspberryPiをWebカメラとして使用する
を参考に

raspivid -a 12 -t 0 -w 1920 -h 1080 -hf -ih -fps 30 -o udp://192.168.1.137:5000

を実行しても

mmal: Failed to write buffer data (2470 from 5350)- aborting
mmal: Failed to write buffer data (2739 from 8877)- aborting

となってしまう

raspivid -a 12 -t 0 -w 1920 -h 1080 -vf -ih -fps 30 -l -o tcp://0.0.0.0:5000


ダイレクト TCP ストリーミング
はできた

リモートの環境のPythonからOpenCVを使い、手元のWebカメラの映像を読みたい
を参考に

vim camera.py  

import cv2
cap = cv2.VideoCapture("tcp://192.168.1.215:5000") # 配信のURLを指定

while True:
  k = cv2.waitKey(1)
  if k == 27: # ESC key
    break

  ret, frame = cap.read()
  if not ret:
    continue

  cv2.imshow('Raw Frame', frame)

cap.release()
cv2.destroyAllWindows()

で保存

これで実行するとmac でラズパイゼロの動画が表示できる

後はここから mac側で画像認識とかできるかテストしていく

stable diffusion web UI のインストールログ

stable diffusion web UI のインストールログ

https://mac-ra.com/mac-automatic1111-stable-diffusion-webui/#toc_id_1
を参考に

brew install cmake protobuf rust python@3.10 git wget

で必要なものをインストール

しかし

Error: No developer tools installed.
Install the Command Line Tools:
 xcode-select --install

が出る

エラーを元に検索
https://techracho.bpsinc.jp/wingdoor/2021_04_09/104821
を参考に

sudo xcode-select --install

めっちゃ時間がかかる

終わったら
再度

brew install cmake protobuf rust python@3.10 git wget

これで成功

cd ~
git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui

今回はモデルとして
AOM3_orangemixs.safetensors
を使ってみた

AOM3_orangemixs.safetensors

をダウンロードして移動してみる

https://mac-ra.com/mac-automatic1111-stable-diffusion-webui/#toc_id_1
によれば
ckpt、safetensors などのモデルの置き場は、この models/Stable-diffusion フォルダになる

cp Downloads/AOM3_orangemixs.safetensors stable-diffusion-webui/models/Stable-diffusion 

でファイルをコピー

cd ~/stable-diffusion-webui
./webui.sh

でインストール開始

http://127.0.0.1:7860
とでたら safari でアクセス

後はこれで好みのモデルがあれば

stable-diffusion-webui/models/Stable-diffusion
へコピー

ネガティブプロンプトも rola のようにまとめてあるものがあるので
EasyNegative.safetensors

をダウンロード

 cp Downloads/EasyNegative.safetensors stable-diffusion-webui/embeddings 

ネガティブプロンプトに「EasyNegative」と入力する