# HG changeset patch # User Benjamin Golinvaux # Date 1613124547 -3600 # Node ID 730604db88b83df355c142931e1006c42b8a0cca # Parent 4bedae500652c4b374ba5deb2dafc6eabafa00ab# Parent 9b69970fbdb55d9a71d96a7a7090aad74053d847 merge diff -r 9b69970fbdb5 -r 730604db88b8 .hgignore --- a/.hgignore Fri Feb 12 09:46:01 2021 +0100 +++ b/.hgignore Fri Feb 12 11:09:07 2021 +0100 @@ -6,36 +6,24 @@ .vscode/ build*/ CMakeLists.txt.user -OrthancStone/Deprecated/Resources/CodeGeneration/.env -OrthancStone/Deprecated/Resources/CodeGeneration/.idea -OrthancStone/Deprecated/Resources/CodeGeneration/__pycache__ -OrthancStone/Deprecated/Resources/CodeGeneration/build/ -OrthancStone/Deprecated/Resources/CodeGeneration/build_browser/ -OrthancStone/Deprecated/Resources/CodeGeneration/testCppHandler/build/ -OrthancStone/Deprecated/Resources/CodeGeneration/testCppHandler/build_msbuild/ -OrthancStone/Deprecated/Resources/CodeGeneration/testWasmIntegrated/build-final/ -OrthancStone/Deprecated/Resources/CodeGeneration/testWasmIntegrated/build-tsc/ -OrthancStone/Deprecated/Resources/CodeGeneration/testWasmIntegrated/build-wasm/ -OrthancStone/Samples/RtViewerPlugin/*/ThirdPartyDownloads/ -OrthancStone/Samples/RtViewerPlugin/ThirdPartyDownloads/ -OrthancStone/Samples/WebAssembly/*/ThirdPartyDownloads/ -OrthancStone/Samples/WebAssembly/ThirdPartyDownloads/ -OrthancStone/Samples/WebAssembly/*/out -OrthancStone/Samples/Sdl/*/ThirdPartyDownloads/ -OrthancStone/Samples/Sdl/ThirdPartyDownloads/ -OrthancStone/Samples/Sdl/*/out -OrthancStone/Samples/Sdl/build*/ -OrthancStone/Samples/Deprecated/Sdl/ThirdPartyDownloads/ -OrthancStone/Samples/Deprecated/Sdl/CMakeLists.txt.orig -OrthancStone/Samples/Deprecated/Qt/ThirdPartyDownloads/ -OrthancStone/Samples/Deprecated/WebAssembly/build/ -OrthancStone/Samples/Deprecated/WebAssembly/ThirdPartyDownloads/ -OrthancStone/Samples/Deprecated/WebAssembly/installDir/ +Applications/Samples/RtViewerPlugin/*/ThirdPartyDownloads/ +Applications/Samples/RtViewerPlugin/ThirdPartyDownloads/ +Applications/Samples/WebAssembly/*/ThirdPartyDownloads/ +Applications/Samples/WebAssembly/ThirdPartyDownloads/ +Applications/Samples/WebAssembly/*/out +Applications/Samples/Sdl/*/ThirdPartyDownloads/ +Applications/Samples/Sdl/ThirdPartyDownloads/ +Applications/Samples/Sdl/*/out +Applications/Samples/Sdl/build*/ +Applications/Samples/Deprecated/Sdl/ThirdPartyDownloads/ +Applications/Samples/Deprecated/Sdl/CMakeLists.txt.orig +Applications/Samples/Deprecated/Qt/ThirdPartyDownloads/ +Applications/Samples/Deprecated/WebAssembly/build/ +Applications/Samples/Deprecated/WebAssembly/ThirdPartyDownloads/ +Applications/Samples/Deprecated/WebAssembly/installDir/ StoneWebViewer/Plugin/ThirdPartyDownloads/ StoneWebViewer/WebAssembly/ThirdPartyDownloads/ UnitTestsSources/ThirdPartyDownloads/ node_modules/ wasm-binaries/ out/ - - diff -r 9b69970fbdb5 -r 730604db88b8 OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp --- a/OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp Fri Feb 12 09:46:01 2021 +0100 +++ b/OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp Fri Feb 12 11:09:07 2021 +0100 @@ -48,7 +48,8 @@ { Orthanc::Toolbox::ToUpperCase(increment); - // This is the "Grid Frame Offset Vector" tag (DICOM_TAG_GRID_FRAME_OFFSET_VECTOR) + // We only support volumes where the FrameIncrementPointer (0028,0009) (required) contains + // the "Grid Frame Offset Vector" tag (DICOM_TAG_GRID_FRAME_OFFSET_VECTOR) if (increment != "3004,000C") { LOG(WARNING) << "Bad value for the FrameIncrementPointer tags in a multiframe image"; @@ -60,7 +61,7 @@ if (!LinearAlgebra::ParseVector(target, dicom, Orthanc::DICOM_TAG_GRID_FRAME_OFFSET_VECTOR) || target.size() != numberOfFrames) { - LOG(INFO) << "The frame offset information is missing in a multiframe image"; + LOG(ERROR) << "The frame offset information (GridFrameOffsetVector (3004,000C)) is missing in a multiframe image"; // DO NOT use ".clear()" here, as the "Vector" class doesn't behave like std::vector! target.resize(0); @@ -109,9 +110,13 @@ height_ = 0; } + + bool sliceThicknessPresent = true; if (!dicom.ParseDouble(sliceThickness_, Orthanc::DICOM_TAG_SLICE_THICKNESS)) { + LOG(INFO) << "The (non-madatory) slice thickness information is missing in a multiframe image"; sliceThickness_ = 100.0 * std::numeric_limits::epsilon(); + sliceThicknessPresent = false; } GeometryToolbox::GetPixelSpacing(pixelSpacingX_, pixelSpacingY_, dicom); @@ -127,6 +132,42 @@ if (numberOfFrames_ > 1) { ExtractFrameOffsets(frameOffsets_, dicom, numberOfFrames_); + + // if the slice thickness is unknown, we try to infer it from the sequence of grid frame offsets + // this only works if: + // - the first offset is 0.0 (case (a) of http://dicom.nema.org/medical/Dicom/2017c/output/chtml/part03/sect_C.8.8.3.2.html) + // - the offsets are all equal, to some small tolerance + // - the offsets is positive (increasing throughout the frames) + if (!sliceThicknessPresent) + { + if (frameOffsets_.size() >= 2) + { + double sliceThickness = frameOffsets_[1] - frameOffsets_[0]; + bool sameSized = true; + if (sliceThickness > 0) + { + for (size_t i = 2; i < frameOffsets_.size(); ++i) + { + double currentThickness = frameOffsets_[i] - frameOffsets_[i-1]; + if (!LinearAlgebra::IsNear(sliceThickness, currentThickness)) + { + LOG(ERROR) << "Unable to extract slice thickness from GridFrameOffsetVector (3004,000C) (reason: varying spacing)"; + sameSized = false; + break; + } + } + if (sameSized) + { + sliceThickness_ = sliceThickness; + LOG(INFO) << "SliceThickness was not specified in the Dicom but was inferred from GridFrameOffsetVector (3004,000C)."; + } + } + } + else + { + LOG(ERROR) << "Unable to extract slice thickness from GridFrameOffsetVector (3004,000C) (reason: GridFrameOffsetVector not present or too small)"; + } + } } else {