今回は、UnitV2で遊んでみた。
## しかし、その道のりが長かったので、まとめます#UnitV2 で、camera_streamを改造して、リアルタイムエッジ抽出をやってみました🎵#M5Stack pic.twitter.com/4CpUxiL3rF
— ウワン (@MuAuan) November 2, 2021
以下の解説で、「VSCodeを使うので、VSCode devcontainerの機能を使います」
ということで、VSCode+Docker containerを利用というのは、Windows10だと、WSL2+VSCodeということで、それなりにハードルは、高い。
さらに、ししかわさんのサイトの通りやっても、OpenCVのversionが現在4.4.0から4.5.4に上がってウワンには動かせなかった。
ということで、WSL2インストールからのお話をまとめることとする。
【参考】
M5Stack UnitV2Frameworkをビルドする:ししかわの二足ロボ研修 Part.6
SSH Connect
UnitV2
WSL2の環境構築手順
WSL2環境構築
新しいマシンのインストールは、以下のリンクのとおりで実施できる。
Power shellを管理者権限で開いて以下を実行して、helpが出たら以下の古い場合の手順へ
wsl --install
古い場合の手順
以前のバージョンの WSL の手動インストール手順
WSL2 + Docker Desktop + VSCode(Remote - Containers) でGoの開発環境構築
管理者として PowerShell を開き、以下を実行します。
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
[設定] メニューで、最新の Windows バージョンに更新
Windows Updateを実施し、最新版に更新する
仮想マシンの機能を有効にする
管理者として PowerShell を開き、以下を実行します。
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
Linux カーネル更新プログラム パッケージをダウンロードする
x64 マシン用 WSL2 Linux カーネル更新プログラム パッケージ
をダウンロードしてダブルクリックしてインストールする。
WSL 2 を既定のバージョンとして設定する
PowerShell を管理者権限で開いて次のコマンドを実行する
これを実行すると、次にインストールするubuntu 20.04のベースWSLがWSL2になる。
wsl --set-default-version 2
Microsoft Store を開き、ubuntu20.04を選択
StoreでWSLやubuntuで検索すると候補が出てくる。ちなみにubuntuもインストールできるが、バージョンが時々になるとのこと。
やり直したいときのuninstallは「アプリと機能」からアンインストールして、やり直しします。
Windows Subsystem for LinuxからUbuntuをアンインストール
インストール状況の確認
PowerShellを管理者権限で開いて以下を実行すると2が確認できる
PS C:\WINDOWS\system32> wsl -l -v
NAME STATE VERSION
* Ubuntu-20.04 Running 2
また、ubuntuもWSLのコマンドラインから以下で確認できる。
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.3 LTS
Release: 20.04
Codename: focal
vscodeのインストール
Dockerインストール
以下をダウンロードしてインストールする。
Docker Desktop for Windows
Power Shellを管理者権限で開いて以下実行し、確認する。
PS C:\WINDOWS\system32> docker version
error during connect: In the default daemon configuration on Windows, the docker client must be run with elevated privileges to connect.: Get "http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/version": open //./pipe/docker_engine: The system cannot find the file specified.
Client:
Cloud integration: 1.0.17
Version: 20.10.8
API version: 1.41
Go version: go1.16.6
Git commit: 3967b7d
Built: Fri Jul 30 19:58:50 2021
OS/Arch: windows/amd64
Context: default
Experimental: true
WSL2でも同様に、ただしこちらはDockerをactivateしていないと注意がでたので、
$ docker version
The command 'docker' could not be found in this WSL 2 distro.
We recommend to activate the WSL integration in Docker Desktop settings.
For details about using Docker Desktop with WSL 2, visit:
https://docs.docker.com/go/wsl2/
Desctopに出ているポップからactivate(Docker start;下図参照)を実行した。
その後、以下のようにUbuntu上でもpermission deniedが出ているが上と同様な情報が得られる。
$ docker version
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/version": dial unix /var/run/docker.sock: connect: permission denied
Client: Docker Engine - Community
Cloud integration: 1.0.17
Version: 20.10.8
API version: 1.41
Go version: go1.16.6
Git commit: 3967b7d
Built: Fri Jul 30 19:54:22 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
そして、
$ sudo docker version
[sudo] password for ubuntu:
Client: Docker Engine - Community
Cloud integration: 1.0.17
Version: 20.10.8
API version: 1.41
Go version: go1.16.6
Git commit: 3967b7d
Built: Fri Jul 30 19:54:22 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.8
API version: 1.41 (minimum version 1.12)
Go version: go1.16.6
Git commit: 75249d8
Built: Fri Jul 30 19:52:31 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.9
GitCommit: e25210fe30a0a703442421b0f60afac609f950a3
runc:
Version: 1.0.1
GitCommit: v1.0.1-0-g4144b63
docker-init:
Version: 0.19.0
GitCommit: de40ad0
VScodeのインストール
Thanks for downloading VS Code for Windows!
から、ダウンロードしてインストール。
これで、以下のコマンドで立ち上げられます。
$ code .
VSCoceの拡張機能 Remote-Containersをインストール
Docker Official Images
venv利用して仮想環境構築+requirements.txtでインストール
WSL2で仮想環境構築
まず、WSL2上で以下の作業を実施。python_ex2という仮想環境を構築する。
$ python3 -m venv python_ex2
$ cd python_ex2
ubuntu@DESKTOP-4CJ3TFH:~/python_ex2$ source bin/activate
(python_ex2) ubuntu@DESKTOP-4CJ3TFH:~/python_ex2$ code .
最後のcode .
でVSCodeを立ち上げると、下の図の最下段のバーのようにこの仮想環境の属性が見える。
インストールは、requirements.txtで行えるものと追加でpytorch関係をpipでインストールした。
結果として、pip freeze
して出力したものをrequirements.txtに張り付けた。
ubuntu@DESKTOP-4CJ3TFH:~/python_ex2$ pip install -r requirements.txt
Collecting cycler==0.10.0
Using cached cycler-0.10.0-py2.py3-none-any.whl (6.5 kB)
Collecting kiwisolver==1.3.2
Using cached kiwisolver-1.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl (1.2 MB)
Collecting matplotlib==3.4.3
Using cached matplotlib-3.4.3-cp38-cp38-manylinux1_x86_64.whl (10.3 MB)
Collecting numpy==1.21.3
Using cached numpy-1.21.3-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (15.7 MB)
Collecting Pillow==8.4.0
Using cached Pillow-8.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.1 MB)
Collecting pyparsing==3.0.3
Using cached pyparsing-3.0.3-py3-none-any.whl (96 kB)
Collecting python-dateutil==2.8.2
Using cached python_dateutil-2.8.2-py2.py3-none-any.whl (247 kB)
Collecting six==1.16.0
Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Collecting typing-extensions==3.10.0.2
Using cached typing_extensions-3.10.0.2-py3-none-any.whl (26 kB)
Installing collected packages: six, cycler, kiwisolver, python-dateutil, numpy, pyparsing, Pillow, matplotlib, typing-extensions
Successfully installed Pillow-8.4.0 cycler-0.10.0 kiwisolver-1.3.2 matplotlib-3.4.3 numpy-1.21.3 pyparsing-3.0.3 python-dateutil-2.8.2 six-1.16.0 typing-extensions-3.10.0.2
ubuntu@DESKTOP-4CJ3TFH:~/python_ex2$ pip3 install torch torchvision torchaudioCollecting torch
Using cached torch-1.10.0-cp38-cp38-manylinux1_x86_64.whl (881.9 MB)
Collecting torchvision
Using cached torchvision-0.11.1-cp38-cp38-manylinux1_x86_64.whl (23.3 MB)
Collecting torchaudio
Downloading torchaudio-0.10.0-cp38-cp38-manylinux1_x86_64.whl (2.9 MB)
|████████████████████████████████| 2.9 MB 2.1 MB/s
Requirement already satisfied: typing-extensions in ./python_ex2/lib/python3.8/site-packages (from torch) (3.10.0.2)
Requirement already satisfied: pillow!=8.3.0,>=5.3.0 in ./python_ex2/lib/python3.8/site-packages (from torchvision) (8.4.0)
Requirement already satisfied: numpy in ./python_ex2/lib/python3.8/site-packages (from torchvision) (1.21.3)
Installing collected packages: torch, torchvision, torchaudio
Successfully installed torch-1.10.0 torchaudio-0.10.0 torchvision-0.11.1
これでpython環境が構築できました。
いよいよUnitV2の環境を構築します。
UnitV2を使う
ここからは、以下の参考の記事の通りにすすめます。
【参考】
【中級者向け】M5Stack UnitV2のOpenCVバージョンを上げる手順
gitする
WSL2上で、以下のようにgitする。
$ git clone https://github.com/mongonta0716/UnitV2Framework-docker.git
$ cd UnitV2Framework-docker
$ code .
VSCodeが開いたら、reopen in containerして、環境構築
一か所、opencv2の所在が参考とは異なっていたので、以下に変更
"/external/opencv/install/arm/include/opencv4/opencv2",
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/external/opencv/install/arm/include/opencv4/opencv2",
"${workspaceFolder}/include",
"${workspaceFolder}/include/ncnn"
],
"defines": [],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++14",
"intelliSenseMode": "linux-clang-x64"
}
],
"version": 4
}
以下で、cmakeすると、
cmake -B build/arm -DOPENCV_DIR=/external/opencv/build/arm/ -DCMAKE_TOOLCHAIN_FILE=./platforms/arm.toolchain.cmake -DTARGET=camera_stream .
cmake --build build/arm
以下のように、bin配下にcamera_streamが作られている。
ちなみに、camera_streamのコードは、以下の通り
# include <opencv2/core/utility.hpp>
# include <opencv2/tracking.hpp>
# include <opencv2/highgui.hpp>
# include <opencv2/imgproc/types_c.h>
# include <iostream>
# include <cstring>
# include "framework.h"
using namespace cv;
# define IMAGE_DIV 2
int main( int argc, char** argv )
{
startFramework("Camera Stream", 640, 480);
int low_quality_mode = false;
while(1)
{
Mat mat_src;
getMat(mat_src);
if(low_quality_mode == true)
{
resize(mat_src, mat_src, Size(), 1.0f / IMAGE_DIV, 1.0f / IMAGE_DIV, INTER_AREA);
}
std::string payload;
if(readPIPE(payload))
{
try
{
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload);
if((doc["config"] == "web_update_data") || (doc["config"] == getFunctionName()))
{
if(doc["operation"] == "enable")
{
low_quality_mode = true;
sendPIPEMessage("Low Quality Mode Enabled.");
}
else
{
low_quality_mode = false;
sendPIPEMessage("Low Quality Mode Disabled.");
}
}
}
catch(...)
{
fprintf(stderr, "[ERROR] Can not parse json.");
}
}
Mat gray_img;
cvtColor(mat_src, gray_img, CV_BGR2GRAY);
sendMat(gray_img);
}
return 0;
}
try~catchの部分を削除すると、以下のようにシンプルになる。
以下はこのコードですすめ、入れ替えができているかを見ることとする。
# include <opencv2/core/utility.hpp>
# include <opencv2/tracking.hpp>
# include <opencv2/highgui.hpp>
# include <opencv2/imgproc/types_c.h>
# include <iostream>
# include <cstring>
# include "framework.h"
using namespace cv;
# define IMAGE_DIV 2
int main( int argc, char** argv )
{
startFramework("Camera Stream", 640, 480);
int low_quality_mode = false;
while(1)
{
Mat mat_src;
getMat(mat_src);
//Mat gray_img;
//cvtColor(mat_src, gray_img, CV_BGR2GRAY);
//sendMat(gray_img);
sendMat(mat_src);
}
return 0;
}
まず、上と同じようにVSCodeのターミナルで、以下を実行してbuildする。
$ cmake -B build/arm -DOPENCV_DIR=/external/opencv/build/arm/ -DCMAKE_TOOLCHAIN_FILE=./platforms/arm.toolchain.cmake -DTARGET=camera_stream .
$ cmake --build build/arm
opencv4.5.4のlibを転送するために、VSCodeにインストールされた資材を参考の通り圧縮し、UnitV2に転送する。
cd /external/opencv/install/arm
tar -zcvf /workspaces/UnitV2Framework-docker/opencv.tar.gz bin include lib share
以下参考のとおり、UnitV2側でsudoを利用できるようにする
M5Stack UnitV2を弄るための備忘録
次にUnitV2に入って、
$ ssh m5stack@10.254.239.1
以下で書き込み可にする。
unitv2% sudo chmod 666 /dev/null
PC側に戻って、scpで先ほどの圧縮ファイルとcamera_streamを転送
unitv2% ctrl-D
$ cd ~/UnitV2Framework-docker
$ scp ./opencv.tar.gz m5stack@10.254.239.1:/home/m5stack
$ scp bin/camera_stream m5stack@10.254.239.1:/home/m5stack
そして、転送したファイルをunitv2上で解凍する。
unitv2% sudo cp opencv.tar.gz /
cd /
sudo zcat opencv.tar.gz | sudo tar -xvf -
次にcamera_streamの入れ替えをする。
実行ファイルは、/home/m5stack/payload/binに置かれてる。
※念のため元のファイルはバックアップを取りましょう。
unitv2% cd /home/m5stack
unitv2% sudo mv payload/bin/camera_stream camera_stream.bak
unitv2% sudo mv camera_stream payload/bin
これで、UnitV2を以下のように再起動すると、web(http://10.254.239.1/)に新しい実行ファイルが起動しているのがわかります。
※立ち上がりにタイムラグ(1min程度)かかります
unitv2% sudo reboot
以下の部分のコメントアウト部分が白黒画像、元のものがカラーであり、これを入れ替えてbuildし、一連の置き換えをすると変更されたことがわかります。
//Mat gray_img;
//cvtColor(mat_src, gray_img, CV_BGR2GRAY);
//sendMat(gray_img);
sendMat(mat_src);
ちょっと書き換えて
以下の参考から「カメラからの映像をリアルタイムにエッジ抽出」のコードを参考にcamera_streamを書き換えてみました。
【参考】
OpenCV 4.3 (C++) で Hello World と顔検出
# include "opencv2/imgproc.hpp"
# include <opencv2/core/utility.hpp>
# include <opencv2/tracking.hpp>
# include <opencv2/highgui.hpp>
# include <opencv2/imgproc/types_c.h>
# include <iostream>
# include <cstring>
# include "framework.h"
using namespace cv;
int main(int, char**) {
//VideoCapture cap(0);
//if(!cap.isOpened()) return -1;
startFramework("Camera Stream", 640, 480);
int low_quality_mode = false;
while(1)
{
Mat mat_src;
getMat(mat_src);
Mat edges;
//namedWindow("edges", WINDOW_AUTOSIZE);
//cap >> mat_src;
// 色をグレースケールに
cvtColor(mat_src, edges, COLOR_BGR2GRAY);
// ガウスフィルターで画像をぼかす
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
// キャニー法によるエッジ抽出
Canny(edges, edges, 0, 30, 3);
// ウィンドウを表示
//imshow("edges", edges);
//if(waitKey(30) >= 0) break;
sendMat(edges);
}
return 0;
}
#UnitV2 で、camera_streamを改造して、リアルタイムエッジ抽出をやってみました🎵#M5Stack pic.twitter.com/4CpUxiL3rF
— ウワン (@MuAuan) November 2, 2021