ヒストグラム平坦化
Mix.install([
{:req, "~> 0.5"},
{:evision, "~> 0.2"},
{:kino, "~> 0.14"},
{:nx, "~> 0.9"},
{:kino_vega_lite, "~> 0.1"}
])
画像のダウンロード
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())
グレースケールの場合
gray_img = Evision.cvtColor(img, Evision.Constant.cv_COLOR_BGR2GRAY())
ピクセル値のヒストグラムをグラフ化
ヒストグラムが平均化される = 暗いところも明るいところも増える = コントラストが強調される
pixel =
gray_img
|> Evision.Mat.to_nx()
|> Nx.to_flat_list()
VegaLite.new()
|> VegaLite.data_from_values(x: pixel)
|> VegaLite.mark(:bar)
|> VegaLite.encode_field(:x, "x", type: :quantitative)
|> VegaLite.encode_field(:y, "x", type: :quantitative, aggregate: :count)
equalized_img = Evision.equalizeHist(gray_img)
Kino.Layout.grid([gray_img, equalized_img], columns: 2)
equalized_pixel =
equalized_img
|> Evision.Mat.to_nx()
|> Nx.to_flat_list()
VegaLite.new()
|> VegaLite.data_from_values(x: equalized_pixel)
|> VegaLite.mark(:bar)
|> VegaLite.encode_field(:x, "x", type: :quantitative)
|> VegaLite.encode_field(:y, "x", type: :quantitative, aggregate: :count)
カラーの場合
BGR から HSV に変換し、明度情報だけをヒストグラム平坦化する
hsv_img = Evision.cvtColor(img, Evision.Constant.cv_COLOR_BGR2HSV())
value =
hsv_img
|> Evision.Mat.to_nx(Nx.BinaryBackend)
|> Nx.slice_along_axis(2, 1, axis: 2)
Kino.Image.new(value)
equalized_value =
value
|> Nx.squeeze()
|> Evision.equalizeHist()
|> Evision.Mat.to_nx(Nx.BinaryBackend)
|> Nx.new_axis(2)
Kino.Image.new(equalized_value)
元画像の色相、彩度とヒストグラム平坦化した明度を結合して BGR に戻す
hs =
hsv_img
|> Evision.Mat.to_nx(Nx.BinaryBackend)
|> Nx.slice_along_axis(0, 2, axis: 2)
equalized_img =
[hs, equalized_value]
|> Nx.concatenate(axis: 2)
|> Evision.Mat.from_nx_2d()
|> Evision.cvtColor(Evision.Constant.cv_COLOR_HSV2BGR())
Kino.Layout.grid([img, equalized_img], columns: 2)