109 lines
3.3 KiB
Rust
109 lines
3.3 KiB
Rust
use crate::{prelude_::*, NdAsImage, NdAsImageMut};
|
|
|
|
/// Resize ndarray using OpenCV resize functions
|
|
pub trait NdCvResize<T, D>: seal::SealedInternal {
|
|
/// The input array must be a continuous 2D or 3D ndarray
|
|
fn resize(
|
|
&self,
|
|
height: u16,
|
|
width: u16,
|
|
interpolation: Interpolation,
|
|
) -> Result<ndarray::ArrayBase<ndarray::OwnedRepr<T>, D>, NdCvError>;
|
|
}
|
|
|
|
#[repr(i32)]
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub enum Interpolation {
|
|
Linear = opencv::imgproc::INTER_LINEAR,
|
|
LinearExact = opencv::imgproc::INTER_LINEAR_EXACT,
|
|
Max = opencv::imgproc::INTER_MAX,
|
|
Area = opencv::imgproc::INTER_AREA,
|
|
Cubic = opencv::imgproc::INTER_CUBIC,
|
|
Nearest = opencv::imgproc::INTER_NEAREST,
|
|
NearestExact = opencv::imgproc::INTER_NEAREST_EXACT,
|
|
Lanczos4 = opencv::imgproc::INTER_LANCZOS4,
|
|
}
|
|
|
|
mod seal {
|
|
pub trait SealedInternal {}
|
|
impl<T: bytemuck::Pod, S: ndarray::Data<Elem = T>> SealedInternal
|
|
for ndarray::ArrayBase<S, ndarray::Ix3>
|
|
{
|
|
}
|
|
impl<T: bytemuck::Pod, S: ndarray::Data<Elem = T>> SealedInternal
|
|
for ndarray::ArrayBase<S, ndarray::Ix2>
|
|
{
|
|
}
|
|
}
|
|
|
|
impl<T: bytemuck::Pod + num::Zero, S: ndarray::Data<Elem = T>> NdCvResize<T, ndarray::Ix2>
|
|
for ndarray::ArrayBase<S, ndarray::Ix2>
|
|
{
|
|
fn resize(
|
|
&self,
|
|
height: u16,
|
|
width: u16,
|
|
interpolation: Interpolation,
|
|
) -> Result<ndarray::Array2<T>, NdCvError> {
|
|
let mat = self.as_image_mat()?;
|
|
let mut dest = ndarray::Array2::zeros((height.into(), width.into()));
|
|
let mut dest_mat = dest.as_image_mat_mut()?;
|
|
opencv::imgproc::resize(
|
|
mat.as_ref(),
|
|
dest_mat.as_mut(),
|
|
opencv::core::Size {
|
|
height: height.into(),
|
|
width: width.into(),
|
|
},
|
|
0.,
|
|
0.,
|
|
interpolation as i32,
|
|
)
|
|
.change_context(NdCvError)?;
|
|
Ok(dest)
|
|
}
|
|
}
|
|
|
|
impl<T: bytemuck::Pod + num::Zero, S: ndarray::Data<Elem = T>> NdCvResize<T, ndarray::Ix3>
|
|
for ndarray::ArrayBase<S, ndarray::Ix3>
|
|
{
|
|
fn resize(
|
|
&self,
|
|
height: u16,
|
|
width: u16,
|
|
interpolation: Interpolation,
|
|
) -> Result<ndarray::ArrayBase<ndarray::OwnedRepr<T>, ndarray::Ix3>, NdCvError> {
|
|
let mat = self.as_image_mat()?;
|
|
let mut dest =
|
|
ndarray::Array3::zeros((height.into(), width.into(), self.len_of(ndarray::Axis(2))));
|
|
let mut dest_mat = dest.as_image_mat_mut()?;
|
|
opencv::imgproc::resize(
|
|
mat.as_ref(),
|
|
dest_mat.as_mut(),
|
|
opencv::core::Size {
|
|
height: height.into(),
|
|
width: width.into(),
|
|
},
|
|
0.,
|
|
0.,
|
|
interpolation as i32,
|
|
)
|
|
.change_context(NdCvError)?;
|
|
Ok(dest)
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_resize_simple() {
|
|
let foo = ndarray::Array2::<u8>::ones((10, 10));
|
|
let foo_resized = foo.resize(15, 20, Interpolation::Linear).unwrap();
|
|
assert_eq!(foo_resized, ndarray::Array2::<u8>::ones((15, 20)));
|
|
}
|
|
|
|
#[test]
|
|
fn test_resize_3d() {
|
|
let foo = ndarray::Array3::<u8>::ones((10, 10, 3));
|
|
let foo_resized = foo.resize(15, 20, Interpolation::Linear).unwrap();
|
|
assert_eq!(foo_resized, ndarray::Array3::<u8>::ones((15, 20, 3)));
|
|
}
|