1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
/*=========================================================================
Program: GDCM (Grassroots DICOM). A DICOM library
Copyright (c) 2006-2011 Mathieu Malaterre
All rights reserved.
See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "gdcmOrientation.h"
#include <cmath>
namespace gdcm
{
Orientation::Orientation() = default;
Orientation::~Orientation() = default;
void Orientation::Print(std::ostream &os) const
{
os << "ObliquityThresholdCosineValue: " << ObliquityThresholdCosineValue;
}
static const char *OrientationStrings[] = {
"UNKNOWN",
"AXIAL",
"CORONAL",
"SAGITTAL",
"OBLIQUE",
nullptr
};
// http://public.kitware.com/pipermail/insight-users/2005-March/012246.html
// 0.5477 would be the square root of 1 (unit vector sum of squares) divided by 3 (oblique axes - a "double" oblique)
// 0.7071 would be the square root of 1 (unit vector sum of squares) divided by 2 (oblique axes)
double Orientation::ObliquityThresholdCosineValue = 0.8;
//const double Orientation::obliquityThresholdCosineValue = 0.7071;
char Orientation::GetMajorAxisFromPatientRelativeDirectionCosine(double x, double y, double z)
{
char axis = 0;
const char orientationX = x < 0 ? 'R' : 'L';
const char orientationY = y < 0 ? 'A' : 'P';
const char orientationZ = z < 0 ? 'F' : 'H';
const double absX = std::fabs(x);
const double absY = std::fabs(y);
const double absZ = std::fabs(z);
// The tests here really don't need to check the other dimensions,
// just the threshold, since the sum of the squares should be == 1.0
// but just in case ...
if (absX>ObliquityThresholdCosineValue && absX>absY && absX>absZ)
{
axis = orientationX;
}
else if (absY>ObliquityThresholdCosineValue && absY>absX && absY>absZ)
{
axis = orientationY;
}
else if (absZ>ObliquityThresholdCosineValue && absZ>absX && absZ>absY)
{
axis = orientationZ;
}
else
{
// nothing
}
return axis;
}
void Orientation::SetObliquityThresholdCosineValue(double val)
{
Orientation::ObliquityThresholdCosineValue = val;
}
double Orientation::GetObliquityThresholdCosineValue()
{
return Orientation::ObliquityThresholdCosineValue;
}
Orientation::OrientationType Orientation::GetType(const double dircos[6])
{
OrientationType type = Orientation::UNKNOWN;
if( dircos )
{
char rowAxis = GetMajorAxisFromPatientRelativeDirectionCosine(dircos[0],dircos[1],dircos[2]);
char colAxis = GetMajorAxisFromPatientRelativeDirectionCosine(dircos[3],dircos[4],dircos[5]);
if (rowAxis != 0 && colAxis != 0 )
{
if ((rowAxis == 'R' || rowAxis == 'L') && (colAxis == 'A' || colAxis == 'P')) type = Orientation::AXIAL;
else if ((colAxis == 'R' || colAxis == 'L') && (rowAxis == 'A' || rowAxis == 'P')) type = Orientation::AXIAL;
else if ((rowAxis == 'R' || rowAxis == 'L') && (colAxis == 'H' || colAxis == 'F')) type = Orientation::CORONAL;
else if ((colAxis == 'R' || colAxis == 'L') && (rowAxis == 'H' || rowAxis == 'F')) type = Orientation::CORONAL;
else if ((rowAxis == 'A' || rowAxis == 'P') && (colAxis == 'H' || colAxis == 'F')) type = Orientation::SAGITTAL;
else if ((colAxis == 'A' || colAxis == 'P') && (rowAxis == 'H' || rowAxis == 'F')) type = Orientation::SAGITTAL;
}
else
{
type = Orientation::OBLIQUE;
}
}
return type;
}
const char *Orientation::GetLabel(OrientationType type)
{
return OrientationStrings[type];
}
}
|