Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrapper for displacement field #111

Merged
merged 27 commits into from
Nov 1, 2019
Merged
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6647251
WIP: Abstracting away the displacement field to allow composite trans…
simeks Oct 28, 2019
e598ea8
Less template arguments
simeks Oct 29, 2019
ddb8051
Test
simeks Oct 29, 2019
4715584
Nope
simeks Oct 29, 2019
efaf985
Update STK
simeks Oct 29, 2019
b948ad1
WIP: DisplacementField class
simeks Oct 29, 2019
7606857
Update STK
simeks Oct 29, 2019
8bac21c
Update STK
simeks Oct 29, 2019
7017e5c
Transform
simeks Oct 29, 2019
f734b4d
Update STK
simeks Oct 29, 2019
7642e39
WIP: DisplacementField class for GPU
simeks Oct 29, 2019
48e9837
Last details
simeks Oct 30, 2019
3cd3396
DisplacementField class for GPU
simeks Oct 30, 2019
ccd808e
Small fixes to cost function kernel
simeks Oct 30, 2019
c3e3576
Fixes
simeks Oct 30, 2019
cc2ad9f
Initialize displacement field
simeks Oct 30, 2019
ef51c05
Merge branch 'displacement-field' of https://github.com/simeks/deform…
simeks Oct 30, 2019
ea27bcc
Update STK
simeks Oct 30, 2019
b057297
A lot of small fixes
simeks Oct 30, 2019
e908d06
Fixed bug where delta wasn't applied properly
simeks Oct 31, 2019
993298b
Bugfix
simeks Oct 31, 2019
c1504b4
Fix
simeks Oct 31, 2019
fddb4b5
Temporary fix for the update problem
simeks Oct 31, 2019
605090d
Refactored the registration loop to mirror the GPU loop
simeks Nov 1, 2019
55e7f3c
Buffering displacement field for composition
simeks Nov 1, 2019
cbde172
Loop change lowered the precision in tests
simeks Nov 1, 2019
5399032
Merge branch 'displacement-field' of https://github.com/simeks/deform…
simeks Nov 1, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
WIP: DisplacementField class
simeks committed Oct 29, 2019
commit b948ad1e975a9de2320fcc9b6a323fe6f59d7254
3 changes: 1 addition & 2 deletions src/deform_lib/registration/blocked_graph_cut_optimizer.inl
Original file line number Diff line number Diff line change
@@ -76,8 +76,7 @@ void BlockedGraphCutOptimizer<TUnaryTerm, TBinaryTerm, TSolver>
if (_max_iteration_count != -1 && num_iterations >= _max_iteration_count)
break;

// TODO: !!!!!
unary_fn.pre_iteration_hook(num_iterations, df.volume());
unary_fn.pre_iteration_hook(num_iterations, df);

done = true;

Original file line number Diff line number Diff line change
@@ -401,12 +401,12 @@ struct MIFunction : public SubFunction
* entropy of the moving image and the joint entropy after each
* iteration.
*/
virtual void pre_iteration_hook(const int iteration, const stk::VolumeFloat3& def)
virtual void pre_iteration_hook(const int iteration, const DisplacementField& df)
{
if (0 == iteration || 0 == _update_interval || iteration % _update_interval) {
return;
}
auto tmp = transform_volume(_moving, def, _interpolator);
auto tmp = transform_volume(_moving, df, _interpolator);
_joint_entropy.update(_fixed, tmp);
_entropy.update(tmp);
}
6 changes: 4 additions & 2 deletions src/deform_lib/registration/cost_functions/sub_function.h
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@

#include <limits>

class DisplacementField;

struct SubFunction
{
virtual ~SubFunction() {}
@@ -23,10 +25,10 @@ struct SubFunction
* \param iteration Number of the iteration just completed.
* \param def Deformation field at the end of the iteration.
*/
virtual void pre_iteration_hook(const int iteration, const stk::VolumeFloat3& def)
virtual void pre_iteration_hook(const int iteration, const DisplacementField& df)
{
(void) iteration;
(void) def;
(void) df;
}

/*!
4 changes: 2 additions & 2 deletions src/deform_lib/registration/cost_functions/unary_function.h
Original file line number Diff line number Diff line change
@@ -41,10 +41,10 @@ struct UnaryFunction
return mask_value * sum;
}

void pre_iteration_hook(const int iteration, const stk::VolumeFloat3& def)
void pre_iteration_hook(const int iteration, const DisplacementField& df)
{
for (auto& fn : _functions) {
fn.function->pre_iteration_hook(iteration, def);
fn.function->pre_iteration_hook(iteration, df);
}
}

33 changes: 29 additions & 4 deletions src/deform_lib/registration/displacement_field.h
Original file line number Diff line number Diff line change
@@ -9,22 +9,22 @@ class DisplacementField
{
public:
DisplacementField(
Settings::UpdateRule update_rule,
const stk::VolumeFloat3& df
const stk::VolumeFloat3& df,
Settings::UpdateRule update_rule = Settings::UpdateRule_Additive
) :
_update_rule(update_rule),
_df(df)
{
}
~DisplacementField() {}

inline float3 get(const int3& p)
inline float3 get(const int3& p) const
{
return _df(p);
}

// delta : Delta in world space (mm)
inline float3 get(const int3& p, const float3& delta)
inline float3 get(const int3& p, const float3& delta) const
{
if (_update_rule == Settings::UpdateRule_Compositive) {
// Convert delta to fixed image space
@@ -52,6 +52,13 @@ class DisplacementField
_df(p) = get(p, delta);
}

// p : Index in displacement field
// Returns coordinates in world space
inline float3 transform_index(const int3& p)
{
return _df.index2point(p) + get(p);
}

dim3 size() const
{
return _df.size();
@@ -63,6 +70,24 @@ class DisplacementField
return _df;
}

inline const float3& operator()(int x, int y, int z) const
{
return _df(p);
}
inline float3& operator()(int x, int y, int z)
{
return _df(p);
}

inline const float3& operator()(const int3& p) const
{
return _df(p);
}
inline float3& operator()(const int3& p)
{
return _df(p);
}

private:
Settings::UpdateRule _update_rule;
stk::VolumeFloat3 _df;
2 changes: 1 addition & 1 deletion src/deform_lib/registration/registration_engine.cpp
Original file line number Diff line number Diff line change
@@ -618,7 +618,7 @@ stk::Volume RegistrationEngine::execute()
#endif

for (int l = _settings.num_pyramid_levels-1; l >= 0; --l) {
DisplacementField df(_settings.update_rule, _deformation_pyramid.volume(l));
DisplacementField df(_deformation_pyramid.volume(l), _settings.update_rule);

std::vector<int3> neighborhood = determine_neighborhood(l);

52 changes: 29 additions & 23 deletions src/deform_lib/registration/transform.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "displacement_field.h"
#include "transform.h"

#include <stk/common/log.h>
@@ -8,7 +9,7 @@ namespace
template<typename TVoxelType>
stk::VolumeHelper<TVoxelType> transform_volume_nn(
const stk::VolumeHelper<TVoxelType>& src,
const stk::VolumeFloat3& def)
const DisplacementField& df)
{
// Transformed volume will have the same dimensions and properties (origin and spacing)
// as the deformation field and not the source image. The deformation field is inherited
@@ -18,28 +19,28 @@ namespace
// There should be no requirements on src to have the same size, spacing and origin as
// the fixed image.

dim3 dims = def.size();
dim3 dims = df.size();

stk::VolumeHelper<TVoxelType> out(dims);
out.copy_meta_from(def);
out.copy_meta_from(df);

#define FAST_ROUND(x_) int(x_+0.5f)

#pragma omp parallel for
for (int z = 0; z < int(dims.z); ++z) {
for (int y = 0; y < int(dims.y); ++y) {
for (int x = 0; x < int(dims.x); ++x) {
// [fixed] -> [world] -> [moving]
const float3 moving_p = src.point2index(def.index2point(int3({x, y, z})) + def(x, y, z));

out(x, y, z) = src.at(
int(FAST_ROUND(moving_p.x)),
int(FAST_ROUND(moving_p.y)),
int(FAST_ROUND(moving_p.z)),
stk::Border_Constant
);
}
}
for (int y = 0; y < int(dims.y); ++y) {
for (int x = 0; x < int(dims.x); ++x) {
// [fixed] -> [world] -> [moving]
const float3 moving_p = src.point2index(df.transform_index(int3{x,y,z});

out(x, y, z) = src.at(
int(FAST_ROUND(moving_p.x)),
int(FAST_ROUND(moving_p.y)),
int(FAST_ROUND(moving_p.z)),
stk::Border_Constant
);
}
}
}
#undef FAST_ROUND

@@ -49,7 +50,7 @@ namespace
template<typename TVoxelType>
stk::VolumeHelper<TVoxelType> transform_volume_linear(
const stk::VolumeHelper<TVoxelType>& src,
const stk::VolumeFloat3& def)
const DisplacementField& df)
{
// Transformed volume will have the same dimensions and properties (origin and spacing)
// as the deformation field and not the source image. The deformation field is inherited
@@ -77,28 +78,28 @@ namespace
}
}

stk::Volume transform_volume(const stk::Volume& src, const stk::VolumeFloat3& def, transform::Interp interp)
stk::Volume transform_volume(const stk::Volume& src, const DisplacementField& df, transform::Interp interp)
{
if (interp == transform::Interp_NN) {
if (src.voxel_type() == stk::Type_Float) {
return transform_volume_nn<float>(src, def);
return transform_volume_nn<float>(src, df);
}
else if (src.voxel_type() == stk::Type_Double) {
return transform_volume_nn<double>(src, def);
return transform_volume_nn<double>(src, df);
}
else if (src.voxel_type() == stk::Type_UChar) {
return transform_volume_nn<uint8_t>(src, def);
return transform_volume_nn<uint8_t>(src, df);
}
else {
LOG(Error) << "transform_volume: Unsupported volume type (type: " << src.voxel_type() << ")";
}
}
else if (interp == transform::Interp_Linear) {
if (src.voxel_type() == stk::Type_Float) {
return transform_volume_linear<float>(src, def);
return transform_volume_linear<float>(src, df);
}
else if (src.voxel_type() == stk::Type_Double) {
return transform_volume_linear<double>(src, def);
return transform_volume_linear<double>(src, df);
}
else {
LOG(Error) << "transform_volume: Unsupported volume type (type: " << src.voxel_type() << ")";
@@ -109,3 +110,8 @@ stk::Volume transform_volume(const stk::Volume& src, const stk::VolumeFloat3& de
}
return stk::Volume();
}

stk::Volume transform_volume(const stk::Volume& src, const stk::VolumeFloat3& df, transform::Interp interp)
{
return transform_volume(src, DisplacementField(df), interp);
}
10 changes: 9 additions & 1 deletion src/deform_lib/registration/transform.h
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@

#include <stk/image/volume.h>

class DisplacementField;

namespace transform
{
enum Interp : uint8_t
@@ -13,6 +15,12 @@ namespace transform

stk::Volume transform_volume(
const stk::Volume& src,
const stk::VolumeFloat3& def,
const DisplacementField& df,
transform::Interp i = transform::Interp_Linear
);

stk::Volume transform_volume(
const stk::Volume& src,
const stk::VolumeFloat3& df,
transform::Interp i = transform::Interp_Linear
);