DEV Community

Cover image for Elixir OpenCV で hello world
Masatoshi Nishiguchi
Masatoshi Nishiguchi

Posted on

Elixir OpenCV で hello world

何事でも基本が大切だと思います。プログラミングではよく "hello, world\n" を印字したりします。OpenCV でもそれ相当のことをやってみたいと思います。

セットアップ

Mix.install([ {:nx, "~> 0.5.0"}, # OpenCV をつかうため {:evision, "0.1.31"}, # 画像をテンソルに変換するため {:stb_image, "~> 0.6.0"}, # 画像を Web からダウンロードするため {:req, "~> 0.3.0"}, # Livebook 上で画像を表示するため # {:kino, "~> 0.9.0"} ]) 
Enter fullscreen mode Exit fullscreen mode

Elixir で OpenCV

cocoa-xu/evision を使うと OpenCV のほとんどの関数にElixirからアクセスできます。

cocoa-xu/evisionパッチバージョンでも破壊的な変更があるようのでバージョンをロックしておいた方が無難そうです。

https://qiita.com/RyoWakabayashi/items/2846133bc7014319d172

cocoa-xu/evision の作者は好んで Cv エイリアスを使用しているのでそれに則ります。

https://github.com/cocoa-xu/evision/tree/main/examples

alias Evision, as: Cv 
Enter fullscreen mode Exit fullscreen mode

HelloWorld モジュールをつくる

画像を Web からダウンロードし、Evision.Mat に変換します。

https://qiita.com/mnishiguchi/items/1006b5cea9287a91a2d3

グラフィカルユーザーインターフェース(GUI)で画像を表示するときには Evision.HighGui モジュールが便利です。

  • Evision.HighGui.imshow/2
    • 画像ウインドウを表示
  • Evision.HighGui.waitKey/1
    • 画像ウインドウを自動で閉じるまでの時間をミリ秒で指定
    • 0 の場合はなんらかのキーが押下されるまで開いたまま
  • Evision.HighGui.destroyAllWindows/0
    • 全ての画像ウインドウを閉じる

https://hexdocs.pm/evision/Evision.HighGui.html

以下のモジュールはターミナルでもLivebookでもイゴきます。

defmodule HelloWorld do alias Evision, as: Cv @wait_time_ms 30_000 def download_image(url) do Req.get!(url) |> then(& &1.body) |> StbImage.read_binary!() |> StbImage.to_nx() |> Cv.Mat.from_nx_2d() |> Cv.cvtColor(Cv.Constant.cv_COLOR_BGR2RGB()) end def show_image_gui(img_list) when is_list(img_list) do for {label, img_mat} <- img_list do Cv.HighGui.imshow(label, img_mat) end Cv.HighGui.waitKey(@wait_time_ms) Cv.HighGui.destroyAllWindows() end def show_image_gui(label, img_mat) do show_image_gui([{label, img_mat}]) end end 
Enter fullscreen mode Exit fullscreen mode

最初は原典に忠実に実施しようと思います。

hello world 1

ウィキペディアの画像をダウンロードして、それをGUIに表示します。

hello_img_mat1 = HelloWorld.download_image( "https://upload.wikimedia.org/wikipedia/commons/2/21/Hello_World_Brian_Kernighan_1978.jpg" ) HelloWorld.show_image_gui("hello OpenCV", hello_img_mat1) 
Enter fullscreen mode Exit fullscreen mode

画像ウインドウがフォーカスされている状態でなんらかのキーを押すと閉じることができます。

CleanShot 2023-05-03 at 21.50.15.gif

hello world 2

せっかく OpenCV を使っているので色チャネル(BGR)を分離する技を使ってみよう思います。それぞれの色の強さを視覚的に確認できます。

hello_img_mat2 = HelloWorld.download_image( "https://upload.wikimedia.org/wikipedia/commons/8/8c/PSP-Homebrew.jpeg" ) HelloWorld.show_image_gui([ {"Red", hello_img_mat2[[.., .., 2]]}, {"Green", hello_img_mat2[[.., .., 1]]}, {"Blue", hello_img_mat2[[.., .., 0]]}, {"BGR", hello_img_mat2} ]) 
Enter fullscreen mode Exit fullscreen mode

CleanShot 2023-05-03 at 22.10.36.gif

Top comments (0)