- default value argument for interpolation
This commit is contained in:
1 parent
b12982da48
commit
9257dd1fcf
4 files changed
+157
-35
No files matched your search
+122
-2
@@ -1,3 +1,4 @@
|
|||||||
|
use std::hash::Hash;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use crate::par_indexed_iter::ParallelIndexedIterMut;
|
use crate::par_indexed_iter::ParallelIndexedIterMut;
|
||||||
use crate::transform::{Transform, transform_point};
|
use crate::transform::{Transform, transform_point};
|
||||||
@@ -9,6 +10,10 @@ use num::traits::FloatConst;
|
|||||||
use num::{Complex, cast::AsPrimitive, complex::ComplexFloat};
|
use num::{Complex, cast::AsPrimitive, complex::ComplexFloat};
|
||||||
use rayon::iter::ParallelIterator;
|
use rayon::iter::ParallelIterator;
|
||||||
use std::ops::{Deref, MulAssign};
|
use std::ops::{Deref, MulAssign};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use rand::distr::StandardUniform;
|
||||||
|
use rand::RngExt;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
fn in_shape(shape_f: &[f64], v: &[f64]) -> bool {
|
fn in_shape(shape_f: &[f64], v: &[f64]) -> bool {
|
||||||
shape_f
|
shape_f
|
||||||
@@ -17,6 +22,117 @@ fn in_shape(shape_f: &[f64], v: &[f64]) -> bool {
|
|||||||
.all(|(s, x)| (-0.5 <= *x) && (x <= s))
|
.all(|(s, x)| (-0.5 <= *x) && (x <= s))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct DefaultValue {
|
||||||
|
#[serde(skip, default = "DefaultValue::make_rng")]
|
||||||
|
rng: Arc<Mutex<rand::prelude::StdRng>>,
|
||||||
|
values: Vec<f64>,
|
||||||
|
weights: Vec<f64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for DefaultValue {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
rng: Self::make_rng(),
|
||||||
|
values: self.values.clone(),
|
||||||
|
weights: self.weights.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DefaultValue {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
rng: Self::make_rng(),
|
||||||
|
values: vec![0.0],
|
||||||
|
weights: vec![1.0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for DefaultValue {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
(self.values == other.values) && (self.weights == other.weights)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DefaultValue {
|
||||||
|
pub fn new(mut values: Vec<f64>, mut weights: Vec<f64>) -> Self {
|
||||||
|
if values.is_empty() {
|
||||||
|
values.push(f64::NAN);
|
||||||
|
}
|
||||||
|
if weights.len() != values.len() {
|
||||||
|
weights.resize(values.len(), 1.0);
|
||||||
|
}
|
||||||
|
weights.iter_mut().for_each(|w| {
|
||||||
|
if !w.is_finite() {
|
||||||
|
*w = 1.0;
|
||||||
|
} else if *w < 0.0 {
|
||||||
|
*w = 0.0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let n = weights.iter().sum::<f64>();
|
||||||
|
weights.iter_mut().fold(0.0, |w, x| {
|
||||||
|
*x += w / n;
|
||||||
|
*x
|
||||||
|
});
|
||||||
|
Self {
|
||||||
|
rng: Self::make_rng(),
|
||||||
|
values,
|
||||||
|
weights,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn values(&self) -> &[f64] {
|
||||||
|
&self.values
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn weights(&self) -> &[f64] {
|
||||||
|
&self.weights
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sample(&self) -> f64 {
|
||||||
|
if self.values.len() == 1 {
|
||||||
|
self.values[0]
|
||||||
|
} else {
|
||||||
|
let i = self.rng.lock().unwrap().sample::<f64, _>(StandardUniform);
|
||||||
|
let n = self.weights.iter().position(|&w| i >= w).expect("weights should sum to 1");
|
||||||
|
self.values[n]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_rng() -> Arc<Mutex<rand::prelude::StdRng>> {
|
||||||
|
Arc::new(Mutex::new(rand::make_rng()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for DefaultValue {}
|
||||||
|
|
||||||
|
impl Hash for DefaultValue {
|
||||||
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.values.iter().for_each(|v| v.to_bits().hash(state));
|
||||||
|
self.weights.iter().for_each(|v| v.to_bits().hash(state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<f64> for DefaultValue {
|
||||||
|
fn from(value: f64) -> Self {
|
||||||
|
Self::new(vec![value], vec![1.0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<f64>> for DefaultValue {
|
||||||
|
fn from(value: Vec<f64>) -> Self {
|
||||||
|
Self::new(value, Vec::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&[f64]> for DefaultValue {
|
||||||
|
fn from(value: &[f64]) -> Self {
|
||||||
|
Self::new(value.to_vec(), Vec::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct BSplineMem {
|
pub struct BSplineMem {
|
||||||
ndim: usize,
|
ndim: usize,
|
||||||
@@ -74,7 +190,7 @@ where
|
|||||||
D: Dimension,
|
D: Dimension,
|
||||||
BSpline<N, D>: BSplineTrait<D>,
|
BSpline<N, D>: BSplineTrait<D>,
|
||||||
{
|
{
|
||||||
pub fn interpolate(&self, transform: &Transform<D>) -> Result<Array<f64, D>, Error> {
|
pub fn interpolate(&self, transform: &Transform<D>, default_value: &DefaultValue) -> Result<Array<f64, D>, Error> {
|
||||||
let mut mem = self.get_mem();
|
let mut mem = self.get_mem();
|
||||||
let shape_f = self.shape_f();
|
let shape_f = self.shape_f();
|
||||||
let center = shape_f.iter().map(|i| i / 2.0).collect::<Vec<_>>();
|
let center = shape_f.iter().map(|i| i / 2.0).collect::<Vec<_>>();
|
||||||
@@ -91,13 +207,15 @@ where
|
|||||||
};
|
};
|
||||||
if in_shape(&shape_f, &v) {
|
if in_shape(&shape_f, &v) {
|
||||||
*x = self.evaluate_at_continuous_index(&v, &mut mem)?;
|
*x = self.evaluate_at_continuous_index(&v, &mut mem)?;
|
||||||
|
} else {
|
||||||
|
*x = default_value.sample();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(new)
|
Ok(new)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interpolate_par(&self, transform: &Transform<D>) -> Result<Array<f64, D>, Error> {
|
pub fn interpolate_par(&self, transform: &Transform<D>, default_value: &DefaultValue) -> Result<Array<f64, D>, Error> {
|
||||||
let mem = self.get_mem();
|
let mem = self.get_mem();
|
||||||
let shape_f = self.shape_f();
|
let shape_f = self.shape_f();
|
||||||
let center = shape_f.iter().map(|i| i / 2.0).collect::<Vec<_>>();
|
let center = shape_f.iter().map(|i| i / 2.0).collect::<Vec<_>>();
|
||||||
@@ -114,6 +232,8 @@ where
|
|||||||
.all(|(s, x)| (-0.5 <= *x) && (x <= s))
|
.all(|(s, x)| (-0.5 <= *x) && (x <= s))
|
||||||
{
|
{
|
||||||
*x = self.evaluate_at_continuous_index(&v, &mut mem)?;
|
*x = self.evaluate_at_continuous_index(&v, &mut mem)?;
|
||||||
|
} else {
|
||||||
|
*x = default_value.sample();
|
||||||
}
|
}
|
||||||
Ok(mem)
|
Ok(mem)
|
||||||
},
|
},
|
||||||
|
|||||||
+3
-3
@@ -84,7 +84,7 @@ mod tests {
|
|||||||
let c = [-0.8, 0.156];
|
let c = [-0.8, 0.156];
|
||||||
let j = julia_image(&shape, &transform_j, ¢er, &c).mapv(|x| x as f64);
|
let j = julia_image(&shape, &transform_j, ¢er, &c).mapv(|x| x as f64);
|
||||||
let k = julia_image(&shape, &transform_k, ¢er, &c).mapv(|x| x as f64);
|
let k = julia_image(&shape, &transform_k, ¢er, &c).mapv(|x| x as f64);
|
||||||
let n = transform.interpolate::<3, _, _>(k.view())?;
|
let n = transform.interpolate::<3, _, _>(k.view(), &Default::default())?;
|
||||||
let sj = j.iter().sum::<f64>();
|
let sj = j.iter().sum::<f64>();
|
||||||
// let sk = k.iter().sum::<f64>();
|
// let sk = k.iter().sum::<f64>();
|
||||||
let sn = n.iter().sum::<f64>();
|
let sn = n.iter().sum::<f64>();
|
||||||
@@ -124,7 +124,7 @@ mod tests {
|
|||||||
let c = [-0.8, 0.156];
|
let c = [-0.8, 0.156];
|
||||||
let j = julia_image(&shape, &transform_j, ¢er, &c).mapv(|x| x as f64);
|
let j = julia_image(&shape, &transform_j, ¢er, &c).mapv(|x| x as f64);
|
||||||
let k = julia_image(&shape, &transform_k, ¢er, &c).mapv(|x| x as f64);
|
let k = julia_image(&shape, &transform_k, ¢er, &c).mapv(|x| x as f64);
|
||||||
let n = transform.interpolate_par::<3, _, _>(k.view())?;
|
let n = transform.interpolate_par::<3, _, _>(k.view(), &Default::default())?;
|
||||||
let sj = j.iter().sum::<f64>();
|
let sj = j.iter().sum::<f64>();
|
||||||
let sn = n.iter().sum::<f64>();
|
let sn = n.iter().sum::<f64>();
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ mod tests {
|
|||||||
&[-0.8, 0.156],
|
&[-0.8, 0.156],
|
||||||
);
|
);
|
||||||
let transform = Transform::from_rotation(1.0, &[3999.5, 2999.5]);
|
let transform = Transform::from_rotation(1.0, &[3999.5, 2999.5]);
|
||||||
let image_b = transform.interpolate_par::<3, _, _>(image_a.view())?;
|
let image_b = transform.interpolate_par::<3, _, _>(image_a.view(), &Default::default())?;
|
||||||
assert_ne!(image_b[[4000, 3000]], 0.0);
|
assert_ne!(image_b[[4000, 3000]], 0.0);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -9,8 +9,7 @@ use itertools::Itertools;
|
|||||||
use ndarray::{Array, Array1, Array2, Array3, AsArray, Axis, Dimension, s};
|
use ndarray::{Array, Array1, Array2, Array3, AsArray, Axis, Dimension, s};
|
||||||
use num::cast::AsPrimitive;
|
use num::cast::AsPrimitive;
|
||||||
use rand::RngExt;
|
use rand::RngExt;
|
||||||
use rayon::iter::IntoParallelIterator;
|
use rayon::iter::{ParallelIterator, IntoParallelIterator};
|
||||||
use rayon::iter::ParallelIterator;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|||||||
+31
-28
@@ -1,4 +1,4 @@
|
|||||||
use crate::bspline::{BSpline, BSplineTrait};
|
use crate::bspline::{BSpline, BSplineTrait, DefaultValue};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::filter::{fft, ifft};
|
use crate::filter::{fft, ifft};
|
||||||
use crate::metric::FixedMu;
|
use crate::metric::FixedMu;
|
||||||
@@ -811,7 +811,7 @@ impl<D: Dimension> Transform<D> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interpolate<'a, const B: usize, T, A>(&self, image: A) -> Result<Array<f64, D>, Error>
|
pub fn interpolate<'a, const B: usize, T, A>(&self, image: A, default_value: &DefaultValue) -> Result<Array<f64, D>, Error>
|
||||||
where
|
where
|
||||||
A: AsArray<'a, T, D>,
|
A: AsArray<'a, T, D>,
|
||||||
D: Dimension,
|
D: Dimension,
|
||||||
@@ -820,12 +820,13 @@ impl<D: Dimension> Transform<D> {
|
|||||||
{
|
{
|
||||||
let image = image.into();
|
let image = image.into();
|
||||||
let bspline = BSpline::<B, _>::new(&image);
|
let bspline = BSpline::<B, _>::new(&image);
|
||||||
bspline.interpolate(self)
|
bspline.interpolate(self, default_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interpolate_par<'a, const B: usize, T, A>(
|
pub fn interpolate_par<'a, const B: usize, T, A>(
|
||||||
&self,
|
&self,
|
||||||
image: A,
|
image: A,
|
||||||
|
default_value: &DefaultValue,
|
||||||
) -> Result<Array<f64, D>, Error>
|
) -> Result<Array<f64, D>, Error>
|
||||||
where
|
where
|
||||||
A: AsArray<'a, T, D>,
|
A: AsArray<'a, T, D>,
|
||||||
@@ -835,13 +836,14 @@ impl<D: Dimension> Transform<D> {
|
|||||||
{
|
{
|
||||||
let image = image.into();
|
let image = image.into();
|
||||||
let bspline = BSpline::<B, _>::new(&image);
|
let bspline = BSpline::<B, _>::new(&image);
|
||||||
bspline.interpolate_par(self)
|
bspline.interpolate_par(self, default_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interpolate_order<'a, T, A>(
|
pub fn interpolate_order<'a, T, A>(
|
||||||
&self,
|
&self,
|
||||||
image: A,
|
image: A,
|
||||||
order: usize,
|
order: usize,
|
||||||
|
default_value: &DefaultValue,
|
||||||
) -> Result<Array<f64, D>, Error>
|
) -> Result<Array<f64, D>, Error>
|
||||||
where
|
where
|
||||||
A: AsArray<'a, T, D>,
|
A: AsArray<'a, T, D>,
|
||||||
@@ -849,12 +851,12 @@ impl<D: Dimension> Transform<D> {
|
|||||||
T: 'a + Clone + AsPrimitive<f64>,
|
T: 'a + Clone + AsPrimitive<f64>,
|
||||||
{
|
{
|
||||||
match order {
|
match order {
|
||||||
0 => Ok(self.interpolate::<0, _, _>(image)?),
|
0 => Ok(self.interpolate::<0, _, _>(image, default_value)?),
|
||||||
1 => Ok(self.interpolate::<1, _, _>(image)?),
|
1 => Ok(self.interpolate::<1, _, _>(image, default_value)?),
|
||||||
2 => Ok(self.interpolate::<2, _, _>(image)?),
|
2 => Ok(self.interpolate::<2, _, _>(image, default_value)?),
|
||||||
3 => Ok(self.interpolate::<3, _, _>(image)?),
|
3 => Ok(self.interpolate::<3, _, _>(image, default_value)?),
|
||||||
4 => Ok(self.interpolate::<4, _, _>(image)?),
|
4 => Ok(self.interpolate::<4, _, _>(image, default_value)?),
|
||||||
5 => Ok(self.interpolate::<5, _, _>(image)?),
|
5 => Ok(self.interpolate::<5, _, _>(image, default_value)?),
|
||||||
_ => Err(Error::InterpolationNotImplemented(order)),
|
_ => Err(Error::InterpolationNotImplemented(order)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -863,6 +865,7 @@ impl<D: Dimension> Transform<D> {
|
|||||||
&self,
|
&self,
|
||||||
image: A,
|
image: A,
|
||||||
order: usize,
|
order: usize,
|
||||||
|
default_value: &DefaultValue,
|
||||||
) -> Result<Array<f64, D>, Error>
|
) -> Result<Array<f64, D>, Error>
|
||||||
where
|
where
|
||||||
A: AsArray<'a, T, D>,
|
A: AsArray<'a, T, D>,
|
||||||
@@ -870,12 +873,12 @@ impl<D: Dimension> Transform<D> {
|
|||||||
T: 'a + Clone + AsPrimitive<f64>,
|
T: 'a + Clone + AsPrimitive<f64>,
|
||||||
{
|
{
|
||||||
match order {
|
match order {
|
||||||
0 => Ok(self.interpolate_par::<0, _, _>(image)?),
|
0 => Ok(self.interpolate_par::<0, _, _>(image, default_value)?),
|
||||||
1 => Ok(self.interpolate_par::<1, _, _>(image)?),
|
1 => Ok(self.interpolate_par::<1, _, _>(image, default_value)?),
|
||||||
2 => Ok(self.interpolate_par::<2, _, _>(image)?),
|
2 => Ok(self.interpolate_par::<2, _, _>(image, default_value)?),
|
||||||
3 => Ok(self.interpolate_par::<3, _, _>(image)?),
|
3 => Ok(self.interpolate_par::<3, _, _>(image, default_value)?),
|
||||||
4 => Ok(self.interpolate_par::<4, _, _>(image)?),
|
4 => Ok(self.interpolate_par::<4, _, _>(image, default_value)?),
|
||||||
5 => Ok(self.interpolate_par::<5, _, _>(image)?),
|
5 => Ok(self.interpolate_par::<5, _, _>(image, default_value)?),
|
||||||
_ => Err(Error::InterpolationNotImplemented(order)),
|
_ => Err(Error::InterpolationNotImplemented(order)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1045,8 +1048,8 @@ mod tests {
|
|||||||
&[-0.8, 0.156],
|
&[-0.8, 0.156],
|
||||||
);
|
);
|
||||||
let transform = Transform::from_rotation(1.0, &[3999.5, 2999.5]);
|
let transform = Transform::from_rotation(1.0, &[3999.5, 2999.5]);
|
||||||
let image_b = transform.interpolate_par::<3, _, _>(image_a.view())?;
|
let image_b = transform.interpolate_par::<3, _, _>(image_a.view(), &Default::default())?;
|
||||||
let image_c = transform.interpolate::<3, _, _>(image_a.view())?;
|
let image_c = transform.interpolate::<3, _, _>(image_a.view(), &Default::default())?;
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
image_b
|
image_b
|
||||||
@@ -1066,7 +1069,7 @@ mod tests {
|
|||||||
&[-0.8, 0.156],
|
&[-0.8, 0.156],
|
||||||
);
|
);
|
||||||
let transform = Transform::from_rotation(1.0, &[3999.5, 2999.5]);
|
let transform = Transform::from_rotation(1.0, &[3999.5, 2999.5]);
|
||||||
let image_b = transform.interpolate::<3, _, _>(image_a.view())?;
|
let image_b = transform.interpolate::<3, _, _>(image_a.view(), &Default::default())?;
|
||||||
assert_ne!(image_b[[4000, 3000]], 0.0);
|
assert_ne!(image_b[[4000, 3000]], 0.0);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1080,7 +1083,7 @@ mod tests {
|
|||||||
&[-0.8, 0.156],
|
&[-0.8, 0.156],
|
||||||
);
|
);
|
||||||
let transform = Transform::from_rotation(1.0, &[3999.5, 2999.5]);
|
let transform = Transform::from_rotation(1.0, &[3999.5, 2999.5]);
|
||||||
let image_b = transform.interpolate_par::<3, _, _>(image_a.view())?;
|
let image_b = transform.interpolate_par::<3, _, _>(image_a.view(), &Default::default())?;
|
||||||
assert_ne!(image_b[[4000, 3000]], 0.0);
|
assert_ne!(image_b[[4000, 3000]], 0.0);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1099,7 +1102,7 @@ mod tests {
|
|||||||
.slice(s![.., 0])
|
.slice(s![.., 0])
|
||||||
.mapv(|i| i as f64);
|
.mapv(|i| i as f64);
|
||||||
let q = vec![0.85, 4.0];
|
let q = vec![0.85, 4.0];
|
||||||
let im_b = Transform::new(q).interpolate::<1, _, _>(&im_a)?;
|
let im_b = Transform::new(q).interpolate::<1, _, _>(&im_a, &Default::default())?;
|
||||||
|
|
||||||
// Test with ALL points (like grad_check uses)
|
// Test with ALL points (like grad_check uses)
|
||||||
let metric_all = MattesMetric::<ndarray::Ix1>::new(
|
let metric_all = MattesMetric::<ndarray::Ix1>::new(
|
||||||
@@ -1183,7 +1186,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.slice(s![.., 0])
|
.slice(s![.., 0])
|
||||||
.mapv(|i| i as f64);
|
.mapv(|i| i as f64);
|
||||||
let im_b = Transform::new(vec![0.85, 4.0]).interpolate::<1, _, _>(&im_a)?;
|
let im_b = Transform::new(vec![0.85, 4.0]).interpolate::<1, _, _>(&im_a, &Default::default())?;
|
||||||
|
|
||||||
// Smooth both images with sigma=8 like level 0
|
// Smooth both images with sigma=8 like level 0
|
||||||
let sigma = Sigma::Absolute(vec![8.0]);
|
let sigma = Sigma::Absolute(vec![8.0]);
|
||||||
@@ -1292,7 +1295,7 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let q = vec![0.85, 2.0];
|
let q = vec![0.85, 2.0];
|
||||||
let moving = Transform::new(q.clone()).interpolate::<3, _, _>(&fixed)?;
|
let moving = Transform::new(q.clone()).interpolate::<3, _, _>(&fixed, &Default::default())?;
|
||||||
|
|
||||||
// The registration finds T such that im_b(T(x)) = im_a(x), which is the inverse of q
|
// The registration finds T such that im_b(T(x)) = im_a(x), which is the inverse of q
|
||||||
let q_inv = Transform::<ndarray::Ix1>::new(q.clone()).inverse()?;
|
let q_inv = Transform::<ndarray::Ix1>::new(q.clone()).inverse()?;
|
||||||
@@ -1348,7 +1351,7 @@ mod tests {
|
|||||||
.slice(s![.., 0])
|
.slice(s![.., 0])
|
||||||
.mapv(|i| i as f64);
|
.mapv(|i| i as f64);
|
||||||
let q = vec![0.85, 2.0];
|
let q = vec![0.85, 2.0];
|
||||||
let im_b = Transform::new(q.clone()).interpolate::<1, _, _>(&im_a)?;
|
let im_b = Transform::new(q.clone()).interpolate::<1, _, _>(&im_a, &Default::default())?;
|
||||||
|
|
||||||
let f = Sigma::Absolute(vec![1.0]).smooth(im_a.view())?;
|
let f = Sigma::Absolute(vec![1.0]).smooth(im_a.view())?;
|
||||||
let m = Sigma::Absolute(vec![1.0]).smooth(im_b.view())?;
|
let m = Sigma::Absolute(vec![1.0]).smooth(im_b.view())?;
|
||||||
@@ -1468,7 +1471,7 @@ mod tests {
|
|||||||
let params = vec![c * sx, -s * sy + shx, s * sx + shy, c * sy, tx, ty];
|
let params = vec![c * sx, -s * sy + shx, s * sx + shy, c * sy, tx, ty];
|
||||||
|
|
||||||
let transform = Transform::<Ix2>::new_around_center(params.clone(), ¢er);
|
let transform = Transform::<Ix2>::new_around_center(params.clone(), ¢er);
|
||||||
let moving = transform.interpolate::<3, _, _>(fixed.view())?;
|
let moving = transform.interpolate::<3, _, _>(fixed.view(), &Default::default())?;
|
||||||
|
|
||||||
let q_inv = transform.inverse()?.parameters;
|
let q_inv = transform.inverse()?.parameters;
|
||||||
|
|
||||||
@@ -1510,7 +1513,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.mapv(|i| i as f64);
|
.mapv(|i| i as f64);
|
||||||
let rotation = Transform::<Ix2>::from_rotation(f64::PI() / 4.0, ¢er);
|
let rotation = Transform::<Ix2>::from_rotation(f64::PI() / 4.0, ¢er);
|
||||||
let im_b = rotation.interpolate::<3, _, _>(im_a.view())?;
|
let im_b = rotation.interpolate::<3, _, _>(im_a.view(), &Default::default())?;
|
||||||
|
|
||||||
let q_inv = rotation.inverse()?.parameters;
|
let q_inv = rotation.inverse()?.parameters;
|
||||||
let p = rotation.parameters.clone();
|
let p = rotation.parameters.clone();
|
||||||
@@ -1592,7 +1595,7 @@ mod tests {
|
|||||||
// Full resolution, sigma=4.0 — matching elastix FixedSmoothingImagePyramid (no downsampling)
|
// Full resolution, sigma=4.0 — matching elastix FixedSmoothingImagePyramid (no downsampling)
|
||||||
for angle_deg in [5.0f64, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0] {
|
for angle_deg in [5.0f64, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0] {
|
||||||
let rotation = Transform::<Ix2>::from_rotation(angle_deg.to_radians(), ¢er);
|
let rotation = Transform::<Ix2>::from_rotation(angle_deg.to_radians(), ¢er);
|
||||||
let im_b = rotation.interpolate::<3, _, _>(im_a.view())?;
|
let im_b = rotation.interpolate::<3, _, _>(im_a.view(), &Default::default())?;
|
||||||
let q_inv = rotation.inverse()?.parameters;
|
let q_inv = rotation.inverse()?.parameters;
|
||||||
let p = rotation.parameters.clone();
|
let p = rotation.parameters.clone();
|
||||||
let f = gaussian_smooth(im_a.view(), &[4.0, 4.0])?;
|
let f = gaussian_smooth(im_a.view(), &[4.0, 4.0])?;
|
||||||
@@ -1727,7 +1730,7 @@ mod tests {
|
|||||||
fn register_real_images2() -> Result<(), Box<dyn std::error::Error>> {
|
fn register_real_images2() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let fixed = read_tiff("test_files/fixed.tif")?;
|
let fixed = read_tiff("test_files/fixed.tif")?;
|
||||||
let e = Transform::<Ix2>::new(vec![0.8, 0.0, 0.0, 1.0, 0.0, 0.0]).inverse()?;
|
let e = Transform::<Ix2>::new(vec![0.8, 0.0, 0.0, 1.0, 0.0, 0.0]).inverse()?;
|
||||||
let moving = e.interpolate::<3, _, _>(fixed.view())?;
|
let moving = e.interpolate::<3, _, _>(fixed.view(), &Default::default())?;
|
||||||
|
|
||||||
let t = Transform::<Ix2>::register(
|
let t = Transform::<Ix2>::register(
|
||||||
fixed.view(),
|
fixed.view(),
|
||||||
|
|||||||
Reference in new issue
Block a user