-
Notifications
You must be signed in to change notification settings - Fork 22
Integration with Nx
Cocoa edited this page Feb 14, 2024
·
1 revision
iex> mat = Evision.imread("/path/to/image.png")
%Evision.Mat{
channels: 3,
dims: 2,
type: {:u, 8},
raw_type: 16,
shape: {512, 512, 3},
ref: #Reference<0.2992585850.4173463580.172624>
}
iex> t = Evision.Mat.to_nx(mat)
#Nx.Tensor<
u8[512][512][3]
Evision.Backend
[
[
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
[255, 255, ...],
...
],
...
]
>
and vice-versa:
iex> %Evision.Mat{} = mat = Evision.imread("/path/to/image.png")
iex> t = Evision.Mat.to_nx(mat)
# convert a tensor to a mat
iex> mat_from_tensor = Evision.Mat.from_nx(t)
%Evision.Mat{
channels: 1,
dims: 3,
type: {:u, 8},
raw_type: 0,
shape: {512, 512, 3},
ref: #Reference<0.1086574232.1510342676.18186>
}
# Note that `Evision.Mat.from_nx` gives a tensor
# however, some OpenCV functions expect the mat
# to be a "valid 2D image"
# therefore, in such cases `Evision.Mat.from_nx_2d`
# should be used instead
#
# Noticing the changes in `channels`, `dims` and `raw_type`
iex> mat_from_tensor = Evision.Mat.from_nx_2d(t)
%Evision.Mat{
channels: 3,
dims: 2,
type: {:u, 8},
raw_type: 16,
shape: {512, 512, 3},
ref: #Reference<0.1086574232.1510342676.18187>
}
# and it works for tensors with any shapes
iex> t = Nx.iota({2, 3, 2, 3, 2, 3}, type: :s32)
iex> mat = Evision.Mat.from_nx(t)
%Evision.Mat{
channels: 1,
dims: 6,
type: {:s, 32},
raw_type: 4,
shape: {2, 3, 2, 3, 2, 3},
ref: #Reference<0.1086574232.1510342676.18188>
}
As OpenCV does not support the following types (yet, as of OpenCV 4.9.0)
{:s, 64}
{:u, 32}
{:u, 64}
Although it's possible to store values with those types using custom types, the resulting Mat/tensor will be incompatible with most existing functions in OpenCV.
Moreover, it's somewhat inconvinient to explicitly specify the type each time using them. Therefore, Evision allows to set a map for those unsupported types.
config :evision, unsupported_type_map: %{
{:s, 64} => {:f, 64},
{:u, 64} => {:f, 64},
{:u, 32} => {:f, 32}
}
The key
of this unsupported_type_map
is the unsupported type, and the value is the replacement type for it.
See this reply for more details on this.