Implement basic gapi module support
MODIFY
Cargo.toml
Cargo.toml
@@ -27,6 +27,10 @@ members = ["binding-generator"]
[[example]]
name = "discrete_fourier_transform"
+# requires Graph-API module
+#[[example]]
+#name = "gapi_api_example"
+
[[example]]
name = "opencl"
@@ -104,7 +108,7 @@ default = [
"flann",
"freetype",
"fuzzy",
-# "gapi",
+ "gapi",
"hdf",
"hfs",
"highgui",

MODIFY
binding-generator/src/generator.rs
binding-generator/src/generator.rs
@@ -205,21 +205,28 @@ impl<'tu, V: GeneratorVisitor> EntityWalkerVisitor<'tu> for OpenCvWalker<'tu, '_
EntityKind::MacroDefinition => self.process_const(entity),
EntityKind::MacroExpansion => {
if let Some(name) = entity.get_name() {
- if name == "CV_EXPORTS" || name == "CV_EXPORTS_W" || name == "CV_WRAP" || name == "GAPI_EXPORTS" {
+ const BOXED: [&str; 6] = [
+ "CV_EXPORTS",
+ "CV_EXPORTS_W",
+ "CV_WRAP",
+ "GAPI_EXPORTS",
+ "GAPI_EXPORTS_W",
+ "GAPI_WRAP",
+ ];
+ const SIMPLE: [&str; 3] = ["CV_EXPORTS_W_SIMPLE", "CV_EXPORTS_W_MAP", "GAPI_EXPORTS_W_SIMPLE"];
+ const RENAME: [&str; 2] = ["CV_EXPORTS_AS", "CV_WRAP_AS"];
+ if BOXED.contains(&name.as_str()) {
self.gen_env.make_export_config(entity);
- } else if name == "CV_EXPORTS_W_SIMPLE" || name == "CV_EXPORTS_W_MAP" {
+ } else if SIMPLE.contains(&name.as_str()) {
self.gen_env.make_export_config(entity).simple = true;
- } else if name == "CV_EXPORTS_AS" || name == "CV_WRAP_AS" {
- let definition = get_definition_text(entity);
- let definition = if let Some(d) = definition.strip_prefix("CV_EXPORTS_AS(").and_then(|d| d.strip_suffix(')')) {
- d.trim()
- } else if let Some(d) = definition.strip_prefix("CV_WRAP_AS(").and_then(|d| d.strip_suffix(')')) {
- d.trim()
- } else {
- unreachable!("Incorrect CV_EXPORTS_AS(..) or CV_WRAP_AS(..) usage")
- };
+ } else if let Some(rename_macro) = RENAME.iter().find(|&r| r == &name) {
+ if let Some(new_name) = get_definition_text(entity)
+ .strip_prefix(&format!("{}(", rename_macro))
+ .and_then(|d| d.strip_suffix(')'))
+ {
self.gen_env.make_export_config(entity);
- self.gen_env.make_rename_config(entity).rename = definition.to_string();
+ self.gen_env.make_rename_config(entity).rename = new_name.trim().to_string();
+ }
} else if name == "CV_NORETURN" {
self.gen_env.make_export_config(entity).no_return = true;
} else if name == "CV_NOEXCEPT" {

MODIFY
binding-generator/src/type_ref.rs
binding-generator/src/type_ref.rs
@@ -222,10 +222,15 @@ impl<'tu, 'ge> TypeRef<'tu, 'ge> {
self.gen_env,
));
}
+ // uint64_t in gapi module ends here for some reason
+ if let Some(&(rust, cpp)) = settings::PRIMITIVE_TYPEDEFS.get(generic_type.as_str()) {
+ Kind::Primitive(rust, cpp)
+ } else {
generic_type.replace_in_place("const ", "");
Kind::Generic(generic_type)
}
}
+ }
TypeKind::Typedef => {
let decl = self.type_ref.get_declaration().expect("Can't get typedef declaration");

MODIFY
binding-generator/src/writer/rust_native/mod.rs
binding-generator/src/writer/rust_native/mod.rs
@@ -168,7 +168,11 @@ impl GeneratorVisitor for RustNativeBindingWriter<'_> {
let prio = typ.element_order();
let safe_id = typ.element_safe_id();
- let path = self.types_dir.join(format!("{:03}-{}.type.rs", prio, safe_id));
+ let suffix = ".type.rs";
+ let mut file_name = format!("{:03}-{}", prio, safe_id);
+ ensure_filename_length(&mut file_name, suffix.len());
+ file_name.push_str(suffix);
+ let path = self.types_dir.join(file_name);
let file = OpenOptions::new().create_new(true).write(true).open(&path);
match file {
Ok(mut file) => {
@@ -187,7 +191,12 @@ impl GeneratorVisitor for RustNativeBindingWriter<'_> {
}
}
- let path = self.types_dir.join(format!("{:03}-{}.type.cpp", prio, safe_id));
+ let suffix = ".type.cpp";
+ let mut filename = format!("{:03}-{}", prio, safe_id);
+ ensure_filename_length(&mut filename, suffix.len());
+ filename.push_str(suffix);
+
+ let path = self.types_dir.join(filename);
let file = OpenOptions::new().create_new(true).write(true).open(&path);
match file {
Ok(mut file) => {
@@ -291,3 +300,13 @@ impl Drop for RustNativeBindingWriter<'_> {
.expect("Can't write rust exports file");
}
}
+
+fn ensure_filename_length(file_name: &mut String, reserve: usize) {
+ const MAX_FILENAME_LEN: usize = 255;
+
+ let max_length = MAX_FILENAME_LEN - reserve;
+
+ if file_name.len() > max_length {
+ *file_name = file_name[..max_length].to_string();
+ }
+}

MODIFY
build.rs
build.rs
@@ -152,9 +152,6 @@ fn get_version_from_headers(header_dir: &Path) -> Option<Version> {
}
fn make_modules(opencv_dir: &Path) -> Result<()> {
- let ignore_modules =
- IntoIterator::into_iter(["core_detect", "cudalegacy", "cudev", "gapi", "opencv", "opencv_modules"]).collect::<HashSet<_>>();
-
let enable_modules = IntoIterator::into_iter(["core".to_string()])
.chain(env::vars_os().filter_map(|(k, _)| {
k.to_str()
@@ -165,9 +162,9 @@ fn make_modules(opencv_dir: &Path) -> Result<()> {
let mut modules = files_with_extension(opencv_dir, "hpp")?
.filter_map(|entry| {
- let module = entry.file_stem().and_then(OsStr::to_str).expect("Can't calculate file stem");
- Some(module)
- .filter(|&m| !ignore_modules.contains(m))
+ entry
+ .file_stem()
+ .and_then(OsStr::to_str)
.filter(|&m| enable_modules.contains(m))
.map(str::to_string)
})

ADD
examples/gapi_api_example.rs
+//! Port of https://github.com/opencv/opencv/blob/master/modules/gapi/samples/api_example.cpp
+
+use std::env;
+
+use opencv::core::{Point, Scalar, Size, Vector, BORDER_DEFAULT};
+use opencv::gapi::GMat;
+use opencv::imgproc::INTER_LINEAR;
+use opencv::prelude::*;
+use opencv::videoio::{VideoCapture, CAP_ANY};
+use opencv::{gapi, highgui, Result};
+
+fn main() -> Result<()> {
+ let mut cap = VideoCapture::default()?;
+ let args = env::args().collect::<Vec<_>>();
+ if args.len() > 1 {
+ cap.open_file(&args[0], CAP_ANY)?;
+ } else {
+ cap.open(0, CAP_ANY)?;
+ }
+ assert!(cap.is_opened()?);
+ let input = GMat::default()?;
+ let vga = gapi::resize(&input, Size::default(), 0.5, 0.5, INTER_LINEAR)?;
+ let gray = gapi::bgr2_gray(&vga)?;
+ let blurred = gapi::blur(&gray, Size::new(5, 5), Point::new(-1, -1), BORDER_DEFAULT, Scalar::all(0.))?;
+ let edges = gapi::canny(&blurred, 32., 128., 3, false)?;
+ let (b, g, r) = gapi::split3(&vga)?.into_tuple();
+ let out = gapi::merge3(&b, &gapi::or_gmat_gmat(&g, &edges)?, &r)?;
+ let mut ac = gapi::GComputation::new(input, out)?;
+ let mut output_frame = Mat::default();
+ loop {
+ let mut input_frame = Mat::default();
+ assert!(cap.read(&mut input_frame)?);
+ ac.apply_2(input_frame, &mut output_frame, Vector::new())?;
+ highgui::imshow("output", &mut output_frame)?;
+ if highgui::wait_key(30)? >= 0 {
+ break;
+ }
+ }
+ Ok(())
+}

MODIFY
src/opencv/hub/videoio.rs
src/opencv/hub/videoio.rs
@@ -1212,7 +1212,7 @@ pub trait VideoCaptureTrait: crate::videoio::VideoCaptureTraitConst {
///
/// The method first calls VideoCapture::release to close the already opened file or camera.
#[inline]
- fn open(&mut self, filename: &str, api_preference: i32, params: &core::Vector<i32>) -> Result<bool> {
+ fn open_file_with_params(&mut self, filename: &str, api_preference: i32, params: &core::Vector<i32>) -> Result<bool> {
extern_container_arg!(filename);
return_send!(via ocvrs_return);
unsafe { sys::cv_VideoCapture_open_const_StringR_int_const_vector_int_R(self.as_raw_mut_VideoCapture(), filename.opencv_as_extern(), api_preference, params.as_raw_VectorOfi32(), ocvrs_return.as_mut_ptr()) };
@@ -1234,7 +1234,7 @@ pub trait VideoCaptureTrait: crate::videoio::VideoCaptureTraitConst {
/// ## C++ default parameters
/// * api_preference: CAP_ANY
#[inline]
- fn open_1(&mut self, index: i32, api_preference: i32) -> Result<bool> {
+ fn open(&mut self, index: i32, api_preference: i32) -> Result<bool> {
return_send!(via ocvrs_return);
unsafe { sys::cv_VideoCapture_open_int_int(self.as_raw_mut_VideoCapture(), index, api_preference, ocvrs_return.as_mut_ptr()) };
return_receive!(unsafe ocvrs_return => ret);
@@ -1254,7 +1254,7 @@ pub trait VideoCaptureTrait: crate::videoio::VideoCaptureTraitConst {
///
/// The method first calls VideoCapture::release to close the already opened file or camera.
#[inline]
- fn open_2(&mut self, index: i32, api_preference: i32, params: &core::Vector<i32>) -> Result<bool> {
+ fn open_with_params(&mut self, index: i32, api_preference: i32, params: &core::Vector<i32>) -> Result<bool> {
return_send!(via ocvrs_return);
unsafe { sys::cv_VideoCapture_open_int_int_const_vector_int_R(self.as_raw_mut_VideoCapture(), index, api_preference, params.as_raw_VectorOfi32(), ocvrs_return.as_mut_ptr()) };
return_receive!(unsafe ocvrs_return => ret);

Implement basic gapi module support