はじめに
少し離れている間に、 Livebook 0.11 がリリースされました!
というわけで私の Elixir 学習用リポジトリーも諸々更新しました
その更新作業の中で、 Kino に破壊的更新があったのでメモとして残しておきます
Kino 0.11
Kino は Livebook の UI/UX を提供してくれるモジュールです
Livebook 0.11 に伴い、 Kino も 0.11 にアップグレードされています
CHANGELOG はこちら
CHANGELOG の先頭に書かれている通り、画像入力の Kino.Input.image を使う場合、入力された画像を取得する際のコードを修正する必要があります
修正内容
Livebook 上に画像入力を作成する場合、以下のように記述します
image_input = Kino.Input.image("IMAGE")
このコードを実行すると、以下のような UI が表示されます
画像を選択すると以下のような表示になります
この画像入力から画像データを取り出す場合、以下のようにファイル入力を読み込みます
image = Kino.Input.read(image_input)
Kino 0.10 以前では Kino.Input.read の戻り値に直接画像のバイナリデータが入っていました
`%{data: <<0 0 0 ...>>, width: 100, height: 100}
そのため、バイナリデータを取得する場合 image.data だけで取得できていました
Kino 0.11 以降ではファイルへの参照が入るようになりました
%{file_ref: "5i7t...", width: 100, height: 100}
そのため、ファイルへの参照から Kino.Input.file_path でファイルのパスを取得し、 File.read! でバイナリを読み込む必要があります
image.file_ref
|> Kino.Input.file_path()
|> File.read!()
Evision で画像を読み込む場合(Nx経由)
Kino 0.10 以前では以下のようなコードで読み込んでいました
image = Kino.Input.read(image_input)
image_cv =
image
|> Map.get(:data)
|> Nx.from_binary(:u8)
|> Nx.reshape({image.height, image.width, 3})
|> Evision.Mat.from_nx_2d()
|> Evision.cvtColor(Evision.Constant.cv_COLOR_RGB2BGR())
Kino 0.11 では以下のコードに変更しなければいけません
image = Kino.Input.read(image_input)
image_cv =
image
|> Map.get(:file_ref)
|> Kino.Input.file_path()
|> File.read!()
|> Nx.from_binary(:u8)
|> Nx.reshape({image.height, image.width, 3})
|> Evision.Mat.from_nx_2d()
|> Evision.cvtColor(Evision.Constant.cv_COLOR_RGB2BGR())
差分で示すと以下のようになります
image = Kino.Input.read(image_input)
image_cv =
image
- |> Map.get(:data)
+ |> Map.get(:file_ref)
+ |> Kino.Input.file_path()
+ |> File.read!()
|> Nx.from_binary(:u8)
|> Nx.reshape({image.height, image.width, 3})
|> Evision.Mat.from_nx_2d()
|> Evision.cvtColor(Evision.Constant.cv_COLOR_RGB2BGR())
Elixir Image で画像を読み込む場合
Kino 0.10 以前の場合は以下のようなコードです
image =
image_input
|> Kino.Input.read()
|> Image.from_kino!()
Kino 0.11 以降では以下のように変更してください
file = Kino.Input.read(image_input)
image =
file
|> Map.merge(%{data: file.file_ref |> Kino.Input.file_path() |> File.read!()})
|> Image.from_kino!()
まとめ
一旦ファイルのパス取得、読み込みを挟む必要があるため、以前よりコードは長くなります
おそらく他のファイル入力との統一したものだと思われますが、少し不便ですね

