View Source Fast Neural Style Transfer

File.cd!(__DIR__)
# for windows JP
System.shell("chcp 65001")

Mix.install([
  {:onnx_interp, "~> 0.1.8"},
  {:cimg, "~> 0.1.14"},
  {:kino, "~> 0.7.0"}
])

0-original-work

0.Original work

Fast Neural Style Transfer

fast-neural-style in PyTorch

Thanks a lot!!!


implementation-with-onnxinterp-in-elixir

Implementation with OnnxInterp in Elixir

System.put_env("MODEL", "candy")
# select dnn model in {"mosaic", "candy", "rain", "udnie", "point"} at compile time.
{model_name, model_path, model_url} =
  System.get_env("MODEL", "candy")
  |> String.downcase()
  |> tap(&IO.puts("-- COMPLE the deme for \"#{&1}\"."))
  |> case do
    "mosaic" ->
      {"Mosaic", "./model/mosaic-9.onnx",
       "https://github.com/onnx/models/raw/main/vision/style_transfer/fast_neural_style/model/mosaic-9.onnx"}

    "candy" ->
      {"Candy", "./model/candy-9.onnx",
       "https://github.com/onnx/models/raw/main/vision/style_transfer/fast_neural_style/model/candy-9.onnx"}

    "rain" ->
      {"RainPrincess", "./model/rain-princess-9.onnx",
       "https://github.com/onnx/models/raw/main/vision/style_transfer/fast_neural_style/model/rain-princess-9.onnx"}

    "udnie" ->
      {"Udnie", "./model/udnie-9.onnx",
       "https://github.com/onnx/models/raw/main/vision/style_transfer/fast_neural_style/model/udnie-9.onnx"}

    "point" ->
      {"Pointilism", "./model/pointilism-9.onnx",
       "https://github.com/onnx/models/raw/main/vision/style_transfer/fast_neural_style/model/pointilism-9.onnx"}

    unknown ->
      raise(
        "** COMILE ERROR: unknon dnn model: '#{unknown}'. it must be one of {vit, vgg16, resnet18} **"
      )
  end

defmodule Candy do
  @name model_name
  @model model_path
  @url model_url

  alias OnnxInterp, as: NNInterp
  use NNInterp, model: @model, url: @url

  def apply(img) do
    input0 =
      img
      |> CImg.resize({224, 224})
      |> CImg.to_binary([{:dtype, "<f4"}, {:range, {0.0, 255.0}}, :nchw])

    output0 =
      session()
      |> NNInterp.set_input_tensor(0, input0)
      |> NNInterp.invoke()
      |> NNInterp.get_output_tensor(0)

    CImg.from_binary(output0, 224, 224, 1, 3, [{:dtype, "<f4"}, {:range, {0.0, 255.0}}, :nchw])
  end

  def info() do
    %{name: @name, path: @model, url: @url}
  end
end

Launch Candy.

# OnnxInterp.stop(Candy)
Candy.start_link([])

3-let-s-try-it

3.Let's try it

Load a photo and apply Candy to it.

filename = "flog.jpg"

CImg.load(filename)
# display the image.
|> tap(fn img -> Kino.render(CImg.resize(img, {224, 224}) |> CImg.display_kino(:jpeg)) end)

# inference.
|> Candy.apply()
|> CImg.display_kino(:jpeg)

4-til

4.TIL ;-)

&#9633;