cv_convert/lib.rs
1//! Data conversion among computer vision libraries.
2//!
3//! # Usage
4//!
5//! **No crates are enabled by default.** You must specify which computer vision
6//! libraries you want to use as features when adding cv-convert to your project.
7//!
8//! ```toml
9//! [dependencies.cv-convert]
10//! version = 'x.y.z'
11//! default-features = false
12//! features = [
13//! 'image',
14//! 'opencv',
15//! 'tch',
16//! 'nalgebra',
17//! 'ndarray',
18//! 'imageproc',
19//! ]
20//! ```
21//!
22//! ## Available Features
23//!
24//! Library features:
25//! - `image` - Enable [image](https://crates.io/crates/image) crate support
26//! - `imageproc` - Enable [imageproc](https://crates.io/crates/imageproc) crate support
27//! - `nalgebra` - Enable [nalgebra](https://crates.io/crates/nalgebra) crate support
28//! - `ndarray` - Enable [ndarray](https://crates.io/crates/ndarray) crate support
29//! - `opencv` - Enable [opencv](https://crates.io/crates/opencv) crate support
30//! - `tch` - Enable [tch](https://crates.io/crates/tch) crate support
31//!
32//! Documentation feature:
33//! - `docs-only` - Used for documentation generation only
34//!
35//! # Traits
36//!
37//! The trait [ToCv] provides `.to_cv()` method for infallible conversions, and
38//! [TryToCv] provides `.try_to_cv()` method for fallible conversions.
39//! Just like std's [Into] and [TryInto] traits.
40//!
41//! ```rust
42//! # use cv_convert::{nalgebra, opencv};
43//! use cv_convert::{ToCv, TryToCv};
44//! use nalgebra as na;
45//! use opencv as cv;
46//!
47//! // ToCv - infallible conversion
48//! let cv_point = cv::core::Point2d::new(1.0, 3.0);
49//! let na_point: na::Point2<f64> = cv_point.to_cv();
50//!
51//! // ToCv - the other direction
52//! let na_point = na::Point2::<f64>::new(1.0, 3.0);
53//! let cv_point: cv::core::Point2d = na_point.to_cv();
54//!
55//! // TryToCv - fallible conversion
56//! let na_mat = na::DMatrix::from_vec(2, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
57//! let cv_mat = na_mat.try_to_cv().unwrap();
58//!
59//! // TryToCv - the other direction
60//! let cv_mat = cv::core::Mat::from_slice_2d(&[&[1.0, 2.0, 3.0], &[4.0, 5.0, 6.0]]).unwrap();
61//! let na_mat: na::DMatrix<f64> = cv_mat.try_to_cv().unwrap();
62//! ```
63//!
64//!
65//! # Supported conversions
66//!
67//! The notations are used for simplicity.
68//!
69//! - `S -> T` suggests the conversion is defined by non-fallible [ToCv].
70//! - `S ->? T` suggests the conversion is defined by fallible [TryToCv].
71//! - `(&)T` means the type can be either owned or borrowed.
72//! - `&'a S -> &'a T` suggests that the target type borrows the source type.
73//!
74//! ## opencv -> opencv
75//!
76//! - [(&)Mat](opencv::core::Mat) ->? [Point_<T>](opencv::core::Point_)
77//! - [(&)Mat](opencv::core::Mat) ->? [Point3_<T>](opencv::core::Point3_)
78//! - [(&)Point_<T>](opencv::core::Point_) ->? [Mat](opencv::core::Mat)
79//! - [(&)Point3_<T>](opencv::core::Point3_) ->? [Mat](opencv::core::Mat)
80//!
81//! ## std -> tch
82//!
83//! - owned/borrowed multi-dimensional [array](array) ->? [Tensor](tch::Tensor)
84//! - [(&)\[T; N\]](array) ->? [Tensor](tch::Tensor)
85//! - [(&)\[\[T; N2\]; N1\]](array) ->? [Tensor](tch::Tensor)
86//! - ... and so on up to 6 dimensions
87//!
88//! ## tch -> std
89//!
90//! - &'a [Tensor](tch::Tensor) -> &'a multi-dimensional [array](array)
91//! - &'a [Tensor](tch::Tensor) -> &'a [\[T; N\]](array)
92//! - &'a [Tensor](tch::Tensor) -> &'a [\[\[T; N2\]; N1\]](array)
93//! - ... and so on up to 6 dimensions
94//! - [(&)Tensor](tch::Tensor) -> owned multi-dimensional [array](array)
95//! - [(&)Tensor](tch::Tensor) ->? [\[T; N\]](array)
96//! - [(&)Tensor](tch::Tensor) ->? [\[\[T; N2\]; N1\]](array)
97//! - ... and so on up to 6 dimensions
98//!
99//! ## tch -> ndarray
100//!
101//! - &[Tensor](tch::Tensor) ->? [Array](ndarray::Array)
102//!
103//! ## ndarray -> tch
104//!
105//! - &[Array](ndarray::Array) ->? [Tensor](tch::Tensor)
106//!
107//! ## ndarray -> opencv
108//!
109//! - &[Array](ndarray::Array) ->? [Mat](opencv::core::Mat)
110//!
111//! ## image -> tch
112//!
113//! - [(&)ImageBuffer](image::ImageBuffer) ->? [TchTensorAsImage]
114//! - [(&)DynamicImage](image::DynamicImage) ->? [TchTensorAsImage]
115//!
116//! ## image -> opencv
117//!
118//! - [(&)ImageBuffer](image::ImageBuffer) ->? [Mat](opencv::core::Mat)
119//! - [(&)DynamicImage](image::DynamicImage) ->? [Mat](opencv::core::Mat)
120//!
121//! ## opencv -> image 0.23
122//!
123//! - [Mat](opencv::core::Mat) ->? [(&)ImageBuffer](image::ImageBuffer)
124//!
125//! ## opencv -> image 0.24
126//!
127//! - [Mat](opencv::core::Mat) ->? [(&)ImageBuffer](image::ImageBuffer)
128//! - [Mat](opencv::core::Mat) ->? [(&)DynamicImage](image::DynamicImage)
129//!
130//! ## opencv -> imageproc
131//! - [(&)Point_<T>](opencv::core::Point_) -> [Point<T>](imageproc::point::Point)
132//!
133//! ## imageproc -> opencv
134//! - [(&)Point<T>](imageproc::point::Point) -> [Point_<T>](opencv::core::Point_)
135//!
136//! ## opencv -> nalgebra
137//!
138//! - [(&)Mat](opencv::core::Mat) ->? [OMatrix](nalgebra::OMatrix)
139//! - [(&)Point_<T>](opencv::core::Point_) -> [Point2<T>](nalgebra::Point2)
140//! - [(&)Point3_<T>](opencv::core::Point3_) -> [Point2<T>](nalgebra::Point3)
141//! - [(&)OpenCvPose<(&)Point3d>](OpenCvPose) ->? [Isometry3<f64>](nalgebra::Isometry3)
142//! - [(&)OpenCvPose<(&)Mat>](OpenCvPose) ->? [Isometry3<f64>](nalgebra::Isometry3)
143//!
144//! ## nalgebra -> opencv
145//!
146//! - [(&)OMatrix](nalgebra::OMatrix) ->? [Mat](opencv::core::Mat)
147//! - [(&)Point2<T>](nalgebra::Point2) -> [Point_<T>](opencv::core::Point_)
148//! - [(&)Point3<T>](nalgebra::Point3) -> [Point3_<T>](opencv::core::Point3_)
149//! - [(&)Translation<N, D>](nalgebra::Translation) ->? [Mat](opencv::core::Mat)
150//! - [(&)Isometry3<T>](nalgebra::Isometry3) ->? [OpenCvPose<Point3_<T>>](OpenCvPose)
151//! - [(&)Isometry3<f64>](nalgebra::Isometry3) ->? [OpenCvPose<Mat>](OpenCvPose)
152//! - [(&)Isometry3<f32>](nalgebra::Isometry3) ->? [OpenCvPose<Mat>](OpenCvPose)
153//!
154//! ## opencv -> tch
155//!
156//! - [(&)Mat](opencv::core::Mat) ->? [Tensor](tch::Tensor)
157//!
158//! The input [Mat](opencv::core::Mat) is regarded as an n-dimensional array with a m-channel elements.
159//! The output [Tensor](tch::Tensor) have n+1 dimensions, which last additional m-sized dimension is the channel.
160//!
161//! - [(&)Mat](opencv::core::Mat) ->? [TchTensorAsImage]
162//!
163//! The input [Mat](opencv::core::Mat) must be a 2D image.
164//! The output [Tensor](tch::Tensor) within [TchTensorAsImage] has 3 dimensions, which last additional dimension is the channel.
165//!
166//! - [&Mat](opencv::core::Mat) ->? [OpenCvMatAsTchTensor]
167//!
168//! ## tch -> opencv
169//!
170//! - [(&)Tensor](tch::Tensor) ->? [Mat](opencv::core::Mat)
171//!
172//! The n-dimensinoal input [Tensor](tch::Tensor) is converted to a [Mat](opencv::core::Mat)
173//! with n dimensions and a channel of size 1.
174//!
175//! - [(&)TchTensorAsImage](TchTensorAsImage) ->? [Mat](opencv::core::Mat)
176//!
177//! The output [Mat](opencv::core::Mat) is a 2D image, which height, width and channel size
178//! are judged from the input [TchTensorAsImage](TchTensorAsImage) shape.
179//!
180//!
181//! ## opencv -> ndarray
182//!
183//! - [&Mat](opencv::core::Mat) ->? [ArrayView](ndarray::ArrayView)
184//! - [(&)Mat](opencv::core::Mat) ->? [Array](ndarray::Array)
185//!
186//!
187//! # Notes for OpenCV
188//!
189//! For opencv older than 0.66, some systems requires `clang-runtime`
190//! feature to build successfully. Otherwise you will get `libclang
191//! shared library is not loaded on this thread!` panic. Add `opencv`
192//! dependency along side `cv-convert` in your project Cargo.toml to
193//! enable this feature.
194//!
195//! ```toml
196//! cv-convert = { version = "0.22.0", default-features = false, features = ["opencv_0-65"] }
197//! opencv = { version = "0.65", features = ["clang-runtime"] }
198//! ```
199//!
200//! Most opencv modules, such as `videoio` and `aruco`, are disabled
201//! by default to avoid bloating. Add opencv dependency to your
202//! project Cargo.toml to enable default modules in your project.
203
204mod traits;
205pub use traits::*;
206
207pub mod prelude {
208 pub use crate::traits::{ToCv, TryToCv};
209}
210
211use cfg_if::cfg_if;
212
213// modules
214
215cfg_if! {
216 if #[cfg(feature = "image")] {
217 pub use image;
218 }
219}
220
221cfg_if! {
222 if #[cfg(feature = "imageproc")] {
223 pub use imageproc;
224 }
225}
226
227cfg_if! {
228 if #[cfg(feature = "nalgebra")] {
229 pub use nalgebra;
230 }
231}
232
233cfg_if! {
234 if #[cfg(feature = "ndarray")] {
235 pub use ndarray;
236 }
237}
238
239cfg_if! {
240 if #[cfg(feature = "opencv")] {
241 pub use opencv;
242
243 mod with_opencv;
244 #[allow(unused)]
245 pub use with_opencv::*;
246 }
247}
248
249cfg_if! {
250 if #[cfg(feature = "tch")] {
251 pub use tch;
252
253 mod with_tch;
254 #[allow(unused)]
255 pub use with_tch::*;
256 }
257}
258
259cfg_if! {
260 if #[cfg(all(feature = "tch", feature = "image"))] {
261 mod with_tch_image;
262 #[allow(unused)]
263 pub use with_tch_image::*;
264 }
265}
266
267cfg_if! {
268 if #[cfg(all(feature = "tch", feature = "ndarray"))] {
269 mod with_tch_ndarray;
270 #[allow(unused)]
271 pub use with_tch_ndarray::*;
272 }
273}
274
275cfg_if! {
276 if #[cfg(all(feature = "image", feature = "opencv"))] {
277 mod with_opencv_image;
278 #[allow(unused)]
279 pub use with_opencv_image::*;
280 }
281}
282
283cfg_if! {
284 if #[cfg(all(feature = "imageproc", feature = "opencv"))] {
285 mod with_opencv_imageproc;
286 #[allow(unused)]
287 pub use with_opencv_imageproc::*;
288 }
289}
290
291cfg_if! {
292 if #[cfg(all(feature = "nalgebra", feature = "opencv"))] {
293 mod with_opencv_nalgebra;
294 #[allow(unused)]
295 pub use with_opencv_nalgebra::*;
296 }
297}
298
299cfg_if! {
300 if #[cfg(all(feature = "tch", feature = "opencv"))] {
301 mod with_opencv_tch;
302 #[allow(unused)]
303 pub use with_opencv_tch::*;
304 }
305}
306
307cfg_if! {
308 if #[cfg(all(feature = "ndarray", feature = "opencv"))] {
309 mod with_opencv_ndarray;
310 #[allow(unused)]
311 pub use with_opencv_ndarray::*;
312 }
313}