ガンマ補正
Mix.install([
{:req, "~> 0.5"},
{:evision, "~> 0.2"},
{:kino, "~> 0.14"},
{:nx, "~> 0.9"},
{:kino_vega_lite, "~> 0.1"}
])
準備
import Nx.Defn
画像のダウンロード
img =
"https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png"
|> Req.get!()
|> Map.get(:body)
|> Evision.imdecode(Evision.Constant.cv_IMREAD_COLOR())
ガンマ補正
defmodule GammaCorrection do
defn generate_gamma_tensor(gamma) do
(Nx.iota({256, 1}) / 255) ** (1 / gamma) * 255
end
def correct(img, gamma) do
gamma_tensor = generate_gamma_tensor(gamma)
Evision.lut(img, gamma_tensor)
end
end
[
img,
GammaCorrection.correct(img, 5.0)
]
|> Kino.Layout.grid(columns: 2)
1..8
|> Enum.to_list()
|> Enum.map(fn gamma_seed -> GammaCorrection.correct(img, gamma_seed / 4) end)
|> Kino.Layout.grid(columns: 4)
演算内容の確認
gamma_tensor = GammaCorrection.generate_gamma_tensor(0.1)
data =
[0.1, 0.25, 0.5, 1.0, 2.0, 5.0, 10.0]
|> Enum.reduce(%{gamma: [], src: [], dst: []}, fn gamma, acc ->
%{
gamma: acc.gamma ++ List.duplicate(gamma, 256),
src: acc.src ++ Enum.to_list(0..255),
dst: acc.dst ++ (gamma |> GammaCorrection.generate_gamma_tensor() |> Nx.to_flat_list())
}
end)
VegaLite.new()
|> VegaLite.data_from_values(data, only: ["src", "dst", "gamma"])
|> VegaLite.mark(:line)
|> VegaLite.encode_field(:x, "src", type: :quantitative)
|> VegaLite.encode_field(:y, "dst", type: :quantitative)
|> VegaLite.encode_field(:color, "gamma", type: :nominal)