メインコンテンツへスキップ
見出し画像

Raspberry Piでやってみた2(画像処理):物体検出ーYOLO/OAK-D OpenCV DepthAI

    1.概要

     Rasberry Piでできることの一つにカメラを用いた撮影があります。環境構築も完了してカメラ動作も確認出来たら次はAIで遊びたくなります。

     今回は「物体検出ライブラリのYOLO」と「OAK-D OpenCV DepthAI」の2つで物体検出できるか確認しました。

    1-1.Rasberry Piの環境構築

     1章の紹介記事をベースにOpenCV使用前にRasberry Piの環境構築を実施しておきます。概要は下記の通りであり詳細は記事をご確認ください。

    【仕様】

    • 本体:Rasberry Pi 4

      • CPU:ARM v8

    • Rasberry Pi OS:Debian Bullseys 64bit(Release:2023/5/3)

    • カメラモジュール:Raspberry Pi カメラモジュール V3

    • ラズパイシステムのPython Version:3.9.2

    • その他:Conda環境のためMiniforge追加

    画像
    https://www.iodata.jp/product/pc/raspberrypi/ud-rp4b/spec.htm

    【Rasberry Piの環境構築】

    1. Raspberry Pi OS(64-bit) :BullseyeをRasberry Pi Imagerで書き込み

    2. ラズパイ初期起動時の設定、インターフェースの有効化

    3. システム更新”sudo apt-get update && sudo apt-get upgrade”を実施

    4. 任意:リモートアクセスの準備

      • ファイルのやり取りができるためVNC Viewerを使用

    5. 任意:VS Code、Miniforgeをインストール

    6. 任意:ソフトウェア(vim, git)を追加

    7. 任意:Linuxコマンドパッケージ(Zip, aptitude)を追加

    8. カメラモジュールの環境構築

      1. 今回はRasberry Pi4×カメラモジュールV3の環境で作成

      2. 動作確認は事前に”libcamera-hello”で確認すること

    9. OpenCVの環境構築

    [Terminal※Webカメラ動作確認用]
    libcamera-hello

    1-2.画像処理ライブラリの紹介

     画像処理ができるPythonライブラリ+αは下記の通りです。

    • OpenCV:OpenCVはコンピュータビジョンのためのオープンソースライブラリであり画像処理、顔認識、物体検出などができます。

    • YOLO(You Only Look Once):リアルタイムでの物体検出を行うためのアルゴリズム

    • OpenPose:人体の姿勢を検出するためのライブラリ

    • MediaPipe:Googleが開発したマルチプラットフォーム向けの機械学習ソリューションであり、手のトラッキングや顔検出などの機能があります。

    • OAK-D OpenCV DepthAI:深度情報を持つ3Dビジョンを実現するためのデバイス

    2.参考:Linuxコマンド

     参考用に使用するLinuxコマンドを参考用として記載します。

    2-1.Linuxコマンド

    1. apt:「Advanced Package Tool」の略で、DebianベースのLinuxディストリビューション(例: Ubuntu, Raspberry Pi OS)でソフトウェアパッケージを管理するためのツールです。aptを使用することで、ソフトウェアのインストール、アップデート、削除などの操作を行うことができます。また、apt-cacheコマンドを使用して、利用可能なパッケージの情報を検索することもできます。

    2. apt-get:DebianベースのLinuxディストリビューション(例: Ubuntu)で使用されるパッケージ管理ツールです。これを使用してソフトウェアのインストール、アップデート、削除などを行います。

      • install:ソフトウェアをインストール

    3. bash:シェルスクリプトを実行するコマンド

      • -b:バッチモードでインストール+確認プロンプトを表示しない。つまりインストールが自動的に進行します。

      • -u:既存のインストールを更新。つまり既にMinicondaがあるなら、そのインストールを最新のバージョンに更新する。

      • -p:インストール先のディレクトリを指定

    4. cd:"change directory"の略。ターミナル上の作業場所を移動する

      • ~:ホームディレクトリを示す。”cd ~”で立ち上げ時のdirに移動

    5. cp:ファイルやディレクトリをコピーするコマンド

    6. df:ディスクの使用量を表示(-hオプションで体裁を綺麗にする)

    7. free:メモリ使用量を表示(-mオプションでMB単位で出力)

    8. ln:ファイルのリンクを作成するためのコマンド

    9. lsb_release:Linux Standard Base (LSB) に関する情報を表示するコマンドであり、-aオプションですべての情報を表示

    10. ls:作業ディレクトリ内のファイルを表示

      1. -lt:作成時間も含めて表示

    11. mkdir:”make directory”の略。新しいフォルダを作成

      • -p:指定したディレクトリが無い場合は作成する。また必要な親ディレクトリも合わせて作成

    12. nano:nanoエディタで指定したファイルを開く

    13. patch:ソースコードにパッチを適用するためのコマンド

      • -p1:パッチファイルのディレクトリ構造をどの程度削除するかを指定->1レベルのディレクトリ構造が削除されます。

      • -i:入力として使用するパッチファイルを指定

    14. rm:"remove"の略で、ファイルやディレクトリを削除するコマンド

      • -r(--recursive):ディレクトリとその内容を再帰的に削除する。ディレクトリを削除する場合はこのオプションが必要

      • -f(--force):エラーメッセージ、警告や確認を表示せずに強制的にファイルやディレクトリを削除

    15. shutdown:コンピューターの電源をオフ/再起動するためのコマンド

      • -rオプション:再起動

    16. sudo:「SuperUser DO」の略で特定のコマンドをシステム管理者(rootユーザー)として実行するためのコマンドです。sudoを使用することで、一時的に高い権限を持つrootユーザーとしてコマンドを実行できます。

    17. tar:ファイルやディレクトリをアーカイブ化、またはアーカイブを展開するためのコマンド(zipみたいに圧縮・展開する)

      • -x:展開

      • -z:gzipで圧縮されたアーカイブを処理

      • -v:詳細モードで動作->処理されているファイルのリストが表示

      • -f:アーカイブファイル名を指定

      • -C:展開先のディレクトリを指定->ホームディレクトリに展開

    18. update:aptのサブコマンドの一つでソフトウェアのリポジトリから最新のパッケージ情報を取得して、ローカルのパッケージデータベースを更新

    19. unzip:ダウンロードしたzipファイルを展開

    20. wget:インターネットからファイルをダウンロード

      • -O:DLしたファイルの保存先と名前を指定

    2-2.Rasberry Pi用コマンド

    1. raspi-config:Raspberry Piのシステム設定ツールを開く

    2. rpi-update:Raspberry Piのファームウェアをアップデート

    https://www.yukkuriikouze.com/2019/02/05/1608/

    https://qiita.com/takeaship/items/5861660c11d9d434368f

    2-3.コマンド使用例

     実際のコマンド使用例は下記の通りです。

    1. ls -lt:作成時間も含めて作業ディレクトリ内のファイルを表示

    2. sudo apt update:インストール可能なソフトウェアのパッケージのリストを最新の状態に更新

    3. sudo apt upgrade:インストールされているソフトウェアを最新のバージョンに更新

    4. sudo shutdown -h now:今すぐシャットダウン(電源OFF)

    5. shutdown -r now:今すぐ再起動を実施する

      • ”sudo reboot now”でも再起動可能

    6. python3 -c "import cv2; print(cv2.file)":PythonでOpenCVをimportしてファイルの場所を表示

    7. sudo find / -name "opencv.hpp" 2>/dev/null:システム全体を検索して、OpenCVのヘッダーファイルやライブラリの場所を特定

    8. sudo find / -name "libopencv*.so*" 2>/dev/null:頭に"libopencv"で途中に".so"を持つファイルの場所を検索

    画像

    3.YOLOv3

     結論としては「私の環境では環境構築が無理なため動かなかった」です。別環境なら動くかもしれないので参考として残しておきます。
     原因はRasberry Pi4×カメラモジュールv3×Opencv4×Darknetの環境が合ってないためと思います。

    3-1.環境構築1:darknetの準備

     YOLOv3が使用できる環境を作成していきます。

     3-1-1.Linuxコマンド追加

     Linuxコマンドとしてmake, gcc, g++を追加します。コマンドは”sudo apt install make gcc g++”でも下記でもOKです。

    [Terminal]
    sudo apt install make 
    sudo apt install gcc
    sudo apt install g++
    画像

     私は以前OpenCVの環境構築でインストール済みのため上図となりました。

     3-1-2.作業Dirにdarknetをクローン

     好きな作業ディレクトリに移動して、GitHubからdarknet(YOLOライブラリ)をインストールします。
     私は作業ディレクトリをDesktopにしたためデスクトップ上に”darknet”フォルダが作成されました。次に、作業ディレクトリを"darknet"に変更したらlsコマンドで"Makefile"があることを確認します。

    [Terminal]
    cd Desktop/
    git clone https://github.com/pjreddie/darknet
    [Terminal]
    cd darknet/
    ls
    画像

    3-2.環境構築2:リアルタイム検出用設定

     静止画だけであれば本作業は不要なため次節からご確認ください。もしリアルタイムで物体検出したい場合はConfigの設定が必要になります。

     なお注意点として私の環境では設定しても最終的に成功はしませんでした。ただかなり惜しいところまで来てるのでメモ用として記載しております。

     3-2-1.OpenCVの有効化

     darknetでは様々なフォーマットに対応できるようにOpenCVを利用しています。OpenCVはデフォルトでは無効になっています。有効化するためにMakefileを開き"OPENCV"変数を1に設定します。

    [Terminal]
    nano Makefile

     なお修正にはnanoエディタを使用しますが”Ctrl+X=終了”、”Ctrl+U=貼り付け”を覚えておくと便利です。

    [修正前:Makefile]
    OPENCV=0
    [修正後:Makefile]
    OPENCV=1
    画像
    画像

     3-2-2.OpenCV連携の設定

     再度”Makefile”を開きOpenCVとの連携を設定します。元々ある設定を"#"でコメントアウトして、別のコードを追加します。

    1. ifeq ($(OPENCV), 1):OPENCV=1の場合に実行

    2. COMMON::コンパイル時に使用される共通のフラグを設定

      • -DOPENCV:#ifdef OPENCV という条件付きコンパイルを行う用

      • -I/<Path>:OpenCVのヘッダーファイルの場所を指定(-Iオプションはディレクトリの場所を指定)

    3. CFLAGS::C言語のソースコードをコンパイル時に使用するフラグを設定

    4. LDFLAGS: プログラムをリンクする際に使用されるフラグを設定

      • -L:ライブラリのディレクトリを指定するためのオプション

    [Terminal]
    nano Makefile
    [Makefile]
    ifeq ($(OPENCV), 1) 
    #COMMON+= -DOPENCV
    #CFLAGS+= -DOPENCV
    #LDFLAGS+= `pkg-config --libs opencv` -lstdc++
    COMMON+= -DOPENCV -I/usr/local/include/opencv4
    CFLAGS+= -DOPENCV
    LDFLAGS+= -L/usr/local/lib -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_videoio -lop>
    
    #COMMON+= `pkg-config --cflags opencv` 
    endif
    画像

    【参考:ファイルの確認方法】
     
    OpenCVに関するファイルの場所は下記で確認しました。

    1. ls /dev/video*:システム上のビデオデバイスをリスト表示

    2. ls /usr/local/include/opencv4/:OpenCVのインストール先

    3. python3 -c "import cv2; print(cv2.__file__)":OpenCVのファイルの場所

    4. sudo find / -name "opencv.hpp" 2>/dev/null:OpenCVのヘッダーファイル

    5. sudo find / -name "libopencv*.so*" 2>/dev/null:ライブラリの場所

    [Terminal]
    ls /dev/video*
    ls /usr/local/include/opencv4/
    python3 -c "import cv2; print(cv2.__file__)"
    sudo find / -name "opencv.hpp" 2>/dev/null
    sudo find / -name "libopencv*.so*" 2>/dev/null
    [OUT]
    opencv2
    
    /usr/local/lib/python3.9/dist-packages/cv2.so
    
    /home/kiyo/Desktop/opencv/opencv-4.8.1/include/opencv2/opencv.hpp
    /home/kiyo/Desktop/opencv/opencv/include/opencv2/opencv.hpp
    /usr/local/include/opencv4/opencv2/opencv.hpp
    
    /home/kiyo/Desktop/opencv/opencv-4.8.1/build/lib/libopencv_plot.so.4.8.1
    以下省略
    画像

     3-2-3.旧APIの変更

     YOLOv3はOpenCV3の時に開発されております(OpenCV 4.0のリリースは2018年11月)。これらの影響により下記修正が必要です。

    1. 旧C言語ベースのAPIの機能を利用(IplImage)

    2. IplImageへの直接変換の部分を修正

    3. ”CV_”を"cv::"に変更

    画像
    https://deepsquare.jp/2020/09/yolo/

     YOLOv3ドキュメントではGPUやOPENCVの設定しか記載されてなく、OpenCVを設定完了してもエラーが出ました。原因としてOpenCV4系ではIplImageが削除されたためと想定されます。
     そこで”src/image_opencv.cpp”ファイルの行頭に”#include <opencv2/core/core_c.h>”を追加して、旧C言語ベースのAPIの機能を利用できるようにしました。

    [Terminal]
    nano src/image_opencv.cpp
    [src/image_opencv.cpp]
    #include <opencv2/core/core_c.h>
    画像

     次に、C++のcv::Matオブジェクト(m)を旧C APIのIplImage形式に変換しています。元々記載のあった"IplImage ipl = m;"を"//"でコメントアウトして"IplImage ipl = cvIplImage(m);"を追加しました。

    [src/image_opencv.cpp]
        //IplImage ipl = m;
        IplImage ipl = cvIplImage(m);
    画像

     最後に新しいC++ APIに対応するために”src/image_opencv.cpp”ファイル中の”CV_XX”を全て"cv::XX"に修正しました。変更箇所は複数あるため注意が必要です。

    画像
    画像

    3-3.環境構築3:ビルド/重み取得

     3-3-1.darknetをビルド

     確認できたら"make"でビルドします。
     ※もしリアルタイムで検出したい方はMakefileなどの設定はビルド(make)前に実施する必要があります。

    [Terminal]
    make
    画像

     ビルドが完了したら作業ディレクトリにsoファイル(libdarknet.so)などが作成されました。

    画像

     3-3-2.学習済みモデルのDL

     事前に学習されたYOLOの重みをインストールします。"tiny"はsmall modelのため軽量に動かすことが出来ます。

    [Terminal]
    wget https://pjreddie.com/media/files/yolov3.weights
    wget https://pjreddie.com/media/files/yolov3-tiny.weights

     完了すると"yolov3.weights"と"yolov3-tiny.weights"ファイルが確認できました(※画像はyolov3.weightsのみ)。

    画像

    3-4.動作確認:静止画の物体検出

    【yolov3.weights】
     動作確認のためテスト画像でYOLOを試します。下記コード実行すると"darknet\data"フォルダにある"dog.jpg"から物体を検出します。

    [Terminal]
    ./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
    画像

     2~3minくらいで処理が完了するとdarknetフォルダ内に"predictions.jpg"が作成されます。本画像内で物体認識されていることが確認できました。
    ※さすがにGPU無しのRasberry Piだと遅い!

    画像

    【yolov3-tiny.weights:軽量版モデル】
     
    フルモデルだと2-3分と処理時間が長いため軽量版モデルを使用しました。こちらでは10s程度で終了しましたが車の認識がやや甘い結果となりました。

    [Terminal]
    ./darknet detect cfg/yolov3-tiny.cfg yolov3-tiny.weights data/dog.jpg
    画像

    3-5.リアルタイムの物体検出

     下記ではどうやってもリアルタイム検出できませんでした。結果としてカメラから画像が読み取れず出力が得られていないためimshow()でエラーになっています。

    [Terminal]
    ./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights
    [Terminal]
    ./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights -c 0
    [OUT]
    Loading weights from yolov3.weights...Done!
    terminate called after throwing an instance of 'cv::Exception'
      what():  OpenCV(4.8.1) /home/kiyo/Desktop/opencv/opencv-4.8.1/modules/highgui/src/window.cpp:971: error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'imshow'
    
    中止

     原因として考えられるのがカメラの相性です。前回の記事でもOpenCVの”cv2.VideoCapture(0)”でキャプチャできなかったためPicamera2を利用しました。
     今回もうまくカメラにアクセスできていないと想定されます。

    4.YOLOv5

     前回記事でYOLOv5の記事は作成しておりますが、LinuxやRasberry Pi用に作成しなおしました。

    4-1.環境構築1:仮想環境の作成

     まず初めにMiniforge(conda)を使用して"YOLOv5"という仮想環境を作成しました。Documentに記載の通りPythonのVersionは3.8以上が必要です。

    画像

     condaで仮想環境を作成します。完了したらconda activateで作成した環境に入りVersionも確認しておきます。

    [Terminal]
    conda create -n yolov5 python=3.8.0
    [Terminal]
    conda activate yolov5
    python3 --version
    
    [OUT]
    3.8.0
    画像
    画像

    【参考:仮想環境の削除-conda remove】
     新しく仮想環境を新しく作り直したい場合は①仮想環境から抜ける、②削除、③再作成 することで作り直すことが出来ます。

    [Terminal]
    conda deactivate
    conda remove -n yolov5 --all
    conda create -n yolov5 python=3.8.0
    画像

    4-2.環境構築2:レポジトリのクローン

     作業ディレクトリをDesktopに変更してYOLOv5をGitHubからクローンします。完了すると"yolov5"フォルダができます。作業ディレクトリをyolov5に移動します。

    [Terminal]
    cd Desktop/
    git clone https://github.com/ultralytics/yolov5
    cd yolov5
    画像

    4-3.コラム:エラー発生の理解

     通常は”pip install -r requirements.txt”をすればよいだけのはずですが、Rasberry Pi4では原因不明のエラーが大量発生します。

    1. Pytorchをインストールできない

    2. YOLOv5を実行すると”Segmentation fault”が発生

    3. ライブラリのVersionを変えると他との環境が合わない

    画像

     次節では「最適なPytorchとTorchvisionのVersionをインストール」したらうまくいきましたが、別環境ではうまくいかない可能性もあります。

     本節では「発生したエラー原因の備忘録」を記載しました。もし同様なエラーが発生した方はご参照ください。

     4-3-1.環境の確認

     まず重要なことは「自分が使用しているRasberry Piの環境を確認」することです。色々なブログに”これでできる”とあるのですが、ピンポイントの環境で整備されているため、完全に同じでないとエラーが出ます。
     Rasberry Pi4の仕様およびコマンドは下記の通りです。

    画像
    https://www.iodata.jp/product/pc/raspberrypi/ud-rp4b/spec.htm
    1. uname -a:システム情報の確認

      • uname -m:システムのアーキテクチャを確認->aarch64は64bit

    2. free -h:メモリ使用量の確認

      • メモリサイズが小さくエラーが出る場合はSwapfileの調整が必要

    3. cat /etc/os-release:Raspberry PiのOSのバージョンや名前などの情報表示

    4. lsb_release -a:Linux Standard Base(LSB)は特定のLinuxディストリビューションに関する情報を表示するコマンド

    [Terminal]
    uname -a
    uname -m
    
    [OUT]
    Linux raspberrypi 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr  3 17:24:16 BST 2023 aarch64 GNU/Linux
    aarch64
    [Terminal]
    free -h
    
    [OUT]
                   total        used        free      shared  buff/cache   available
    Mem:           7.6Gi       370Mi       2.5Gi        25Mi       4.7Gi       7.1Gi
    Swap:           99Mi          0B        99Mi
    [Terminal]
    cat /etc/os-release
    
    [OUT]
    PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
    NAME="Debian GNU/Linux"
    VERSION_ID="11"
    VERSION="11 (bullseye)"
    VERSION_CODENAME=bullseye
    ID=debian
    HOME_URL="https://www.debian.org/"
    SUPPORT_URL="https://www.debian.org/support"
    BUG_REPORT_URL="https://bugs.debian.org/"
    [Terminal]
    lsb_release -a
    
    [OUT]
    No LSB modules are available.
    Distributor ID:	Debian
    Description:	Debian GNU/Linux 11 (bullseye)
    Release:	11
    Codename:	bullseye

     4-3-2.Case1:torchのインストールエラー

     仮想環境作成時においてPythonのVersionを指定せずに適当に作成して、”pip install -r requirements.txt”を実行するとTorchがインストールできないエラーが発生しました。

    [Terminal]
    conda create -n test1
    conda activate test1
    python3 --version
    pip install -r requirements.txt
    [OUT]
    Python 3.9.2
    画像
    画像

     何回か繰り返すとエラーがでなくなったのですが、そもそも環境下で使用できませんでした。とりあえず仮想環境時はPythonのVersionを指定しておいた方が再現性は高くなります。

    画像

     4-3-3.Case2:TorchのWhlファイルが合わない

     多くの記事で「Rasberry Pi用にwhlファイル(ZIPファイルみたいなもの)からインストール」するパターンが見られます。whlファイルには命名規則があり、名前を見ると使用できる環境が分かります。

    [WHL ファイルの命名規則 ]
    {dist}-{version}(-{build})?-{python}-{abi}-{platform}.whl

     例は下記の通りですが、PythonのVersionが古かったり、Rasberry Pi4のアーキテクチャ(Cortex-A72 (ARM v8) 64-bit)に合ってなかったりします。
     PythonのVersionを合わせると"pip install -r requirements.txt"時にエラーがでたりするため、初学者での対応は不可能です。
     私も無理だったのでこの方法はあきらめました。

    • ファイル名:torch-1.8.0a0+56b43f4-cp37-cp37m-linux_armv7l.whl

    • distribution:Pytorch1.8.0

    • cp37:Python3.7系で使用

    • linux_armv7l:Linux OSでのARMv7アーキテクチャ

    【参考記事】

    4-4.環境構築3:ライブラリのインストール

     私の環境は下記の通りです。この場合、いったん必要なライブラリを全てインストールした後で、PytorchとTorchvisionを別Ver.に入れなおすことでうまくいきました。

    • 本体:Rasberry Pi 4

      • CPU:ARM v8

    • Rasberry Pi OS:Debian Bullseys 64bit(Release:2023/5/3)

    • python:3.8.0

    • 作業環境:Miniforgeによるcondaの仮想環境

    [Terminal]
    pip install -r requirements.txt
    pip3 uninstall torch torchvision
    pip3 install torch==1.11.0 torchvision==0.12.0

    4-5.動作確認:静止画の物体検出

     yolov5ディレクトリ内で"python3 detect.py"を実行すると”data/images"内にある画像を検出して出力されます。出力場所は"runs/detect/exp"に出力されました。

    [Terminal]
    python3 detect.py
    画像
    画像

    4-6.リアルタイムの物体検出

     今回もYOLOv3と同様にリアルタイムでの検出はできませんでした。これはOpenCVの”cv2.VideoCapture(0)”でキャプチャできなかったのと同様にカメラの相性が理由と推測されます。

    [Terminal]
    python3 detect.py --source 0
    [OUT]
    AttributeError: 'NoneType' object has no attribute 'shape'
    画像

    【番外編:USB-Webカメラの利用】
     
    Rasberry Pi用カメラモジュールではなくUSBカメラで動作検証してみました。USBカメラは安いやつを選定し、USB3(青色)に接続しました。

    画像

     事前にWebカメラのUSB接続前後で”ls /dev/video*”コマンドを実行し、どのvideoが所定のデバイスファイルか当たりを付けます。
     次に”v4l2-ctl --list-devices”で接続されているVideo4Linuxデバイスの一覧を表示し、カメラの番号を確認します。本コマンドはv4l2-utilsパッケージのため、インストールしていない人は事前に”sudo apt install v4l-utils”が必要となります。

    [Terminal]
    ls /dev/video*
    v4l2-ctl --list-devices
    画像
    [OUT]
    bcm2835-codec-decode (platform:bcm2835-codec):
    	/dev/video10
    	/dev/video11
    	/dev/video12
    	/dev/video18
    	/dev/video31
    	/dev/media3
    
    bcm2835-isp (platform:bcm2835-isp):
    	/dev/video13
    	/dev/video14
    	/dev/video15
    	/dev/video16
    	/dev/video20
    	/dev/video21
    	/dev/video22
    	/dev/video23
    	/dev/media0
    	/dev/media2
    
    unicam (platform:fe801000.csi):
    	/dev/video2
    	/dev/video3
    	/dev/media1
    
    rpivid (platform:rpivid):
    	/dev/video19
    	/dev/media4
    
    UVC Camera (046d:0825) (usb-0000:01:00.0-1.2):
    	/dev/video0
    	/dev/video1
    	/dev/media5

     結果としてUSBカメラはvideo0に該当すると判断できました(※別日にやったためデバイス番号は他の記事と同じ出ないものがあります)。
     "source <device No.>"を0に指定して実行するとUSBカメラから画像取得できていることが確認できました。

    [Terminal]
    python3 detect.py --source 0
    画像

    5.OAK-D OpenCV DepthAI

     Luxonis社のDepth AIを用いてRasberry Piから簡単に画像処理できるか試してみました。

    5-1.環境構築1:仮想環境の作成

     まずは仮想環境を作成します。DepthAIのPythonのVersion要求が確認できなかったのですが、とりあえず3.8系で作成しました。
     詐称場所をDesktopに変え、仮想環境を作成し、環境を有効化しました。

    [Terminal]
    cd Desktop/
    conda create -n depthai python=3.8
    conda activate depthai
    画像

    5-2.環境構築2:レポジトリのクローン

     公式GitHubに記載の通り、まず初めにレポジトリをクローンします。完了したらdepthaiフォルダが作成されます。
    ※--recursive:サブモジュールも含めてクローンしてくれる。

    [Terminal]
    git clone --recursive https://github.com/luxonis/depthai.git
    cd depthai
    画像

    5-3.環境構築3:OSにパッケージ追加

     インストーラーを用いてDepthAIに必要なパッケージをOSにインストールします。こちらは仮想環境とは関係なく、OSに対して1回の実施でよいです(公式はOne-time installationと記載があるため)。

     コマンドの意味は、curlで取得した"install_dependencies.sh"スクリプトをbashコマンドで実行します。

    [Terminal]
    sudo curl -fL https://docs.luxonis.com/install_dependencies.sh | bash
    画像

    5-4.環境構築4:ライブラリのインストール

     必要なライブラリをインストールします。

    [Terminal]
    python3 install_requirements.py
    画像

    【参考:install_requirements.py】
     install_requirements.pyの中身は下記の通りです。

    [install_requirements.py]
    #!/usr/bin/env python3
    import platform
    import subprocess
    import sys
    import os
    
    script_directory = os.path.dirname(os.path.realpath(__file__))
    this_platform = platform.machine()
    
    # https://stackoverflow.com/a/58026969/5494277
    # Check if in virtual environment
    in_venv = getattr(sys, "real_prefix", getattr(sys, "base_prefix", sys.prefix)) != sys.prefix
    pip_call = [sys.executable, "-m", "pip"]
    pip_installed = True
    pip_install = pip_call + ["install", "-U"]
    pip_package_install = pip_install + ["--prefer-binary"]
    
    try:
        subprocess.check_call(pip_call + ["--version"])
    except subprocess.CalledProcessError as ex:
        pip_installed = False
    
    if not pip_installed:
        err_str = "Issues with \"pip\" package detected! Follow the official instructions to install - https://pip.pypa.io/en/stable/installation/"
        raise RuntimeError(err_str)
    
    if sys.version_info[0] != 3:
        raise RuntimeError("Demo script requires Python 3 to run (detected: Python {})".format(sys.version_info[0]))
    
    is_pi = this_platform.startswith("arm")
    prebuiltWheelsPythonVersion = [7,9]
    if is_pi and sys.version_info[1] not in prebuiltWheelsPythonVersion:
    
        print("[WARNING] There are no prebuilt wheels for Python 3.{} for OpenCV, building process on this device may be long and unstable".format(sys.version_info[1]))
    
    if not in_venv:
        pip_install.append("--user")
        pip_package_install.append("--user")
    
    subprocess.check_call(pip_install + ["pip", "-U"])
    
    subprocess.check_call(pip_call + ["uninstall", "opencv-python", "opencv-contrib-python", "--yes"])
    subprocess.check_call(pip_call + ["uninstall", "depthai", "--yes"])
    subprocess.check_call(pip_package_install + ["-r", "requirements.txt"], cwd=script_directory)
    
    try:
        subprocess.check_call(pip_package_install + ["-r", "requirements-optional.txt"], cwd=script_directory, stderr=subprocess.DEVNULL)
    except subprocess.CalledProcessError as ex:
        print("Optional dependencies were not installed. This is not an error.")

    5-5.環境構築5:デバイスの接続

     デバイスをRasberry Piに接続します。注意点として必ずUSB3 cable(青色)の方に繋いでください。電源は付属品を用いて100Vコンセントからとりました。

    画像

     接続したら下記コマンドを実行してUSBが検出されるか確認します。

    [Terminal]
    lsusb | grep MyriadX
    画像

    【参考:コマンドの意味】
     lsusb
    でシステムに接続されているUSBデバイスの情報を取得しており、その情報を grep に渡して"MyriadX" という文字列が含まれる行を検索します。
     Depthaiがビジョン処理ユニットとしてMyriadXを使用しているためこのような表示になります。参考までにUSB接続前後において"lsusb"を実行した結果を表示しました。接続後に1行追加されていることが確認できます。

    画像

    5-6.リアルタイム検出

     5-6-1.デモ運転

     作業ディレクトリ上で下記コマンドを実行するだけです。実行後にウィンドウが立ち上がりカメラとともにデフォルトの物体検出モデルが動きます。

    [Terminal]
    python3 depthai_demo.py
    画像

     以前の記事においてWindows環境下での実行結果と異なりますが、カメラが動作することまでは確認できました。

     5-6-1.AIモデル指定

     起動時に"python depthai_demo.py -cnn <モデル名>"よりモデルを指定して実行できます。参考として公式のモデルリストを下表に示しますが一部はエラーとなります(おそらく適宜更新されている)ので使いたいモデルは"CNN model"から確認する必要があります。

    画像
    画像

     軽量版YOLOv3の結果は以下の通りです。軽量版モデルでもRasberry Piだと比較的かくつき※が発生しました。
    ※Depthaiの中にInterの処理プロセッサーがあると思うのですが、何用でどこまで使用しているかが理解出来ていません。

    [Terminal]
    python3 depthai_demo.py -cnn yolo-v3-tf
    画像

    5-7.Webカメラで利用1:UVC

     OAK devicesをWebカメラとして使用することも可能です。

     5-7-1.設定方法の確認

     Webカメラとして起動させるには2パターンあります。1はエラーが出たため2で実行していきます。

    1. Using DepthAI Demo Script

    2. Using UVC (USB Video Class)

      • UVCとは主にUSBカメラ(規格上は逆方向通信も可能であるので、例えばUSBディスプレイにも応用可能)の通信方法に関する規格

      • UVCに対応したデバイスはドライバが不要でUSBポートに接続するだけで自動的に認識される

    【エラーの内容:Using DepthAI Demo Script】
     公式Docsでは”python3 depthai_demo.py --app uvc”実行のみ記載があります。これを実行すると下記表示がありWebカメラは起動しませんでした。
     おそらくRasberry Pi4のCPU(AARCH64)との互換性が無いと判断できます。

    画像

     5-7-2.環境構築

     環境構築は公式に記載の通り下記手順で実施しました。

    1. GitHubから"depthai-python"レポジトリをクローン

    2. 作業ディレクトリを"depthai-python"に変更

    3. Gitコマンドで”develop”ブランチに切り替え

    4. 必要なライブラリのインストール

    [Terminal]
    git clone https://github.com/luxonis/depthai-python.git
    cd depthai-python
    git checkout develop
    python3 examples/install_requirements.py
    画像

     5-7-3.Webカメラ起動:UVC

     Webカメラの起動は"rgb_uvc.py"をPythonスクリプトとして実行します。注意点として公式ドキュメントとは別の場所にファイルがあるため「find . -name "rgb_uvc.py"」で事前にファイル場所を確認しました。

     起動は下記スクリプトを実行するだけとなります。起動したかどうかは「https://ja.webcamtests.com/」サイトで確認しました。スクリプトを停止するとWebカメラとして利用できなくなることも確認できました。
    ※特定サイト・アプリでWebカメラとして使用できないリスクがあるため注意

    [Terminal]
    python3 examples/ColorCamera/rgb_uvc.py
    画像
    画像


    参考資料

    別添1.Python関係

    別添2.YOLO関係

    Official YOLOv7 (state-of-the-art real-time detector) is more accurate and faster than:
    - YOLOv5 by 120% FPS
    - YOLOX by 180% FPS
    - Dual-Swin-T by 1200% FPS
    - ConvNext by 550% FPS
    - SWIN-L CM-RCNN by 500% FPS
    - PPYOLOE-X by 150% FPShttps://t.co/t5EOx3IdQahttps://t.co/utnk0nqu83 pic.twitter.com/jqLzRtfMNN

    — Alexey Bochkovskiy (@alexeyab84) July 7, 2022

    別添3.Webカメラ関係

    あとがき

     もう一度カメラモジュールV3でPiCamera2を使わずに動画接続できるか検証したい。
     Depthaiに関しては後でゆっくり追加していきます。

     
     

    KIYO

     
     
    普段は製造業で企画/開発/設計しております。記事はプログラミング・機械学習、IoT関係の記事をメインで作成し、なるべく1つの記事で知りたいことを網羅していきます。内容は学術的より実装・アウトプット(ほしくなるもの)を重視して作成しています。 面白そうな仕事があればやりたいです!

    あなたへのおすすめ