use std::{fs, path::Path};
use opencv::{
core::{Mat, MatTraitConst, Vector},
imgcodecs,
};
use super::error::{McvError, Result};
#[cfg(feature = "template-matching")]
pub fn read_image_gray(path: impl AsRef<Path>) -> Result<Mat> {
let bytes = fs::read(path.as_ref())?;
let data = Vector::<u8>::from_slice(&bytes);
let image = imgcodecs::imdecode(&data, imgcodecs::IMREAD_GRAYSCALE)?;
if image.empty() {
return Err(McvError::InvalidImage(format!(
"failed to decode {}",
path.as_ref().display()
)));
}
Ok(image)
}
#[cfg(feature = "multi-color")]
pub fn read_image_bgr(path: impl AsRef<Path>) -> Result<Mat> {
let bytes = fs::read(path.as_ref())?;
let data = Vector::<u8>::from_slice(&bytes);
let image = imgcodecs::imdecode(&data, imgcodecs::IMREAD_COLOR)?;
if image.empty() {
return Err(McvError::InvalidImage(format!(
"failed to decode {}",
path.as_ref().display()
)));
}
validate_bgr_image(&image)?;
Ok(image)
}
#[cfg(feature = "multi-color")]
pub(crate) fn validate_bgr_image(image: &Mat) -> Result<()> {
if image.empty() {
return Err(McvError::InvalidImage("image is empty".to_string()));
}
if image.channels() != 3 {
return Err(McvError::InvalidImage(format!(
"image must be 3-channel BGR, got {} channel(s)",
image.channels()
)));
}
if !image.is_continuous() {
return Err(McvError::InvalidImage(
"image must be stored in a continuous buffer".to_string(),
));
}
Ok(())
}