use super::core::{
af_array, dim_t, AfError, Array, BorderType, CannyThresholdType, ColorSpace, ConfidenceCCInput,
Connectivity, DeconvInput, DiffusionEq, EdgeComputable, FloatingPoint, FluxFn,
GrayRGBConvertible, HasAfEnum, ImageFilterType, ImageNativeType, InterpType, InverseDeconvAlgo,
IterativeDeconvAlgo, MomentType, MomentsComputable, RealFloating, RealNumber, YCCStd,
HANDLE_ERROR,
};
use libc::{c_char, c_double, c_float, c_int, c_uint};
use std::ffi::CString;
extern "C" {
fn af_cast(out: *mut af_array, arr: af_array, aftype: c_uint) -> c_int;
fn af_gradient(dx: *mut af_array, dy: *mut af_array, arr: af_array) -> c_int;
fn af_load_image(out: *mut af_array, filename: *const c_char, iscolor: bool) -> c_int;
fn af_save_image(filename: *const c_char, input: af_array) -> c_int;
fn af_load_image_native(out: *mut af_array, filename: *const c_char) -> c_int;
fn af_save_image_native(filename: *const c_char, input: af_array) -> c_int;
fn af_resize(
out: *mut af_array,
input: af_array,
odim0: dim_t,
odim1: dim_t,
method: c_uint,
) -> c_int;
fn af_transform(
out: *mut af_array,
input: af_array,
trans: af_array,
odim0: dim_t,
odim1: dim_t,
method: c_uint,
is_inverse: bool,
) -> c_int;
fn af_rotate(
out: *mut af_array,
input: af_array,
theta: c_float,
crop: bool,
method: c_uint,
) -> c_int;
fn af_translate(
out: *mut af_array,
input: af_array,
trans0: c_float,
trans1: c_float,
odim0: dim_t,
odim1: dim_t,
method: c_uint,
) -> c_int;
fn af_scale(
out: *mut af_array,
input: af_array,
scale0: c_float,
scale1: c_float,
odim0: dim_t,
odim1: dim_t,
method: c_uint,
) -> c_int;
fn af_skew(
out: *mut af_array,
input: af_array,
skew0: c_float,
skew1: c_float,
odim0: dim_t,
odim1: dim_t,
method: c_uint,
is_inverse: bool,
) -> c_int;
fn af_histogram(
out: *mut af_array,
input: af_array,
nbins: c_uint,
minval: c_double,
maxval: c_double,
) -> c_int;
fn af_dilate(out: *mut af_array, input: af_array, mask: af_array) -> c_int;
fn af_dilate3(out: *mut af_array, input: af_array, mask: af_array) -> c_int;
fn af_erode(out: *mut af_array, input: af_array, mask: af_array) -> c_int;
fn af_erode3(out: *mut af_array, input: af_array, mask: af_array) -> c_int;
fn af_regions(out: *mut af_array, input: af_array, conn: c_uint, aftype: c_uint) -> c_int;
fn af_sobel_operator(dx: *mut af_array, dy: *mut af_array, i: af_array, ksize: c_uint)
-> c_int;
fn af_rgb2gray(
out: *mut af_array,
input: af_array,
r: c_float,
g: c_float,
b: c_float,
) -> c_int;
fn af_gray2rgb(
out: *mut af_array,
input: af_array,
r: c_float,
g: c_float,
b: c_float,
) -> c_int;
fn af_hist_equal(out: *mut af_array, input: af_array, hist: af_array) -> c_int;
fn af_hsv2rgb(out: *mut af_array, input: af_array) -> c_int;
fn af_rgb2hsv(out: *mut af_array, input: af_array) -> c_int;
fn af_bilateral(
out: *mut af_array,
input: af_array,
sp_sig: c_float,
ch_sig: c_float,
iscolor: bool,
) -> c_int;
fn af_mean_shift(
out: *mut af_array,
input: af_array,
sp_sig: c_float,
ch_sig: c_float,
iter: c_uint,
iscolor: bool,
) -> c_int;
fn af_medfilt(
out: *mut af_array,
input: af_array,
wlen: dim_t,
wwid: dim_t,
etype: c_uint,
) -> c_int;
fn af_medfilt1(out: *mut af_array, input: af_array, wlen: dim_t, etype: c_uint) -> c_int;
fn af_minfilt(
out: *mut af_array,
input: af_array,
wlen: dim_t,
wwid: dim_t,
etype: c_uint,
) -> c_int;
fn af_maxfilt(
out: *mut af_array,
input: af_array,
wlen: dim_t,
wwid: dim_t,
etype: c_uint,
) -> c_int;
fn af_gaussian_kernel(
out: *mut af_array,
rows: c_int,
cols: c_int,
sigma_r: c_double,
sigma_c: c_double,
) -> c_int;
fn af_color_space(
out: *mut af_array,
input: af_array,
tospace: c_uint,
fromspace: c_uint,
) -> c_int;
fn af_unwrap(
out: *mut af_array,
input: af_array,
wx: dim_t,
wy: dim_t,
sx: dim_t,
sy: dim_t,
px: dim_t,
py: dim_t,
is_column: bool,
) -> c_int;
fn af_wrap(
out: *mut af_array,
input: af_array,
ox: dim_t,
oy: dim_t,
wx: dim_t,
wy: dim_t,
sx: dim_t,
sy: dim_t,
px: dim_t,
py: dim_t,
is_column: bool,
) -> c_int;
fn af_sat(out: *mut af_array, input: af_array) -> c_int;
fn af_ycbcr2rgb(out: *mut af_array, input: af_array, stnd: c_uint) -> c_int;
fn af_rgb2ycbcr(out: *mut af_array, input: af_array, stnd: c_uint) -> c_int;
fn af_is_image_io_available(out: *mut bool) -> c_int;
fn af_transform_coordinates(
out: *mut af_array,
tf: af_array,
d0: c_float,
d1: c_float,
) -> c_int;
fn af_moments(out: *mut af_array, input: af_array, moment: c_uint) -> c_int;
fn af_moments_all(out: *mut c_double, input: af_array, moment: c_uint) -> c_int;
fn af_canny(
out: *mut af_array,
input: af_array,
thres_type: c_int,
low: c_float,
high: c_float,
swindow: c_uint,
is_fast: bool,
) -> c_int;
fn af_anisotropic_diffusion(
out: *mut af_array,
input: af_array,
dt: c_float,
K: c_float,
iters: c_uint,
fftype: c_uint,
diff_kind: c_uint,
) -> c_int;
fn af_confidence_cc(
out: *mut af_array,
input: af_array,
seedx: af_array,
seedy: af_array,
radius: c_uint,
multiplier: c_uint,
iterations: c_int,
seg_val: c_double,
) -> c_int;
fn af_iterative_deconv(
out: *mut af_array,
input: af_array,
ker: af_array,
iterations: c_uint,
rfactor: c_float,
algo: c_uint,
) -> c_int;
fn af_inverse_deconv(
out: *mut af_array,
input: af_array,
ker: af_array,
gamma: c_float,
algo: c_uint,
) -> c_int;
}
pub fn gradient<T>(input: &Array<T>) -> (Array<T>, Array<T>)
where
T: HasAfEnum + FloatingPoint,
{
unsafe {
let mut dx: af_array = std::ptr::null_mut();
let mut dy: af_array = std::ptr::null_mut();
let err_val = af_gradient(
&mut dx as *mut af_array,
&mut dy as *mut af_array,
input.get(),
);
HANDLE_ERROR(AfError::from(err_val));
(dx.into(), dy.into())
}
}
#[allow(clippy::match_wild_err_arm)]
pub fn load_image<T>(filename: String, is_color: bool) -> Array<T>
where
T: HasAfEnum + RealNumber,
{
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
let trgt_type = T::get_af_dtype();
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err1 = af_load_image(&mut temp as *mut af_array, cstr_param.as_ptr(), is_color);
HANDLE_ERROR(AfError::from(err1));
let mut img: af_array = std::ptr::null_mut();
let err2 = af_cast(&mut img as *mut af_array, temp, trgt_type as c_uint);
HANDLE_ERROR(AfError::from(err2));
img.into()
}
}
#[allow(clippy::match_wild_err_arm)]
pub fn load_image_native<T>(filename: String) -> Array<T>
where
T: HasAfEnum + ImageNativeType,
{
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
let trgt_type = T::get_af_dtype();
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err1 = af_load_image_native(&mut temp as *mut af_array, cstr_param.as_ptr());
HANDLE_ERROR(AfError::from(err1));
let mut img: af_array = std::ptr::null_mut();
let err2 = af_cast(&mut img as *mut af_array, temp, trgt_type as c_uint);
HANDLE_ERROR(AfError::from(err2));
img.into()
}
}
#[allow(clippy::match_wild_err_arm)]
pub fn save_image<T>(filename: String, input: &Array<T>)
where
T: HasAfEnum + RealNumber,
{
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
unsafe {
let err_val = af_save_image(cstr_param.as_ptr(), input.get());
HANDLE_ERROR(AfError::from(err_val));
}
}
#[allow(clippy::match_wild_err_arm)]
pub fn save_image_native<T>(filename: String, input: &Array<T>)
where
T: HasAfEnum + ImageNativeType,
{
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
unsafe {
let err_val = af_save_image_native(cstr_param.as_ptr(), input.get());
HANDLE_ERROR(AfError::from(err_val));
}
}
pub fn resize<T: HasAfEnum>(
input: &Array<T>,
odim0: i64,
odim1: i64,
method: InterpType,
) -> Array<T> {
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_resize(
&mut temp as *mut af_array,
input.get(),
odim0 as dim_t,
odim1 as dim_t,
method as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn transform<T: HasAfEnum>(
input: &Array<T>,
trans: &Array<f32>,
odim0: i64,
odim1: i64,
method: InterpType,
is_inverse: bool,
) -> Array<T> {
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_transform(
&mut temp as *mut af_array,
input.get(),
trans.get(),
odim0 as dim_t,
odim1 as dim_t,
method as c_uint,
is_inverse,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn rotate<T: HasAfEnum>(
input: &Array<T>,
theta: f64,
crop: bool,
method: InterpType,
) -> Array<T> {
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_rotate(
&mut temp as *mut af_array,
input.get(),
theta as c_float,
crop,
method as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn translate<T: HasAfEnum>(
input: &Array<T>,
trans0: f32,
trans1: f32,
odim0: i64,
odim1: i64,
method: InterpType,
) -> Array<T> {
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_translate(
&mut temp as *mut af_array,
input.get(),
trans0,
trans1,
odim0 as dim_t,
odim1 as dim_t,
method as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn scale<T: HasAfEnum>(
input: &Array<T>,
scale0: f32,
scale1: f32,
odim0: i64,
odim1: i64,
method: InterpType,
) -> Array<T> {
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_scale(
&mut temp as *mut af_array,
input.get(),
scale0,
scale1,
odim0 as dim_t,
odim1 as dim_t,
method as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn skew<T: HasAfEnum>(
input: &Array<T>,
skew0: f32,
skew1: f32,
odim0: i64,
odim1: i64,
method: InterpType,
is_inverse: bool,
) -> Array<T> {
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_skew(
&mut temp as *mut af_array,
input.get(),
skew0,
skew1,
odim0 as dim_t,
odim1 as dim_t,
method as c_uint,
is_inverse,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn histogram<T>(input: &Array<T>, nbins: u32, minval: f64, maxval: f64) -> Array<u32>
where
T: HasAfEnum + RealNumber,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_histogram(
&mut temp as *mut af_array,
input.get(),
nbins,
minval,
maxval,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn dilate<T>(input: &Array<T>, mask: &Array<T>) -> Array<T>
where
T: HasAfEnum + ImageFilterType,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_dilate(&mut temp as *mut af_array, input.get(), mask.get());
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn erode<T>(input: &Array<T>, mask: &Array<T>) -> Array<T>
where
T: HasAfEnum + ImageFilterType,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_erode(&mut temp as *mut af_array, input.get(), mask.get());
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn dilate3<T>(input: &Array<T>, mask: &Array<T>) -> Array<T>
where
T: HasAfEnum + ImageFilterType,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_dilate3(&mut temp as *mut af_array, input.get(), mask.get());
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn erode3<T>(input: &Array<T>, mask: &Array<T>) -> Array<T>
where
T: HasAfEnum + ImageFilterType,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_erode3(&mut temp as *mut af_array, input.get(), mask.get());
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn bilateral<T>(
input: &Array<T>,
spatial_sigma: f32,
chromatic_sigma: f32,
iscolor: bool,
) -> Array<T::AbsOutType>
where
T: HasAfEnum + ImageFilterType,
T::AbsOutType: HasAfEnum,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_bilateral(
&mut temp as *mut af_array,
input.get(),
spatial_sigma,
chromatic_sigma,
iscolor,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn mean_shift<T>(
input: &Array<T>,
spatial_sigma: f32,
chromatic_sigma: f32,
iter: u32,
iscolor: bool,
) -> Array<T>
where
T: HasAfEnum + RealNumber,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_mean_shift(
&mut temp as *mut af_array,
input.get(),
spatial_sigma,
chromatic_sigma,
iter,
iscolor,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
macro_rules! filt_func_def {
($doc_str: expr, $fn_name: ident, $ffi_name: ident) => {
#[doc=$doc_str]
pub fn $fn_name<T>(input: &Array<T>, wlen: u64, wwid: u64, etype: BorderType) -> Array<T>
where
T: HasAfEnum + ImageFilterType,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = $ffi_name(
&mut temp as *mut af_array,
input.get(),
wlen as dim_t,
wwid as dim_t,
etype as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
};
}
filt_func_def!("Median filter", medfilt, af_medfilt);
filt_func_def!(
"Box filter with minimum as box operation",
minfilt,
af_minfilt
);
filt_func_def!(
"Box filter with maximum as box operation",
maxfilt,
af_maxfilt
);
pub fn gaussian_kernel(rows: i32, cols: i32, sigma_r: f64, sigma_c: f64) -> Array<f32> {
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_gaussian_kernel(&mut temp as *mut af_array, rows, cols, sigma_r, sigma_c);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn color_space<T>(input: &Array<T>, tospace: ColorSpace, fromspace: ColorSpace) -> Array<T>
where
T: HasAfEnum + RealNumber,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_color_space(
&mut temp as *mut af_array,
input.get(),
tospace as c_uint,
fromspace as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn regions<OutType>(input: &Array<bool>, conn: Connectivity) -> Array<OutType>
where
OutType: HasAfEnum + RealNumber,
{
let otype = OutType::get_af_dtype();
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_regions(
&mut temp as *mut af_array,
input.get(),
conn as c_uint,
otype as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn sobel<T>(input: &Array<T>, ker_size: u32) -> (Array<T::SobelOutType>, Array<T::SobelOutType>)
where
T: HasAfEnum + ImageFilterType,
T::SobelOutType: HasAfEnum,
{
unsafe {
let mut dx: af_array = std::ptr::null_mut();
let mut dy: af_array = std::ptr::null_mut();
let err_val = af_sobel_operator(
&mut dx as *mut af_array,
&mut dy as *mut af_array,
input.get(),
ker_size,
);
HANDLE_ERROR(AfError::from(err_val));
(dx.into(), dy.into())
}
}
pub fn hist_equal<T>(input: &Array<T>, hist: &Array<u32>) -> Array<T>
where
T: HasAfEnum + RealNumber,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_hist_equal(&mut temp as *mut af_array, input.get(), hist.get());
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
macro_rules! grayrgb_func_def {
($doc_str: expr, $fn_name: ident, $ffi_name: ident) => {
#[doc=$doc_str]
pub fn $fn_name<T>(input: &Array<T>, r: f32, g: f32, b: f32) -> Array<T>
where
T: HasAfEnum + GrayRGBConvertible,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = $ffi_name(&mut temp as *mut af_array, input.get(), r, g, b);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
};
}
grayrgb_func_def!("Color(RGB) to Grayscale conversion", rgb2gray, af_rgb2gray);
grayrgb_func_def!("Grayscale to Color(RGB) conversion", gray2rgb, af_gray2rgb);
macro_rules! hsvrgb_func_def {
($doc_str: expr, $fn_name: ident, $ffi_name: ident) => {
#[doc=$doc_str]
pub fn $fn_name<T>(input: &Array<T>) -> Array<T>
where
T: HasAfEnum + RealFloating,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = $ffi_name(&mut temp as *mut af_array, input.get());
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
};
}
hsvrgb_func_def!("HSV to RGB color space conversion", hsv2rgb, af_hsv2rgb);
hsvrgb_func_def!("RGB to HSV color space conversion", rgb2hsv, af_rgb2hsv);
#[allow(clippy::too_many_arguments)]
pub fn unwrap<T: HasAfEnum>(
input: &Array<T>,
wx: i64,
wy: i64,
sx: i64,
sy: i64,
px: i64,
py: i64,
is_column: bool,
) -> Array<T> {
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_unwrap(
&mut temp as *mut af_array,
input.get(),
wx,
wy,
sx,
sy,
px,
py,
is_column,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
#[allow(clippy::too_many_arguments)]
pub fn wrap<T: HasAfEnum>(
input: &Array<T>,
ox: i64,
oy: i64,
wx: i64,
wy: i64,
sx: i64,
sy: i64,
px: i64,
py: i64,
is_column: bool,
) -> Array<T> {
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_wrap(
&mut temp as *mut af_array,
input.get(),
ox,
oy,
wx,
wy,
sx,
sy,
px,
py,
is_column,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn sat<T>(input: &Array<T>) -> Array<T::AggregateOutType>
where
T: HasAfEnum + RealNumber,
T::AggregateOutType: HasAfEnum,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_sat(&mut temp as *mut af_array, input.get());
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn rgb2ycbcr<T>(input: &Array<T>, standard: YCCStd) -> Array<T>
where
T: HasAfEnum + RealFloating,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_rgb2ycbcr(&mut temp as *mut af_array, input.get(), standard as c_uint);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn ycbcr2rgb<T>(input: &Array<T>, standard: YCCStd) -> Array<T>
where
T: HasAfEnum + RealFloating,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_ycbcr2rgb(&mut temp as *mut af_array, input.get(), standard as c_uint);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn is_imageio_available() -> bool {
let mut temp: bool = false;
unsafe {
af_is_image_io_available(&mut temp as *mut bool);
}
temp
}
pub fn transform_coords<T>(tf: &Array<T>, d0: f32, d1: f32) -> Array<T>
where
T: HasAfEnum + RealFloating,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_transform_coordinates(&mut temp as *mut af_array, tf.get(), d0, d1);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn moments<T>(input: &Array<T>, moment: MomentType) -> Array<f32>
where
T: HasAfEnum + MomentsComputable,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_moments(&mut temp as *mut af_array, input.get(), moment as c_uint);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn moments_all<T>(input: &Array<T>, moment: MomentType) -> f64
where
T: HasAfEnum + MomentsComputable,
{
let mut temp: f64 = 0.0;
unsafe {
let err_val = af_moments_all(&mut temp as *mut c_double, input.get(), moment as c_uint);
HANDLE_ERROR(AfError::from(err_val));
}
temp
}
pub fn medfilt1<T>(input: &Array<T>, wlen: u64, etype: BorderType) -> Array<T>
where
T: HasAfEnum + ImageFilterType,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_medfilt1(
&mut temp as *mut af_array,
input.get(),
wlen as dim_t,
etype as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn canny<T>(
input: &Array<T>,
threshold_type: CannyThresholdType,
low: f32,
high: f32,
sobel_window: u32,
is_fast: bool,
) -> Array<bool>
where
T: HasAfEnum + EdgeComputable,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_canny(
&mut temp as *mut af_array,
input.get(),
threshold_type as c_int,
low,
high,
sobel_window as c_uint,
is_fast,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn anisotropic_diffusion<T>(
img: &Array<T>,
dt: f32,
k: f32,
iters: u32,
fftype: FluxFn,
diff_kind: DiffusionEq,
) -> Array<T::AbsOutType>
where
T: HasAfEnum + EdgeComputable,
T::AbsOutType: HasAfEnum,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_anisotropic_diffusion(
&mut temp as *mut af_array,
img.get(),
dt,
k,
iters,
fftype as c_uint,
diff_kind as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn confidence_cc<InOutType>(
input: &Array<InOutType>,
seedx: &Array<u32>,
seedy: &Array<u32>,
radius: u32,
multiplier: u32,
iterations: u32,
segmented_val: f64,
) -> Array<InOutType>
where
InOutType: ConfidenceCCInput,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_confidence_cc(
&mut temp as *mut af_array,
input.get(),
seedx.get(),
seedy.get(),
radius,
multiplier,
iterations as i32,
segmented_val,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn iterative_deconv<T>(
input: &Array<T>,
kernel: &Array<f32>,
iterations: u32,
relaxation_factor: f32,
algo: IterativeDeconvAlgo,
) -> Array<T::AbsOutType>
where
T: DeconvInput,
T::AbsOutType: HasAfEnum,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_iterative_deconv(
&mut temp as *mut af_array,
input.get(),
kernel.get(),
iterations,
relaxation_factor,
algo as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}
pub fn inverse_deconv<T>(
input: &Array<T>,
kernel: &Array<f32>,
gamma: f32,
algo: InverseDeconvAlgo,
) -> Array<T::AbsOutType>
where
T: DeconvInput,
T::AbsOutType: HasAfEnum,
{
unsafe {
let mut temp: af_array = std::ptr::null_mut();
let err_val = af_inverse_deconv(
&mut temp as *mut af_array,
input.get(),
kernel.get(),
gamma,
algo as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
temp.into()
}
}