- registration getting better
This commit is contained in:
+48
-97
@@ -276,6 +276,11 @@ impl<D: Dimension> Transform<D> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_shape(mut self, shape: Vec<usize>) -> Self {
|
||||
self.shape = shape;
|
||||
self
|
||||
}
|
||||
|
||||
/// create a transform from a scaling
|
||||
pub fn from_scaling(scaling: &[f64]) -> Self {
|
||||
let ndim = if let Some(ndim) = D::NDIM {
|
||||
@@ -673,7 +678,6 @@ mod tests {
|
||||
)
|
||||
.slice(s![.., 0])
|
||||
.mapv(|i| i as f64);
|
||||
let q = vec![0.85, 4.0];
|
||||
let im_b =
|
||||
Transform::new(vec![0.85, 4.0], vec![im_a.shape()[0]]).interpolate::<1, _, _>(&im_a)?;
|
||||
|
||||
@@ -960,98 +964,6 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn register2_interpolate() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let shape = [200, 200];
|
||||
let center = [99.5, 99.5];
|
||||
let im_a = julia_image(
|
||||
&shape,
|
||||
&[1.0, 0.0, 0.0, 1.0, 0.0, 0.0],
|
||||
¢er,
|
||||
&[-0.8, 0.156],
|
||||
)
|
||||
.mapv(|i| i as f64);
|
||||
let rotation = Transform::<Ix2>::from_rotation(f64::PI() / 4.0, ¢er);
|
||||
let im_b = rotation.interpolate::<3, _, _>(im_a.view())?;
|
||||
|
||||
let q_inv = rotation.inverse()?.parameters;
|
||||
|
||||
// Use default_steps which matches elastix FixedSmoothingImagePyramid:
|
||||
// sigma = [4.0, 2.0, 1.0, 0.5] (schedule [8,4,2,1] with spacing=1)
|
||||
let (t, steps) = Transform::register_debug(
|
||||
im_a.view(),
|
||||
im_b.view(),
|
||||
vec![None, None, None, None, None, None],
|
||||
None,
|
||||
None,
|
||||
)?;
|
||||
println!("steps:");
|
||||
for step in steps {
|
||||
println!(" {:?}", step);
|
||||
}
|
||||
println!("t: {:?}", t);
|
||||
println!("i: {:?}", t.inverse()?);
|
||||
println!("q_inv: {:?}", q_inv);
|
||||
assert!(
|
||||
t.parameters
|
||||
.iter()
|
||||
.zip(q_inv.iter())
|
||||
.map(|(a, b)| (a - b).powi(2))
|
||||
.sum::<f64>()
|
||||
< 1.0
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn register2() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let t = Transform::from_rotation(f64::PI() / 4.0, &[299.5, 399.5]);
|
||||
let s = Transform::new(vec![1.0, 0.0, 0.0, 1.0, 0.0, 0.0], vec![600, 800]);
|
||||
let r = t * s;
|
||||
let p = r.parameters;
|
||||
println!("{:?}", p);
|
||||
|
||||
let im_a = julia_image(
|
||||
&[600, 800],
|
||||
&[1.0, 0.0, 0.0, 1.0, 0.0, 0.0],
|
||||
&[299.5, 399.5],
|
||||
&[-0.8, 0.156],
|
||||
);
|
||||
let im_b = julia_image(
|
||||
&[600, 800],
|
||||
&[p[0], p[1], p[2], p[3], p[4], p[5]],
|
||||
&[299.5, 399.5],
|
||||
&[-0.8, 0.156],
|
||||
);
|
||||
let (t, steps) = Transform::register_debug(
|
||||
im_a.view(),
|
||||
im_b.view(),
|
||||
vec![None, None, None, None, None, None],
|
||||
None,
|
||||
None,
|
||||
)?;
|
||||
println!("steps:");
|
||||
for step in steps {
|
||||
println!(" {:?}", step);
|
||||
}
|
||||
println!("t: {:?}", t);
|
||||
println!("i: {:?}", t.inverse()?);
|
||||
println!("p: {:?}", p);
|
||||
// julia_image applies transform to coordinates, so T maps im_b->im_a means T = p_inv
|
||||
let p_inv = Transform::<ndarray::Ix2>::new(p.clone(), vec![600, 800])
|
||||
.inverse()?
|
||||
.parameters;
|
||||
assert!(
|
||||
t.parameters
|
||||
.iter()
|
||||
.zip(p_inv.iter())
|
||||
.map(|(a, b)| (a - b).powi(2))
|
||||
.sum::<f64>()
|
||||
< 1.0
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_tiff<P: AsRef<Path>>(path: P) -> Result<Array2<f64>, Box<dyn std::error::Error>> {
|
||||
let mut reader = Decoder::new(File::open(path)?)?;
|
||||
reader.seek_to_image(0)?;
|
||||
@@ -1064,7 +976,7 @@ mod tests {
|
||||
DecodingResult::I16(data) => data.into_iter().map(|i| i as f64).collect::<Vec<_>>(),
|
||||
DecodingResult::I32(data) => data.into_iter().map(|i| i as f64).collect::<Vec<_>>(),
|
||||
DecodingResult::I64(data) => data.into_iter().map(|i| i as f64).collect::<Vec<_>>(),
|
||||
DecodingResult::F16(data) => data.into_iter().map(|i| f64::from(i)).collect::<Vec<_>>(),
|
||||
DecodingResult::F16(data) => data.into_iter().map(f64::from).collect::<Vec<_>>(),
|
||||
DecodingResult::F32(data) => data.into_iter().map(|i| i as f64).collect::<Vec<_>>(),
|
||||
DecodingResult::F64(data) => data,
|
||||
};
|
||||
@@ -1110,14 +1022,53 @@ mod tests {
|
||||
.fold(0.0f64, f64::max);
|
||||
println!("Our: {:?} max_err: {:.4} sse: {:.4}", t, max_err, sse);
|
||||
|
||||
assert!(max_err < 1.0);
|
||||
assert!(sse < 1.0);
|
||||
|
||||
let mut tif = IJTiffFile::new(std::env::home_dir().unwrap().join("tmp/register_real_images.tif"))?;
|
||||
tif.save(fixed.mapv(|i| i as u16), 0, 0, 0)?;
|
||||
tif.save(t.interpolate_par::<1, _, _>(moving.view())?.mapv(|i| i as u16), 1, 0, 0)?;
|
||||
tif.save(moving.mapv(|i| i as u16), 2, 0, 0)?;
|
||||
|
||||
assert!(max_err < 0.1);
|
||||
assert!(sse < 0.1);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn register_real_images2() -> Result<(), Box<dyn std::error::Error>> {
|
||||
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], fixed.shape().to_vec()).inverse()?;
|
||||
let moving = e.interpolate::<3, _, _>(fixed.view())?;
|
||||
|
||||
let t = Transform::<Ix2>::register(
|
||||
fixed.view(),
|
||||
moving.view(),
|
||||
vec![None, None, None, None, None, None],
|
||||
None,
|
||||
None,
|
||||
)?;
|
||||
|
||||
let sse = t
|
||||
.parameters
|
||||
.iter()
|
||||
.zip(e.parameters.iter())
|
||||
.map(|(a, b)| (a - b).powi(2))
|
||||
.sum::<f64>();
|
||||
let max_err = t
|
||||
.parameters
|
||||
.iter()
|
||||
.zip(e.parameters.iter())
|
||||
.map(|(a, b)| (a - b).abs())
|
||||
.fold(0.0f64, f64::max);
|
||||
println!("Our: {:?} max_err: {:.4} sse: {:.4}", t, max_err, sse);
|
||||
|
||||
// let mut tif = IJTiffFile::new(std::env::home_dir().unwrap().join("tmp/register_real_images2.tif"))?;
|
||||
// tif.save(fixed.mapv(|i| i as u16), 0, 0, 0)?;
|
||||
// tif.save(t.interpolate_par::<1, _, _>(moving.view())?.mapv(|i| i as u16), 1, 0, 0)?;
|
||||
// tif.save(moving.mapv(|i| i as u16), 2, 0, 0)?;
|
||||
|
||||
assert!(max_err < 0.1);
|
||||
assert!(sse < 0.1);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user