Now build SimpleITK into static libs and use (auto)cxx.

This commit is contained in:
Wim Pomp
2025-09-12 18:03:24 +02:00
parent 0c6a38e4fa
commit 5750fd7f99
17 changed files with 8110 additions and 1426 deletions

View File

@@ -2,30 +2,47 @@
This crate does two things:
- find an affine transform or translation that transforms one image into the other
- use bpline or nearest neighbor interpolation to apply a transformation to an image
- use bspline or nearest neighbor interpolation to apply a transformation to an image
To do this, [SimpleITK](https://github.com/SimpleITK/SimpleITK.git), which is written in
C++, is used. An adapter library is created to expose the required functionality in SimpleITK
in a shared library. Because of this, compilation of this crate requires quite some time, as
wel as cmake.
C++, is used. An adapter library is created using [autocxx](https://crates.io/crates/autocxx)
to expose the required functionality in SimpleITK. Because of this, compilation of this crate
requires quite some time, several GB of memory, up to 50 GB of hard disk space, as well as
cmake, a C++ compiler, llvm and git. Use at your own risk!
## Examples
### Registration
```
let image_a = (some Array2);
let iameg_b = (some transformed Array2);
let transform = Transform::register_affine(image_a.view(), image_b.view())?;
println!("transform: {:#?}", transform);
use ndarray::Array2;
use sitk_registration_sys::registration::{AffineTransform, julia_image};
let j = julia_image(0f32, 0f32).unwrap();
let shape = j.shape();
let origin = [
((shape[1] - 1) as f64) / 2f64,
((shape[0] - 1) as f64) / 2f64,
];
let s = AffineTransform::new([1.2, 0., 0., 1., 5., 7.], origin, [shape[0], shape[1]]);
let k: Array2<_> = s.transform_image_bspline(j.view()).unwrap().into();
let t = AffineTransform::register_affine(j.view(), k.view()).unwrap().inverse().unwrap();
let d = (t.matrix() - s.matrix()).powi(2).sum();
assert!(d < 0.025, "d: {}, t: {:?}", d, t.parameters);
```
### Interpolation
```
let image = (Some Array2);
let shape = image.shape();
let origin = [
((shape[1] - 1) as f64) / 2f64,
((shape[0] - 1) as f64) / 2f64,
];
let transform = Transform::new([1.2, 0., 0., 1., 10., 0.], origin, [shape[0], shape[1]]);
let transformed_image = transform.transform_image_bspline(image.view())?;
```
use ndarray::Array2;
use sitk_registration_sys::registration::{AffineTransform, julia_image};
let j = julia_image(-120f32, 10f32).unwrap();
let k = julia_image(0f32, 0f32).unwrap();
let shape = j.shape();
let origin = [
((shape[1] - 1) as f64) / 2f64,
((shape[0] - 1) as f64) / 2f64,
];
let transform = AffineTransform::new([1., 0., 0., 1., 120., -10.], origin, [shape[0], shape[1]]);
let n: Array2<_> = transform.transform_image_bspline(j.view()).unwrap().into();
let d = (k.mapv(|x| x as f64) - n.mapv(|x| x as f64)).powi(2).sum();
assert!(d <= (shape[0] * shape[1]) as f64);
```