Evision による画像処理
Mix.install([
{:req, "~> 0.5"},
{:evision, "~> 0.2"},
{:kino, "~> 0.14"},
{:nx, "~> 0.9"}
])
画像生成
[
[
[255, 0, 0],
[255, 128, 0],
[255, 255, 0]
],
[
[0, 255, 0],
[0, 255, 128],
[0, 255, 255]
],
[
[0, 0, 255],
[128, 0, 255],
[255, 0, 255]
]
]
|> Nx.tensor(type: {:u, 8})
# Evision のマトリックスに変換
|> Evision.Mat.from_nx_2d()
# 見やすいように拡大
|> Evision.resize({300, 300}, interpolation: Evision.Constant.cv_INTER_AREA())
画像のダウンロード
img_binary =
"https://www.elixirconf.eu/assets/images/ryo-wakabayashi.jpg"
|> Req.get!()
|> Map.get(:body)
img = Evision.imdecode(img_binary, Evision.Constant.cv_IMREAD_COLOR())
画像の書込
img_path = "rwakabay.jpg"
Evision.imwrite(img_path, img)
画像の読込
img = Evision.imread(img_path)
size = Evision.Mat.shape(img)
Evision.Mat.to_nx(img)
リサイズ
Evision.resize(img, {256, 128})
グレースケール
Evision.imread(img_path, flags: Evision.Constant.cv_IMREAD_GRAYSCALE())
Evision.cvtColor(img, Evision.Constant.cv_COLOR_BGR2GRAY())
二値化
{threshold, mono_img} =
img_path
|> Evision.imread(flags: Evision.Constant.cv_IMREAD_GRAYSCALE())
|> Evision.threshold(127, 255, Evision.Constant.cv_THRESH_BINARY())
IO.inspect(threshold)
mono_img
並進
affine =
[
[1, 0, 100],
[0, 1, 50]
]
|> Nx.tensor(type: :f32)
Evision.warpAffine(img, affine, {512, 512})
回転
affine = Evision.getRotationMatrix2D({512 / 2, 512 / 2}, 70, 1)
Evision.warpAffine(img, affine, {512, 512})
ぼかし
Evision.blur(img, {9, 9})
Evision.medianBlur(img, 9)
Evision.gaussianBlur(img, {9, 9}, 5)
図形描画
img
# 直線
|> Evision.line(
# 始点{x, y}
{200, 400},
# 終点{x, y}
{300, 450},
# 色{R, G, B}
{0, 255, 255},
# 線の太さ
thickness: 5
)
# 矢印
|> Evision.arrowedLine(
# 始点{x, y}
{300, 200},
# 終点{x, y}
{400, 150},
# 色{R, G, B}
{255, 255, 0},
# 線の太さ
thickness: 3,
# 頭の大きさ
tipLength: 0.3
)
img
# 四角形
|> Evision.rectangle(
# 左上{x, y}
{150, 120},
# 右下{x, y}
{225, 320},
# 色{R, G, B}
{0, 0, 255},
# 線の太さ
thickness: 12,
# 線の引き方(角がギザギザになる)
lineType: Evision.Constant.cv_LINE_4()
)
|> Evision.rectangle(
# 左上{x, y}
{50, 120},
# 右下{x, y}
{125, 320},
# 色{R, G, B}
{0, 0, 255},
# 線の太さ
thickness: 12,
# 線の引き方(角が滑らかになる)
lineType: Evision.Constant.cv_LINE_AA()
)
|> Evision.rectangle(
# 左上{x, y}
{250, 60},
# 右下{x, y}
{325, 110},
# 色{R, G, B}
{0, 255, 0},
# 塗りつぶし
thickness: -1
)
img
# 円
|> Evision.circle(
# 中心{x, y}
{100, 100},
# 半径
50,
# 色{R, G, B}
{255, 0, 0},
# 塗りつぶし
thickness: -1
)
# 楕円
|> Evision.ellipse(
# 中心{x, y}
{300, 300},
# {長径, 短径}
{100, 200},
# 回転角度
30,
# 弧の開始角度
0,
# 弧の終了角度
360,
# 色{R, G, B}
{255, 255, 0},
# 線の太さ
thickness: 3
)
# 扇形
|> Evision.ellipse(
# 中心{x, y}
{400, 200},
# {長径, 短径}
{100, 100},
# 回転角度
0,
# 弧の開始角度
100,
# 弧の終了角度
200,
# 色{R, G, B}
{0, 255, 0},
# 塗りつぶし
thickness: -1
)
文字描画
img
|> Evision.putText(
# 文字列
"Ryo",
# 左下{x, y}
{250, 200},
# フォント種類
Evision.Constant.cv_FONT_HERSHEY_SIMPLEX(),
# フォントサイズ
2.5,
# 文字色
{0, 0, 255},
# 文字太さ
thickness: 5
)
Nx による画像の縦横変換
img
|> Evision.Mat.to_nx(Nx.BinaryBackend)
|> Nx.transpose(axes: [1, 0, 2])
|> Evision.Mat.from_nx_2d()
|> dbg
Nx による画像のグレースケール化
img
|> Evision.Mat.to_nx(Nx.BinaryBackend)
|> Nx.mean(axes: [2])
|> Nx.broadcast({600, 600, 3}, axes: [0, 1])
|> Evision.Mat.from_nx_2d()
|> dbg