Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
OpenWalnut
OpenWalnut Core
Commits
8a1e16a9
Commit
8a1e16a9
authored
Sep 24, 2010
by
Mathias Goldau
Browse files
[ADD] New simple tract resampler prepared...
parent
d5917a47
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
354 additions
and
0 deletions
+354
-0
src/modules/fiberResampling/WSimpleResampler.cpp
src/modules/fiberResampling/WSimpleResampler.cpp
+92
-0
src/modules/fiberResampling/WSimpleResampler.h
src/modules/fiberResampling/WSimpleResampler.h
+94
-0
src/modules/fiberResampling/test/WSimpleResampler_test.h
src/modules/fiberResampling/test/WSimpleResampler_test.h
+167
-0
src/modules/modules-others.toolbox
src/modules/modules-others.toolbox
+1
-0
No files found.
src/modules/fiberResampling/WSimpleResampler.cpp
0 → 100644
View file @
8a1e16a9
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include "../../common/math/WPosition.h"
#include "WSimpleResampler.h"
WSimpleResampler
::
WSimpleResampler
(
size_t
numSamples
)
:
m_numSamples
(
numSamples
)
{
}
void
WSimpleResampler
::
resample
(
boost
::
shared_ptr
<
const
std
::
vector
<
double
>
>
verts
,
const
size_t
startIdx
,
const
size_t
length
,
boost
::
shared_ptr
<
std
::
vector
<
double
>
>
newVerts
,
const
size_t
newStartIdx
)
const
{
if
(
length
!=
m_numSamples
&&
length
>
0
&&
m_numSamples
>
0
)
{
// 1. compute length of tract
// 2. compute new segment length
// 3. walk along the tract and make every new segment length a new sample point.
// 4. YES I know that this does not result in perfect equidistant
// sample points, but thats exactly the reason why this algo has the
// SIMPLE in its name :P
const
double
pathLength
=
lineIntegration
(
verts
,
startIdx
,
length
);
const
double
newSegmentLength
=
pathLength
/
(
m_numSamples
-
1
);
double
remainingLength
=
0.0
;
(
*
newVerts
)[
newStartIdx
*
3
]
=
(
*
verts
)[
startIdx
*
3
];
(
*
newVerts
)[
newStartIdx
*
3
+
1
]
=
(
*
verts
)[
startIdx
*
3
+
1
];
(
*
newVerts
)[
newStartIdx
*
3
+
2
]
=
(
*
verts
)[
startIdx
*
3
+
2
];
for
(
size_t
i
=
startIdx
*
3
,
j
=
(
newStartIdx
+
1
)
*
3
;
i
<
(
startIdx
+
length
-
1
)
*
3
;
i
+=
3
)
{
wmath
::
WPosition
current
(
(
*
verts
)[
i
],
(
*
verts
)[
i
+
1
],
(
*
verts
)[
i
+
2
]
);
wmath
::
WPosition
next
(
(
*
verts
)[
i
+
3
],
(
*
verts
)[
i
+
4
],
(
*
verts
)[
i
+
5
]
);
remainingLength
+=
(
current
-
next
).
norm
();
while
(
remainingLength
>
newSegmentLength
)
{
remainingLength
-=
newSegmentLength
;
wmath
::
WPosition
newPoint
=
next
+
remainingLength
*
(
current
-
next
).
normalized
();
(
*
newVerts
)[
j
]
=
newPoint
[
0
];
(
*
newVerts
)[
j
+
1
]
=
newPoint
[
1
];
(
*
newVerts
)[
j
+
2
]
=
newPoint
[
2
];
j
+=
3
;
}
}
}
}
double
WSimpleResampler
::
lineIntegration
(
boost
::
shared_ptr
<
const
std
::
vector
<
double
>
>
verts
,
const
size_t
startIdx
,
const
size_t
length
)
const
{
double
result
=
0.0
;
size_t
start
=
startIdx
*
3
;
wmath
::
WPosition
last
(
(
*
verts
)[
start
],
(
*
verts
)[
start
+
1
],
(
*
verts
)[
start
+
2
]
);
for
(
size_t
i
=
startIdx
*
3
;
i
<
(
startIdx
+
length
-
1
)
*
3
;
i
+=
3
)
{
wmath
::
WPosition
current
(
(
*
verts
)[
i
],
(
*
verts
)[
i
+
1
],
(
*
verts
)[
i
+
2
]
);
wmath
::
WPosition
next
(
(
*
verts
)[
i
+
3
],
(
*
verts
)[
i
+
4
],
(
*
verts
)[
i
+
5
]
);
result
+=
(
current
-
next
).
norm
();
}
return
result
;
}
src/modules/fiberResampling/WSimpleResampler.h
0 → 100644
View file @
8a1e16a9
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WSIMPLERESAMPLER_H
#define WSIMPLERESAMPLER_H
#include <vector>
#include <boost/shared_ptr.hpp>
/**
* Algorithm to resample a single tract into almost equidistant segments.
*
* \note Since this is a SIMPLE resampler, it measures along the given tract or
* curve an equidistant width, and places its sample points at each segment
* end. This clearly leads to shorter segments incase of strong curvature
* (which is taken to measure the segments) replaced by a straight segment line
* which may be shorter then.
*/
class
WSimpleResampler
{
friend
class
WSimpleResamplerTest
;
public:
/**
* Constructs a new Sampling instance for a given number of sample points.
*
* \param numSamples The new number of sample points.
*/
explicit
WSimpleResampler
(
size_t
numSamples
);
/**
* Resamples a tract (given via <em>verts, startIdx</em> and \e length) to
* the number of samples points given in the constructor of this instance.
*
* \param verts Pointer to the original vertices array
*
* \param startIdx Start position of the first vertex.
*
* \param length The number of VERTICES (not components nor doubles) the
* tract is about.
*
* \param newVerts The place where to save the new sample points. Since all
* new tracts will have the same length the start index can be derived from
* startIdx.
*
* \param newStartIdx The new offset where to write the new sample points.
* This is also a direct component or double index (as startIdx is) but not
* a vertex index.
*
* \note The only reason for the fourth argument is that the memory can be
* allocated before the sampling takes places which could lead to
* performance losses when multithreading and dynamic allocation comes into
* play.
*/
void
resample
(
boost
::
shared_ptr
<
const
std
::
vector
<
double
>
>
verts
,
const
size_t
startIdx
,
const
size_t
length
,
boost
::
shared_ptr
<
std
::
vector
<
double
>
>
newVerts
,
const
size_t
newStartIdx
)
const
;
protected:
double
lineIntegration
(
boost
::
shared_ptr
<
const
std
::
vector
<
double
>
>
verts
,
const
size_t
startIdx
,
const
size_t
length
)
const
;
private:
/**
* The new number of points where each given tract is sampled to.
*/
size_t
m_numSamples
;
};
#endif // WSIMPLERESAMPLER_H
src/modules/fiberResampling/test/WSimpleResampler_test.h
0 → 100644
View file @
8a1e16a9
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WSIMPLERESAMPLER_TEST_H
#define WSIMPLERESAMPLER_TEST_H
#include <sstream>
#include <vector>
#include <cxxtest/TestSuite.h>
#include "../WSimpleResampler.h"
/**
* Testsuite for the simple resample method.
*/
class
WSimpleResamplerTest
:
public
CxxTest
::
TestSuite
{
public:
/**
* The line integrator sum's up all segment's length''''ssss. Damn I never
* know when to set the apostroph''ss...
*/
void
testLineIntegration
(
void
)
{
WSimpleResampler
r
(
0
);
TS_ASSERT_EQUALS
(
r
.
lineIntegration
(
m_equiTractVerts
,
m_startIdx
,
m_length
),
std
::
sqrt
(
3.0
)
*
4.0
);
}
/**
* If there is the same number of sample points given then the tract should
* be resampled equidistantly into \c n-1 segments when having \c n new
* sample points.
*/
void
testResamplingWithGivenNumberOfNewSamplePoints
(
void
)
{
WSimpleResampler
r
(
3
);
boost
::
shared_ptr
<
std
::
vector
<
double
>
>
newTractVerts
(
new
std
::
vector
<
double
>
(
9
*
3
,
-
1.0
)
);
r
.
resample
(
m_equiTractVerts
,
m_startIdx
,
m_length
,
newTractVerts
,
3
);
double
verts
[]
=
{
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
// NOLINT
0.0
,
0.0
,
0.0
,
2.0
,
2.0
,
2.0
,
4.0
,
4.0
,
4.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
};
// NOLINT
std
::
vector
<
double
>
expected
(
verts
,
verts
+
sizeof
(
verts
)
/
sizeof
(
double
)
);
TS_ASSERT_EQUALS
(
expected
.
size
(),
newTractVerts
->
size
()
);
for
(
size_t
i
=
0
;
i
<
expected
.
size
();
++
i
)
{
if
(
std
::
abs
(
expected
[
i
]
-
(
*
newTractVerts
)[
i
]
)
>
1.0e-10
)
{
std
::
stringstream
ss
;
ss
<<
"Positions differ in index: "
<<
i
<<
" with expected: "
<<
expected
[
i
]
<<
" but got "
<<
(
*
newTractVerts
)[
i
];
TS_FAIL
(
ss
.
str
()
);
}
}
}
// /**
// * When a given new segment length is given, resample the fiber in segments
// * of this length, the last segment may be not that length.
// * TODO(math): please talk to sebastian, if that really makes sense??
// */
// void testResampleWithGivenSegmentLength( void )
// {
// }
/**
* If the tract is not equidistant sampled than this should work:
* TODO(math): describe the drawbacks of the simple resampler
*/
void
testResamplingOnNonEquidistantTract
(
void
)
{
}
/**
* The resampling should also work with equidistant sampled tracts.
*/
void
testResamplingOnEquidistantTract
(
void
)
{
}
/**
* Prepares two single fibers, one which is equidistant sampled and one
* which is not. Also the vertex array is simulated, as well as start index
* and length.
*/
void
setUp
(
void
)
{
double
vertsE
[]
=
{
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
// NOLINT array init list
0.0
,
0.0
,
0.0
,
1.0
,
1.0
,
1.0
,
2.0
,
2.0
,
2.0
,
3.0
,
3.0
,
3.0
,
4.0
,
4.0
,
4.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
};
// NOLINT array init list
m_equiTractVerts
=
boost
::
shared_ptr
<
std
::
vector
<
double
>
>
(
new
std
::
vector
<
double
>
(
vertsE
,
vertsE
+
sizeof
(
vertsE
)
/
sizeof
(
double
)
)
);
// NOLINT long line
m_startIdx
=
5
;
m_length
=
5
;
double
vertsNE
[]
=
{
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
// NOLINT array init list
0.75
,
0.0
,
0.0
,
0.8
,
0.9
,
0.0
,
1.0
,
1.0
,
0.0
,
1.2
,
0.9
,
0.0
,
1.25
,
0.0
,
0.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
};
// NOLINT array init list
m_nonEquiTractVerts
=
boost
::
shared_ptr
<
std
::
vector
<
double
>
>
(
new
std
::
vector
<
double
>
(
vertsNE
,
vertsNE
+
sizeof
(
vertsNE
)
/
sizeof
(
double
)
)
);
// NOLINT long line
}
/**
* We do not need to remove the arrays since the are not allocated via the
* NEW operator. But we should clear the vectors and reset the indices.
*/
void
tearDown
(
void
)
{
m_equiTractVerts
->
clear
();
m_nonEquiTractVerts
->
clear
();
m_startIdx
=
0
;
m_length
=
0
;
}
private:
/**
* Simulates a vertex array of equidistant sampled tracts as you will have
* with WDataSetFibers.
*/
boost
::
shared_ptr
<
std
::
vector
<
double
>
>
m_equiTractVerts
;
/**
* Simulates a vertex array of non equidistant sampled tracts as you maybe
* will have with WDataSetFibers.
*/
boost
::
shared_ptr
<
std
::
vector
<
double
>
>
m_nonEquiTractVerts
;
/**
* Simulates the start index of the a tract inside of the vertex array.
*/
size_t
m_startIdx
;
/**
* Simulates the length of the tract inside of the vertex array.
*/
size_t
m_length
;
};
#endif // WSIMPLERESAMPLER_TEST_H
src/modules/modules-others.toolbox
View file @
8a1e16a9
...
...
@@ -14,6 +14,7 @@ ADD_SUBDIRECTORY( effectiveConnectivityCluster )
ADD_SUBDIRECTORY( fiberDisplaySimple )
ADD_SUBDIRECTORY( fiberSelection )
ADD_SUBDIRECTORY( fiberTransform )
ADD_SUBDIRECTORY( fiberResampling )
ADD_SUBDIRECTORY( imageExtractor )
ADD_SUBDIRECTORY( lineGuidedSlice )
ADD_SUBDIRECTORY( probTractDisplay )
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment