ITK  6.0.0 Insight Toolkit
SphinxExamples/src/Filtering/MathematicalMorphology/GenerateStructureElementsWithAccurateArea/Code.cxx
/*=========================================================================
*
*
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
*
*=========================================================================*/
// Helper function
template <class SEType>
bool
ComputeAreaError(SEType k, unsigned int thickness = 0);
int
main()
{
int scalarThickness = 2;
SE2Type k2;
std::cout << "2D ball of radius " << scalarRadius << " with radiusIsParametric mode off:" << std::endl;
k2 = SE2Type::Ball(r2);
ComputeAreaError(k2);
std::cout << "2D ball of radius " << scalarRadius << " with radiusIsParametric mode on:" << std::endl;
ComputeAreaError(k2);
std::cout << "2D annulus of radius " << scalarRadius << " and thickness " << scalarThickness
<< " with radiusIsParametric mode off:" << std::endl;
k2 = SE2Type::Annulus(r2, scalarThickness, false);
ComputeAreaError(k2, scalarThickness);
std::cout << "2D annulus of radius " << scalarRadius << " and thickness " << scalarThickness
<< " with radiusIsParametric mode on:" << std::endl;
k2 = SE2Type::Annulus(r2, scalarThickness, false, radiusIsParametric);
ComputeAreaError(k2, scalarThickness);
SE3Type k3;
std::cout << "3D ball of radius " << scalarRadius << " with radiusIsParametric mode off:" << std::endl;
k3 = SE3Type::Ball(r3);
ComputeAreaError(k3);
std::cout << "3D ball of radius " << scalarRadius << " with radiusIsParametric mode on:" << std::endl;
ComputeAreaError(k3);
std::cout << "3D annulus of radius " << scalarRadius << " and thickness " << scalarThickness
<< " with radiusIsParametric mode off:" << std::endl;
k3 = SE3Type::Annulus(r3, scalarThickness, false);
ComputeAreaError(k3, scalarThickness);
std::cout << "3D annulus of radius " << scalarRadius << " and thickness " << scalarThickness
<< " with radiusIsParametric mode on:" << std::endl;
k3 = SE3Type::Annulus(r3, scalarThickness, false, radiusIsParametric);
ComputeAreaError(k3, scalarThickness);
SE4Type k4;
std::cout << "4D ball of radius " << scalarRadius << " with radiusIsParametric mode off:" << std::endl;
k4 = SE4Type::Ball(r4);
ComputeAreaError(k4);
std::cout << "4D ball of radius " << scalarRadius << " with radiusIsParametric mode on:" << std::endl;
ComputeAreaError(k4);
std::cout << "4D annulus of radius " << scalarRadius << " and thickness " << scalarThickness
<< " with radiusIsParametric mode off:" << std::endl;
k4 = SE4Type::Annulus(r4, scalarThickness, false);
ComputeAreaError(k4, scalarThickness);
std::cout << "4D annulus of radius " << scalarRadius << " and thickness " << scalarThickness
<< " with radiusIsParametric mode on:" << std::endl;
k4 = SE4Type::Annulus(r4, scalarThickness, false, radiusIsParametric);
ComputeAreaError(k4, scalarThickness);
return EXIT_SUCCESS;
}
template <class SEType>
bool
ComputeAreaError(SEType k, unsigned int thickness)
{
float expectedOuterForegroundArea = 1;
float expectedInnerForegroundArea;
if (thickness == 0)
{
// Circle/Ellipse has no inner area to subract.
expectedInnerForegroundArea = 0;
}
else
{
// Annulus does have inner area to subract.
expectedInnerForegroundArea = 1;
}
if (SEType::NeighborhoodDimension == 2)
{
expectedOuterForegroundArea *= itk::Math::pi;
expectedInnerForegroundArea *= itk::Math::pi;
}
else if (SEType::NeighborhoodDimension == 3)
{
expectedOuterForegroundArea *= 4.0 / 3.0 * itk::Math::pi;
expectedInnerForegroundArea *= 4.0 / 3.0 * itk::Math::pi;
}
else if (SEType::NeighborhoodDimension == 4)
{
expectedOuterForegroundArea *= 0.5 * itk::Math::pi * itk::Math::pi;
expectedInnerForegroundArea *= 0.5 * itk::Math::pi * itk::Math::pi;
}
else
{
return EXIT_FAILURE;
}
for (unsigned int i = 0; i < SEType::NeighborhoodDimension; ++i)
{
}
float expectedForegroundArea = expectedOuterForegroundArea - expectedInnerForegroundArea;
// Show the neighborhood if it is 2D.
typename SEType::Iterator SEIt;
if (SEType::NeighborhoodDimension == 2)
{
for (SEIt = k.Begin(); SEIt != k.End(); ++SEIt)
{
std::cout << *SEIt << "\t";
if ((SEIt - k.Begin() + 1) % k.GetSize()[0] == 0)
{
std::cout << std::endl;
}
}
}
// Compute the area/volume.
float computedForegroundArea = 0;
for (SEIt = k.Begin(); SEIt != k.End(); ++SEIt)
{
if (*SEIt)
{
computedForegroundArea++;
}
}
std::cout << "Expected foreground area: " << expectedForegroundArea << std::endl;
std::cout << "Computed foreground area: " << computedForegroundArea << std::endl;
std::cout << "Foreground area error: "
<< 100 * itk::Math::abs(expectedForegroundArea - computedForegroundArea) / expectedForegroundArea << "%"
<< "\n\n";
return EXIT_FAILURE;
}
itk::FlatStructuringElement
A class to support a variety of flat structuring elements, including versions created by decompositio...
Definition: itkKernelImageFilter.h:27
itk::Math::abs
bool abs(bool x)
Definition: itkMath.h:844
itkFlatStructuringElement.h
itk::Math::pi
static constexpr double pi
Definition: itkMath.h:66