I am implementing a backend in Rust to run ONNX inferences on images using the opencv crate. Everything's working great but I have some doubts about a function I have written to crop an image at a specified location:

// assume coordinates are always validimg.col_range(&opencv::core::Range::new(xmin, xmax).unwrap()).unwrap().row_range(&opencv::core::Range::new(ymin, ymax).unwrap()).unwrap();

Is this the only way to accomplish a simple Mat crop? Hope I am not missing a better and more efficient solution.

1

Best Answer


There's nothing inefficient with what you've written. OpenCV Mats use data-sharing by default so there's no worry that you're needlessly copying large portions of original image. There's many ways to "slice and dice" the data and what you've chosen is a sensible way to crop an image. In fact, its the primary way you would do this in other languages (from Cropping an Image using OpenCV):

  • Python: cropped_image = img[80:280, 150:330]
  • C++: Mat cropped_image = img(Range(80,280), Range(150,330));

What I would recommend, which may be more clear and direct in Rust, is to use Mat::roi (a.k.a. the "region of interest" constructor):

let cropped_image = Mat::roi(&img, opencv::core::Rect {x: xmin,y: ymin,width: xmax - xmin,height: ymax - ymin,}).unwrap();

See also:

  • How to crop a CvMat in OpenCV?
  • How to crop an image in OpenCV using Python