Evision Example - QRCode Encoding and Decoding
Mix.install([
{:evision, "~> 0.2"},
{:kino, "~> 0.7"},
{:req, "~> 0.5"}
], system_env: [
# optional, defaults to `true`
# set `EVISION_PREFER_PRECOMPILED` to `false`
# if you prefer `:evision` to be compiled from source
# note that to compile from source, you may need at least 1GB RAM
{"EVISION_PREFER_PRECOMPILED", true},
# optional, defaults to `true`
# set `EVISION_ENABLE_CONTRIB` to `false`
# if you don't need modules from `opencv_contrib`
{"EVISION_ENABLE_CONTRIB", true},
# optional, defaults to `false`
# set `EVISION_ENABLE_CUDA` to `true`
# if you wish to use CUDA related functions
# note that `EVISION_ENABLE_CONTRIB` also has to be `true`
# because cuda related modules come from the `opencv_contrib` repo
{"EVISION_ENABLE_CUDA", false},
# required when
# - `EVISION_ENABLE_CUDA` is `true`
# - and `EVISION_PREFER_PRECOMPILED` is `true`
#
# set `EVISION_CUDA_VERSION` to the version that matches
# your local CUDA runtime version
#
# current available versions are
# - 118
# - 121
{"EVISION_CUDA_VERSION", "118"},
# require for Windows users when
# - `EVISION_ENABLE_CUDA` is `true`
# set `EVISION_CUDA_RUNTIME_DIR` to the directory that contains
# CUDA runtime libraries
{"EVISION_CUDA_RUNTIME_DIR", "C:/PATH/TO/CUDA/RUNTIME"}
])
:ok
Encode A String to QRCode
# let's encode this example string
string_to_encode = "This is a string!"
# the result image will be in minimal possible size
# which is what it should be to avoid unnecessary memory allocations
# because it would be easier to let the user to resize the result image
# (most of the time we need to resize it to fit our needs anyway, this saves one call to resize)
%Evision.Mat{} =
minimal_qrcode = Evision.QRCodeEncoder.encode(Evision.QRCodeEncoder.create(), string_to_encode)
# for this example, we can resize it to 300x300
qrcode = Evision.resize(minimal_qrcode, {300, 300}, interpolation: Evision.Constant.cv_INTER_AREA())
%Evision.Mat{
channels: 1,
dims: 2,
type: {:u, 8},
raw_type: 0,
shape: {300, 300},
ref: #Reference<0.2207498009.3335389204.191169>
}
Read the String Back From the Encoded QRCode
{decoded_string, points, straight_qrcode} =
Evision.QRCodeDetector.detectAndDecode(Evision.QRCodeDetector.qrCodeDetector(), qrcode)
decoded_string
"This is a string!"
The Second Value In the Returned Tuple
# `points` is the keypoints for the QRCode
# the shape would be {1, 4, 2}, in which:
# - 1: number of QRCode
# - 4: always 4, 4 keypoints: top_left, bottom_left, bottom_right, top_right
# - 2: always 2, (x, y)
points = Evision.Mat.to_nx(points, Nx.BinaryBackend)
#Nx.Tensor<
f32[1][4][2]
[
[
[24.0, 24.0],
[275.0000305175781, 24.0],
[275.0000305175781, 275.0000305175781],
[24.0, 275.0000305175781]
]
]
>
# here we take the first QRCode's keypoints
keypoints = Nx.as_type(points[0], :s32)
{top_left, bottom_right} = {
List.to_tuple(Nx.to_flat_list(keypoints[0])),
List.to_tuple(Nx.to_flat_list(keypoints[2]))
}
{{24, 24}, {275, 275}}
{{row_start, col_start}, {row_end, col_end}} = {top_left, bottom_right}
qrcode[[col_start..col_end, row_start..row_end]]
%Evision.Mat{
channels: 1,
dims: 2,
type: {:u, 8},
raw_type: 0,
shape: {252, 252},
ref: #Reference<0.2207498009.3335389204.191179>
}
The Third Value In the Returned Tuple
# the third value is `straight_qrcode`, which is the minimal possible image
# for the QRCode
Evision.resize(straight_qrcode, {300, 300}, interpolation: Evision.Constant.cv_INTER_AREA())
%Evision.Mat{
channels: 1,
dims: 2,
type: {:u, 8},
raw_type: 0,
shape: {300, 300},
ref: #Reference<0.2207498009.3335389204.191182>
}