evision事始め - ElixirでOpenCVを使って画像処理をする
はじめに
本記事では、evisionを試してみます。evisionとは、OpenCVのElixirバインディングです。Nxとの連携もできNervesにも対応している、夢が広がるライブラリです。
実験環境
- iMac (24-inch, M1, 2021)
- macOSX Monterey (12.2)
- Elixir: 1.13.2-otp-24
- Livebook: Version 1.67
事前準備
evisionの依存ライブラリ(OpenCVなど)をインストールし、Livebook上で依存モジュールをインストールします。
依存ライブラリのインストール
依存ライブラリをインストールします。
$ brew install opencv cmake
依存モジュールのインストール
Mix.install/2
をLivebook上で実行します。
Mix.install([
{:evision, "~> 0.1.0-dev", github: "cocoa-xu/evision", branch: "main"},
{:kino, "~> 0.5.2"}
])
evisionを動かしてみる
iMacの内蔵カメラで映像をキャプチャして、そこからフレームを読み取って画像として書き出してみます。
まず、evisionモジュールをalias
し(しなくてもいいけど、提供元のドキュメントに合わせます)、ファイルを読み書きしたいディレクトリ(このLivebookのファイルの実体があるディレクトリ)に移動し、内蔵カメラのデバイスを取得します。
alias Evision, as: OpenCV
File.cd!(__DIR__)
{:ok, cap} = OpenCV.VideoCapture.videoCapture(0)
Evision
からalias
されたOpenCV
経由のAPIを使っていきます。
{:ok, mat} = OpenCV.VideoCapture.read(cap)
:ok = OpenCV.imwrite("capture.png", mat)
上記のコードを実行すると、capture.png
という名前で映像からキャプチャした画像が書き出されます。
カメラから画像を取得して表示する
今度は、カメラから取得した映像をLivebook上に直接表示してみる。
{:ok, mat} = OpenCV.VideoCapture.read(cap)
{:ok, encoded} = OpenCV.imencode(".png", mat)
encoded
|> IO.iodata_to_binary()
|> Kino.Image.new(:png)
ご覧の通り、素敵な画像を取得できました。
カメラ映像を表示する
Kinoの提供するKino.animate/3
を使えば、映像から画像を読み出してアニメーションすることで、Livebook上に動画を表示することもできます。
Kino.animate(10, 0, fn i ->
{:ok, mat} = OpenCV.VideoCapture.read(cap)
{:ok, encoded} = OpenCV.imencode(".png", mat)
kino =
encoded
|> IO.iodata_to_binary()
|> Kino.Image.new(:png)
# とりあえず1000回で止める
if i < 1000 do
{:cont, kino, i + 1}
else
:halt
end
end)
※ リアルタイムに表示している動画なので、記事上では表示できません。カメラの前で、上記写真の画像の素敵な男性が動いているのを想像してください。
発展的な話題
上記のアニメーションによる映像表示は、@ShozFさんが以下のツイートでRaspberry PiとNerves Livebookを使って実現していたのを見て、自分でも試してみたものです(こちらは、OpenCVではなくPicamを使っています)。
@ShozFさんはさらに、機械学習モデルを動かして手の検出をするデモも実現しています。こんなことが簡単にできるようになるなんて、夢が広がりますね。
また、画像処理や機械学習については、evisionのexamplesディレクトリに例がありますので、詳しくはそちらをどうぞ。
Discussion