better integration with opencv, housekeeping

This commit is contained in:
l1npengtul
2022-12-18 17:52:59 +09:00
parent 36773c3ddb
commit d038d5a43c
4 changed files with 66 additions and 83 deletions
+12 -12
View File
@@ -27,7 +27,7 @@ input-v4l = ["nokhwa-bindings-linux"]
input-native = ["input-avfoundation", "input-v4l", "input-msmf"]
# Re-enable it once soundness has been proven + mozjpeg is updated to 0.9.x
# input-uvc = ["uvc", "uvc/vendor", "usb_enumeration", "lazy_static"]
input-opencv = ["opencv", "opencv/rgb", "rgb"]
input-opencv = ["opencv", "opencv/rgb", "rgb", "nokhwa-core/opencv-mat"]
input-jscam = ["web-sys", "js-sys", "wasm-bindgen-futures", "wasm-bindgen", "wasm-rs-async-executor"]
output-wgpu = ["wgpu", "nokhwa-core/wgpu-types"]
#output-wasm = ["input-jscam"]
@@ -43,7 +43,7 @@ thiserror = "1.0"
paste = "1.0"
[dependencies.nokhwa-core]
version = "0.1.0-rc.2"
version = "0.1.0"
path = "nokhwa-core"
[dependencies.serde]
@@ -63,7 +63,7 @@ version = "0.13"
optional = true
[dependencies.usb_enumeration]
version = "0.1.2"
version = "0.2"
optional = true
[dependencies.wgpu]
@@ -81,12 +81,12 @@ version = "0.8"
optional = true
[dependencies.nokhwa-bindings-windows]
version = "0.4.0-rc.1"
version = "0.4.0"
path = "nokhwa-bindings-windows"
optional = true
[dependencies.nokhwa-bindings-macos]
version = "0.2.0-rc.1"
version = "0.2.0"
path = "nokhwa-bindings-macos"
optional = true
@@ -96,7 +96,7 @@ path = "nokhwa-bindings-linux"
optional = true
[dependencies.regex]
version = "1.4.6"
version = "1.7"
optional = true
[dependencies.web-sys]
@@ -135,13 +135,13 @@ optional = true
version = "0.9"
optional = true
[dependencies.parking_lot]
version = "0.12"
optional = true
#[dependencies.parking_lot]
#version = "0.12"
#optional = true
[dependencies.lazy_static]
version = "1.4"
optional = true
#[dependencies.lazy_static]
#version = "1.4"
#optional = true
[profile.release]
lto = true
+7 -1
View File
@@ -14,12 +14,13 @@ default = []
serialize = ["serde"]
wgpu-types = ["wgpu"]
mjpeg = ["mozjpeg"]
opencv-mat = ["opencv"]
docs-features = []
[dependencies]
thiserror = "1.0"
bytes = "1.2"
bytes = "1.3"
[dependencies.image]
version = "0.24"
@@ -34,6 +35,11 @@ optional = true
version = "0.14"
optional = true
[dependencies.opencv]
version = "0.74"
default-features = false
optional = true
[dependencies.mozjpeg]
version = "0.9"
optional = true
+47
View File
@@ -102,4 +102,51 @@ impl Buffer {
buffer,
)
}
/// Decodes a image with allocation using the provided [`FormatDecoder`] into a [`Mat`](https://docs.rs/opencv/latest/opencv/core/struct.Mat.html).
///
/// Note that this does a clone when creating the buffer, to decouple the lifetime of the internal data to the temporary Buffer. If you want to avoid this, please see [`decode_as_opencv_mat`](Self::decode_as_opencv_mat).
/// # Errors
/// Will error when the decoding fails, or `OpenCV` failed to create/copy the [`Mat`](https://docs.rs/opencv/latest/opencv/core/struct.Mat.html).
/// # Safety
/// This function uses `unsafe` in order to create the [`Mat`](https://docs.rs/opencv/latest/opencv/core/struct.Mat.html). Please see [`Mat::new_rows_cols_with_data`](https://docs.rs/opencv/latest/opencv/core/struct.Mat.html#method.new_rows_cols_with_data) for more.
///
/// Most notably, the `data` **must** stay in scope for the duration of the [`Mat`](https://docs.rs/opencv/latest/opencv/core/struct.Mat.html) or bad, ***bad*** things happen.
#[cfg(feature = "opencv-mat")]
#[cfg_attr(feature = "docs-features", doc(cfg(feature = "opencv-mat")))]
pub fn decode_opencv_mat<F: FormatDecoder>(&self) -> Result<opencv::core::Mat, NokhwaError> {
use image::Pixel;
use opencv::core::{Mat, Mat_AUTO_STEP, CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4};
let array_type = match F::Output::CHANNEL_COUNT {
1 => CV_8UC1,
2 => CV_8UC2,
3 => CV_8UC3,
4 => CV_8UC4,
_ => {
return Err(NokhwaError::ProcessFrameError {
src: FrameFormat::RAWRGB,
destination: "OpenCV Mat".to_string(),
error: "Invalid Decoder FormatDecoder Channel Count".to_string(),
})
}
};
unsafe {
// TODO: Look into removing this unnecessary copy.
let mat1 = Mat::new_rows_cols_with_data(
self.resolution.height_y as i32,
self.resolution.width_x as i32,
array_type,
data.as_ref().as_mut_ptr().cast(),
Mat_AUTO_STEP,
)
.map_err(|why| NokhwaError::ProcessFrameError {
src: FrameFormat::RAWRGB,
destination: "OpenCV Mat".to_string(),
error: why.to_string(),
})?;
Ok(mat1)
}
}
}
-70
View File
@@ -46,13 +46,6 @@ mod query;
#[cfg_attr(feature = "docs-features", doc(cfg(feature = "output-threaded")))]
pub mod threaded;
// #[cfg(feature = "input-ipcam")]
// #[cfg_attr(feature = "docs-features", doc(cfg(feature = "input-ipcam")))]
// #[deprecated(
// since = "0.10.0",
// note = "please use `Camera` with `CameraIndex::String` and `input-opencv` enabled."
// )]
// pub use backends::capture::NetworkCamera;
pub use camera::Camera;
pub use init::*;
pub use nokhwa_core::buffer::Buffer;
@@ -64,69 +57,6 @@ pub use threaded::CallbackCamera;
pub mod utils {
pub use nokhwa_core::types::*;
#[cfg(feature = "input-opencv")]
#[doc(inline)]
#[cfg_attr(feature = "docs-features", doc(cfg(feature = "input-opencv")))]
pub use opencv_int::decode_opencv_mat;
#[cfg(feature = "input-opencv")]
mod opencv_int {
use image::Pixel;
use nokhwa_core::{
error::NokhwaError,
pixel_format::FormatDecoder,
types::{FrameFormat, Resolution},
};
use opencv::core::{Mat, Mat_AUTO_STEP, CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4};
/// Decodes a image with allocation using the provided [`FormatDecoder`] into a [`Mat`](https://docs.rs/opencv/latest/opencv/core/struct.Mat.html).
///
/// Note that this does a clone when creating the buffer, to decouple the lifetime of the internal data to the temporary Buffer. If you want to avoid this, please see [`decode_as_opencv_mat`](Self::decode_as_opencv_mat).
/// # Errors
/// Will error when the decoding fails, or `OpenCV` failed to create/copy the [`Mat`](https://docs.rs/opencv/latest/opencv/core/struct.Mat.html).
/// # Safety
/// This function uses `unsafe` in order to create the [`Mat`](https://docs.rs/opencv/latest/opencv/core/struct.Mat.html). Please see [`Mat::new_rows_cols_with_data`](https://docs.rs/opencv/latest/opencv/core/struct.Mat.html#method.new_rows_cols_with_data) for more.
///
/// Most notably, the `data` **must** stay in scope for the duration of the [`Mat`](https://docs.rs/opencv/latest/opencv/core/struct.Mat.html) or bad, ***bad*** things happen.
#[cfg(feature = "input-opencv")]
#[cfg_attr(feature = "docs-features", doc(cfg(feature = "input-opencv")))]
pub fn decode_opencv_mat<F: FormatDecoder>(
resolution: Resolution,
data: &mut [u8],
) -> Result<Mat, NokhwaError> {
let array_type = match F::Output::CHANNEL_COUNT {
1 => CV_8UC1,
2 => CV_8UC2,
3 => CV_8UC3,
4 => CV_8UC4,
_ => {
return Err(NokhwaError::ProcessFrameError {
src: FrameFormat::RAWRGB,
destination: "OpenCV Mat".to_string(),
error: "Invalid Decoder FormatDecoder Channel Count".to_string(),
})
}
};
unsafe {
#[allow(clippy::cast_possible_wrap)]
let mat1 = Mat::new_rows_cols_with_data(
resolution.height_y as i32,
resolution.width_x as i32,
array_type,
data.as_mut().as_mut_ptr().cast(),
Mat_AUTO_STEP,
)
.map_err(|why| NokhwaError::ProcessFrameError {
src: FrameFormat::RAWRGB,
destination: "OpenCV Mat".to_string(),
error: why.to_string(),
})?;
Ok(mat1)
}
}
}
}
pub mod error {