| 83 | } |
| 84 | |
| 85 | double |
| 86 | mitk::SortByImagePositionPatient |
| 87 | ::InternalNumericDistance(const mitk::DICOMDatasetAccess* left, const mitk::DICOMDatasetAccess* right, bool& possible) const |
| 88 | { |
| 89 | // sort by distance to world origin, assuming (almost) equal orientation |
| 90 | static const DICOMTag tagImagePositionPatient = DICOMTag(0x0020,0x0032); // Image Position (Patient) |
| 91 | static const DICOMTag tagImageOrientation = DICOMTag(0x0020, 0x0037); // Image Orientation |
| 92 | |
| 93 | Vector3D leftRight; leftRight.Fill(0.0); |
| 94 | Vector3D leftUp; leftUp.Fill(0.0); |
| 95 | bool leftHasOrientation(false); |
| 96 | DICOMStringToOrientationVectors( left->GetTagValueAsString( tagImageOrientation ).value, |
| 97 | leftRight, leftUp, leftHasOrientation ); |
| 98 | |
| 99 | Vector3D rightRight; rightRight.Fill(0.0); |
| 100 | Vector3D rightUp; rightUp.Fill(0.0); |
| 101 | bool rightHasOrientation(false); |
| 102 | DICOMStringToOrientationVectors(right->GetTagValueAsString(tagImageOrientation).value, |
| 103 | rightRight, rightUp, rightHasOrientation ); |
| 104 | |
| 105 | Point3D leftOrigin; leftOrigin.Fill(0.0f); |
| 106 | bool leftHasOrigin(false); |
| 107 | leftOrigin = DICOMStringToPoint3D(left->GetTagValueAsString(tagImagePositionPatient).value, leftHasOrigin); |
| 108 | |
| 109 | Point3D rightOrigin; rightOrigin.Fill(0.0f); |
| 110 | bool rightHasOrigin(false); |
| 111 | rightOrigin = DICOMStringToPoint3D(right->GetTagValueAsString(tagImagePositionPatient).value, rightHasOrigin); |
| 112 | |
| 113 | // we tolerate very small differences in image orientation, since we got to know about |
| 114 | // acquisitions where these values change across a single series (7th decimal digit) |
| 115 | // (https://phabricator.mitk.org/T12263) |
| 116 | // still, we want to check if our assumption of 'almost equal' orientations is valid |
| 117 | for (unsigned int dim = 0; dim < 3; ++dim) |
| 118 | { |
| 119 | if ( fabs(leftRight[dim] - rightRight[dim]) > 0.0001 |
| 120 | || fabs(leftUp[dim] - rightUp[dim]) > 0.0001) |
| 121 | { |
| 122 | MITK_ERROR << "Dicom images have different orientations."; |
| 123 | throw std::logic_error("Dicom images have different orientations. Call GetSeries() first to separate images."); |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | Vector3D normal; |
| 128 | normal[0] = leftRight[1] * leftUp[2] - leftRight[2] * leftUp[1]; |
| 129 | normal[1] = leftRight[2] * leftUp[0] - leftRight[0] * leftUp[2]; |
| 130 | normal[2] = leftRight[0] * leftUp[1] - leftRight[1] * leftUp[0]; |
| 131 | |
| 132 | double leftDistance = 0.0; |
| 133 | double rightDistance = 0.0; |
| 134 | |
| 135 | // this computes the distance from world origin (0,0,0) ALONG THE NORMAL of the image planes |
| 136 | for (unsigned int dim = 0; dim < 3; ++dim) |
| 137 | { |
| 138 | leftDistance += normal[dim] * leftOrigin[dim]; |
| 139 | rightDistance += normal[dim] * rightOrigin[dim]; |
| 140 | } |
| 141 | |
| 142 | // if we can sort by just comparing the distance, we do exactly that |
nothing calls this directly
no test coverage detected