From 0c256d8c18e897333990befede0de67a21ae8e46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Spaltenstein?= Date: Tue, 30 Jan 2024 00:16:56 +0000 Subject: [PATCH 1/7] work on label maps --- include/dcmqi/OverlapUtil.h | 21 ++++ libsrc/OverlapUtil.cpp | 227 ++++++++++++++++++++++++++---------- 2 files changed, 188 insertions(+), 60 deletions(-) diff --git a/include/dcmqi/OverlapUtil.h b/include/dcmqi/OverlapUtil.h index dcc37a59..a4b58edc 100644 --- a/include/dcmqi/OverlapUtil.h +++ b/include/dcmqi/OverlapUtil.h @@ -93,6 +93,9 @@ class OverlapUtil /// and index 0 is unused. I.e. index i is segment number, value is vector of physical frame numbers. typedef OFVector> FramesForSegment; + // Lists of segments for each frame. Used for Label Maps where each frame can have multiple segments. + typedef OFVector> SegmentsForFrame; + /// Implements comparision operator to be used for sorting of frame positions, /// making the sorting order depend on the coordinate given in the constructor struct ComparePositions @@ -193,6 +196,11 @@ class OverlapUtil */ OFCondition getFramesForSegment(const Uint32 segmentNumber, OFVector& frames); + /** + * TODO + */ + OFCondition getSegmentsForFrame(const Uint32 frameNumber, std::set& segments); + /** Returns computed overlap matrix * @param matrix Resulting overlap matrix * @return EC_Normal if successful, error otherwise @@ -277,6 +285,16 @@ class OverlapUtil */ OFCondition checkFramesOverlap(const Uint32& f1, const Uint32& f2, OFBool& overlap); + /** + * @param sf1 TODO + * @param sf1 TODO + * @param overlap Resulting overlap (overlaps if OFTrue, otherwise not) + * @return EC_Normal if successful, error otherwise + */ + OFCondition checkFramesOverlapLabelMap(const SegNumAndFrameNum& sf1, + const SegNumAndFrameNum& sf2, + OFBool& overlap); + /** Checks whether the given two frames overlap by using comparing their pixel data * by bitwise "and". This is very efficient, however, only works and is called (right now), * if row*cols % 8 = 0, so we can easily extract frames as binary bitsets without unpacking them. @@ -340,6 +358,9 @@ class OverlapUtil /// segment. FramesForSegment m_framesForSegment; + /// Stores which segments are present on each frame. + SegmentsForFrame m_segmentsForFrame; + /// Logical frames, ie. physical frames with the same position are /// grouped together to a logical frame. For every logical frame, we /// store the related physical frame numbers. The logical frame number diff --git a/libsrc/OverlapUtil.cpp b/libsrc/OverlapUtil.cpp index 1fd94cc0..05abb9c2 100644 --- a/libsrc/OverlapUtil.cpp +++ b/libsrc/OverlapUtil.cpp @@ -49,6 +49,7 @@ OverlapUtil::OverlapUtil() : m_imageOrientation() , m_framePositions() , m_framesForSegment() + , m_segmentsForFrame() , m_logicalFramePositions() , m_segmentsByPosition() , m_segmentOverlapMatrix(0) @@ -126,35 +127,111 @@ OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, OFVecto // in the vector m_segmentsForFrame for (Uint32 f = 0; f < numFrames; f++) { - FGBase* group = NULL; - FGSegmentation* segFG = NULL; - group = fg.get(f, DcmFGTypes::EFG_SEGMENTATION); - segFG = OFstatic_cast(FGSegmentation*, group); - if (segFG) + OFCondition result; + std::set segments; + result = getSegmentsForFrame(f, segments); + if (result.good()) { - Uint16 segNum = 0; - OFCondition cond = segFG->getReferencedSegmentNumber(segNum); - if (cond.good() && segNum > 0) + if(segments.find(segmentNumber) != segments.end()) { + m_framesForSegment[segmentNumber - 1].push_back(f); // physical frame number for segment + } + } + else + { + DCMSEG_ERROR("getFramesForSegment(): Cannot get segments for frame " << f); + return EC_IllegalCall; + } + } + } + frames = m_framesForSegment[segmentNumber - 1]; + return EC_Normal; +} + +OFCondition OverlapUtil::getSegmentsForFrame(const Uint32 frameNumber, std::set& segments) +{ + if (!m_seg) + { + DCMSEG_ERROR("getSegmentsForFrame(): No segmentation object set"); + return EC_IllegalCall; + } + if (frameNumber > m_seg->getNumberOfFrames() - 1) + { + DCMSEG_ERROR("getSegmentsForFrame(): Frame number " << frameNumber << " is out of range"); + return EC_IllegalParameter; + } + if (m_segmentsForFrame.empty()) + { + FGInterface& fg = m_seg->getFunctionalGroups(); + size_t tempNum = m_seg->getNumberOfFrames(); + if (tempNum > 4294967295) + { + DCMSEG_ERROR("getSegmentsForFrame(): Number of frames " << tempNum << " exceeds maximum number of possible frames (2^32-1)"); + return EC_IllegalParameter; + } + Uint32 numFrames = static_cast(m_seg->getNumberOfFrames()); + m_segmentsForFrame.clear(); + m_segmentsForFrame.resize(numFrames); + for (Uint32 f = 0; f < numFrames; f++) { + m_segmentsForFrame.push_back(std::set()); + if (m_seg->getSegmentationType() == (DcmSegTypes::E_SegmentationType) 3) // LABELMAP + { + const DcmIODTypes::Frame* f_data = m_seg->getFrame(f); + Uint16 rows, cols; + rows = cols = 0; + DcmIODImage>* ip = static_cast>*>(m_seg); + ip->getImagePixel().getRows(rows); + ip->getImagePixel().getColumns(cols); + if (!f_data) { - m_framesForSegment[segNum - 1].push_back(f); // physical frame number for segment + DCMSEG_ERROR("getSegmentsForFrame(): Cannot access label map frame " << f); + return EC_IllegalCall; } - else if (segNum == 0) + + for (size_t n = 0; n < f_data->length; ++n) { - DCMSEG_WARN("getFramesForSegment(): Referenced Segment Number is 0 (not permitted) for frame #" - << f << ", ignoring"); - return EC_InvalidValue; + Uint8 segmentNumber = f_data->pixData[n]; + if ((segmentNumber == 0) || (segmentNumber > m_seg->getNumberOfSegments())) + { + DCMSEG_ERROR("getSegmentsForFrame(): Segment number " << segmentNumber << " is out of range"); + return EC_IllegalParameter; + } + m_segmentsForFrame[f].insert(segmentNumber); } - else + return EC_Normal; + } + else + { + FGBase* group = NULL; + FGSegmentation* segFG = NULL; + group = fg.get(f, DcmFGTypes::EFG_SEGMENTATION); + segFG = OFstatic_cast(FGSegmentation*, group); + if (segFG) { - DCMSEG_ERROR( - "getFramesForSegment(): Referenced Segment Number not found (not permitted) for frame #" - << f << ", cannot add segment"); - return EC_TagNotFound; + Uint16 segNum = 0; + OFCondition cond = segFG->getReferencedSegmentNumber(segNum); + if (cond.good() && segNum > 0) + { + m_segmentsForFrame[f].insert(segNum); // physical frame number for segment + } + else if (segNum == 0) + { + DCMSEG_WARN("getSegmentsForFrame(): Referenced Segment Number is 0 (not permitted) for frame #" + << f << ", ignoring"); + return EC_InvalidValue; + } + else + { + DCMSEG_ERROR( + "getSegmentsForFrame(): Referenced Segment Number not found (not permitted) for frame #" + << f << ", cannot add segment"); + return EC_TagNotFound; + } } } } } - frames = m_framesForSegment[segmentNumber - 1]; + + segments = m_segmentsForFrame[frameNumber]; return EC_Normal; } @@ -296,52 +373,24 @@ OFCondition OverlapUtil::getSegmentsByPosition(SegmentsByPosition& result) m_segmentsByPosition.resize(m_logicalFramePositions.size()); for (size_t l = 0; l < m_logicalFramePositions.size(); ++l) { - OFVector segments; for (size_t f = 0; f < m_logicalFramePositions[l].size(); ++f) { + std::set segmentsInFrame; Uint32 frameNumber = m_logicalFramePositions[l][f]; - OFVector segs; - FGBase* group = NULL; - FGSegmentation* segFG = NULL; - group = m_seg->getFunctionalGroups().get(frameNumber, DcmFGTypes::EFG_SEGMENTATION); - segFG = OFstatic_cast(FGSegmentation*, group); - if (segFG) + if (getSegmentsForFrame(frameNumber, segmentsInFrame).good()) { - Uint16 segNum = 0; - cond = segFG->getReferencedSegmentNumber(segNum); - if (cond.good() && segNum > 0 && (segNum <= numSegments)) - { - m_segmentsByPosition[l].insert(SegNumAndFrameNum(segNum, frameNumber)); - } - else if (segNum == 0) - { - DCMSEG_ERROR( - "getSegmentsByPosition(): Referenced Segment Number is 0 (not permitted), cannot add segment"); - cond = EC_InvalidValue; - break; - } - else if (segNum > numSegments) - { - DCMSEG_ERROR("getSegmentsByPosition(): Found Referenced Segment Number " - << segNum << " but only " << numSegments - << " segments are present, cannot add segment"); - DCMSEG_ERROR( - "getSegmentsByPosition(): Segments are not numbered consecutively, cannot add segment"); - cond = EC_InvalidValue; - break; - } - else + for (std::set::iterator it = segmentsInFrame.begin(); + it != segmentsInFrame.end(); + ++it) { - DCMSEG_ERROR("getSegmentsByPosition(): Referenced Segment Number not found (not permitted) , " - "cannot add segment"); - cond = EC_TagNotFound; - break; + m_segmentsByPosition[l].insert(SegNumAndFrameNum(*it, frameNumber)); } } - } - if (cond.bad()) - { - break; + else + { + DCMSEG_ERROR("getSegmentsByPosition(): Cannot get segments for frame " << frameNumber); + return EC_IllegalCall; + } } } // print segments per logical frame if debug log level is enabled @@ -564,7 +613,14 @@ OFCondition OverlapUtil::buildOverlapMatrix() // Compare pixels of the frames referenced by each segments. // If they overlap, mark as overlapping OFBool overlap = OFFalse; - checkFramesOverlap(it->m_frameNumber, it2->m_frameNumber, overlap); + if (m_seg->getSegmentationType() == (DcmSegTypes::E_SegmentationType) 3) // LABELMAP + { + checkFramesOverlapLabelMap(*it, *it2, overlap); + } + else + { + checkFramesOverlap(it->m_frameNumber, it2->m_frameNumber, overlap); + } // Enter result into overlap matrix m_segmentOverlapMatrix[(*it).m_segmentNumber - 1][(*it2).m_segmentNumber - 1] = overlap ? 1 : 0; @@ -595,6 +651,57 @@ OFCondition OverlapUtil::buildOverlapMatrix() return EC_Normal; } +OFCondition OverlapUtil::checkFramesOverlapLabelMap(const SegNumAndFrameNum& sf1, + const SegNumAndFrameNum& sf2, + OFBool& overlap) +{ + if (sf1.m_frameNumber == sf2.m_frameNumber || sf1.m_segmentNumber == sf2.m_segmentNumber) + { + // The same frame or segment should not be considered overlapping + overlap = OFFalse; + return EC_Normal; + } + + overlap = OFFalse; + const Uint32& f1 = sf1.m_frameNumber; + const Uint32& f2 = sf2.m_frameNumber; + OFCondition result; + const DcmIODTypes::Frame* f1_data = m_seg->getFrame(sf1.m_frameNumber); + const DcmIODTypes::Frame* f2_data = m_seg->getFrame(sf2.m_frameNumber); + Uint16 rows, cols; + rows = cols = 0; + DcmIODImage>* ip = static_cast>*>(m_seg); + ip->getImagePixel().getRows(rows); + ip->getImagePixel().getColumns(cols); + + DCMSEG_DEBUG("checkFramesOverlapLabelMap(): Comparing frame " << f1 << ", segment " << sf1.m_segmentNumber << ", and frame " + << f2 << ", segment " << sf2.m_segmentNumber + << ", for overlap"); + if (!f1_data || !f2_data) + { + DCMSEG_ERROR("checkFramesOverlapLabelMap(): Cannot access label map frames " << f1 << " and " << f2 << " for comparison"); + return EC_IllegalCall; + } + if (f1_data->length != f2_data->length) + { + DCMSEG_ERROR("checkFramesOverlapLabelMap(): Frames " << f1 << " and " << f2 + << " have different length, cannot compare"); + return EC_IllegalCall; + } + + for (size_t n = 0; n < f1_data->length; ++n) + { + if (f1_data->pixData[n] == sf1.m_segmentNumber && f2_data->pixData[n] == sf2.m_segmentNumber) + { + DCMSEG_DEBUG("checkFramesOverlapLabelMap(): Frame " << f1 << ", segment " << sf1.m_segmentNumber << ", and frame " + << f2 << ", segment " << sf2.m_segmentNumber << ", do overlap at index " << n); + overlap = OFTrue; + break; + } + } + return EC_Normal; +} + OFCondition OverlapUtil::checkFramesOverlap(const Uint32& f1, const Uint32& f2, OFBool& overlap) { if (f1 == f2) @@ -608,7 +715,7 @@ OFCondition OverlapUtil::checkFramesOverlap(const Uint32& f1, const Uint32& f2, const DcmIODTypes::Frame* f1_data = m_seg->getFrame(f1); const DcmIODTypes::Frame* f2_data = m_seg->getFrame(f2); Uint16 rows, cols; - rows = cols = 0; + rows = cols = 0; DcmIODImage>* ip = static_cast>*>(m_seg); ip->getImagePixel().getRows(rows); ip->getImagePixel().getColumns(cols); From 3b79d845ab93011aec3d786a2ce0230467c4958c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Spaltenstein?= Date: Tue, 30 Jan 2024 16:21:35 +0000 Subject: [PATCH 2/7] bug fixes and refactoring --- include/dcmqi/OverlapUtil.h | 30 +++++++-- libsrc/OverlapUtil.cpp | 131 +++++++++++++++++++++--------------- 2 files changed, 101 insertions(+), 60 deletions(-) diff --git a/include/dcmqi/OverlapUtil.h b/include/dcmqi/OverlapUtil.h index a4b58edc..4cc1db26 100644 --- a/include/dcmqi/OverlapUtil.h +++ b/include/dcmqi/OverlapUtil.h @@ -196,8 +196,11 @@ class OverlapUtil */ OFCondition getFramesForSegment(const Uint32 segmentNumber, OFVector& frames); - /** - * TODO + /** Get the all the segments, by segment number (1..n), present on + * a specified frame + * @param frameNumber The frame number for which to get segments + * @param segments Resulting set of segment numbers (1..n) + * @return EC_Normal if successful, error otherwise */ OFCondition getSegmentsForFrame(const Uint32 frameNumber, std::set& segments); @@ -242,6 +245,22 @@ class OverlapUtil protected: + /** Get the list of segment numbers (1..n) for segments within a labelmap + * segmentation frame. Does not cache the result. To be used only a label map frame. + * @param frameNumber The frame number for which to get labels + * @param segments The resulting set of segments on the frame + * @return EC_Normal if successful, error otherwise + */ + OFCondition getSegmentsForLabelMapFrame(const Uint32 frameNumber, std::set& segments); + + /** Get the segment number (1..n) for a binary or fractional segmentation a frame. + * Does not cache the result. To be used exclusively a binary or fractional segmentation + * frame. + * @param frameNumber The frame number for which to get labels + * @param segment The resulting segments on the frame + * @return EC_Normal if successful, error otherwise + */ + OFCondition getSegmentForFrame(const Uint32 frameNumber, Uint32& segment); /** Group physical frame positions into logical positions. This is done by sorting * frames after *that* position coordinate that in its mean position difference is @@ -285,9 +304,10 @@ class OverlapUtil */ OFCondition checkFramesOverlap(const Uint32& f1, const Uint32& f2, OFBool& overlap); - /** - * @param sf1 TODO - * @param sf1 TODO + /** Checks, on labelmap frames, if a segment as present of a first frame + * overlaps with another segment as present a second frame + * @param sf1 Segment number on frame number to check + * @param sf2 Segment number on frame number to check * @param overlap Resulting overlap (overlaps if OFTrue, otherwise not) * @return EC_Normal if successful, error otherwise */ diff --git a/libsrc/OverlapUtil.cpp b/libsrc/OverlapUtil.cpp index 05abb9c2..fe478682 100644 --- a/libsrc/OverlapUtil.cpp +++ b/libsrc/OverlapUtil.cpp @@ -139,7 +139,7 @@ OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, OFVecto else { DCMSEG_ERROR("getFramesForSegment(): Cannot get segments for frame " << f); - return EC_IllegalCall; + return result; } } } @@ -159,73 +159,33 @@ OFCondition OverlapUtil::getSegmentsForFrame(const Uint32 frameNumber, std::set< DCMSEG_ERROR("getSegmentsForFrame(): Frame number " << frameNumber << " is out of range"); return EC_IllegalParameter; } + size_t tempNum = m_seg->getNumberOfFrames(); + if (tempNum > 4294967295) + { + DCMSEG_ERROR("getSegmentsForFrame(): Number of frames " << tempNum << " exceeds maximum number of possible frames (2^32-1)"); + return EC_IllegalParameter; + } if (m_segmentsForFrame.empty()) { - FGInterface& fg = m_seg->getFunctionalGroups(); - size_t tempNum = m_seg->getNumberOfFrames(); - if (tempNum > 4294967295) - { - DCMSEG_ERROR("getSegmentsForFrame(): Number of frames " << tempNum << " exceeds maximum number of possible frames (2^32-1)"); - return EC_IllegalParameter; - } Uint32 numFrames = static_cast(m_seg->getNumberOfFrames()); - m_segmentsForFrame.clear(); m_segmentsForFrame.resize(numFrames); for (Uint32 f = 0; f < numFrames; f++) { - m_segmentsForFrame.push_back(std::set()); + OFCondition result; if (m_seg->getSegmentationType() == (DcmSegTypes::E_SegmentationType) 3) // LABELMAP { - const DcmIODTypes::Frame* f_data = m_seg->getFrame(f); - Uint16 rows, cols; - rows = cols = 0; - DcmIODImage>* ip = static_cast>*>(m_seg); - ip->getImagePixel().getRows(rows); - ip->getImagePixel().getColumns(cols); - if (!f_data) - { - DCMSEG_ERROR("getSegmentsForFrame(): Cannot access label map frame " << f); - return EC_IllegalCall; - } - - for (size_t n = 0; n < f_data->length; ++n) + result = getSegmentsForLabelMapFrame(f, m_segmentsForFrame[f]); + if (result.bad()) { - Uint8 segmentNumber = f_data->pixData[n]; - if ((segmentNumber == 0) || (segmentNumber > m_seg->getNumberOfSegments())) - { - DCMSEG_ERROR("getSegmentsForFrame(): Segment number " << segmentNumber << " is out of range"); - return EC_IllegalParameter; - } - m_segmentsForFrame[f].insert(segmentNumber); + return result; } - return EC_Normal; } else { - FGBase* group = NULL; - FGSegmentation* segFG = NULL; - group = fg.get(f, DcmFGTypes::EFG_SEGMENTATION); - segFG = OFstatic_cast(FGSegmentation*, group); - if (segFG) + Uint32 segment; + result = getSegmentForFrame(frameNumber, segment); + if (result.good()) { - Uint16 segNum = 0; - OFCondition cond = segFG->getReferencedSegmentNumber(segNum); - if (cond.good() && segNum > 0) - { - m_segmentsForFrame[f].insert(segNum); // physical frame number for segment - } - else if (segNum == 0) - { - DCMSEG_WARN("getSegmentsForFrame(): Referenced Segment Number is 0 (not permitted) for frame #" - << f << ", ignoring"); - return EC_InvalidValue; - } - else - { - DCMSEG_ERROR( - "getSegmentsForFrame(): Referenced Segment Number not found (not permitted) for frame #" - << f << ", cannot add segment"); - return EC_TagNotFound; - } + m_segmentsForFrame[f].insert(segment); } } } @@ -562,6 +522,67 @@ void OverlapUtil::printNonOverlappingSegments(OFStringStream& ss) } } +OFCondition OverlapUtil::getSegmentsForLabelMapFrame(const Uint32 frameNumber, std::set& segments) +{ + const DcmIODTypes::Frame* f_data = m_seg->getFrame(frameNumber); + Uint16 rows, cols; + rows = cols = 0; + DcmIODImage>* ip = static_cast>*>(m_seg); + ip->getImagePixel().getRows(rows); + ip->getImagePixel().getColumns(cols); + if (!f_data) + { + DCMSEG_ERROR("getSegmentsForLabelMapFrame(): Cannot access label map frame " << frameNumber); + return EC_IllegalCall; + } + + segments.clear(); + for (size_t n = 0; n < f_data->length; ++n) + { + Uint8 segmentNumber = f_data->pixData[n]; + if ((segmentNumber == 0) || (segmentNumber > m_seg->getNumberOfSegments())) + { + DCMSEG_ERROR("getSegmentsForFrame(): Segment number " << segmentNumber << " is out of range"); + return EC_IllegalParameter; + } + segments.insert(segmentNumber); + } + return EC_Normal; +} + +OFCondition OverlapUtil::getSegmentForFrame(const Uint32 frameNumber, Uint32& segment) +{ + FGBase* group = NULL; + FGSegmentation* segFG = NULL; + FGInterface& fg = m_seg->getFunctionalGroups(); + group = fg.get(frameNumber, DcmFGTypes::EFG_SEGMENTATION); + segFG = OFstatic_cast(FGSegmentation*, group); + if (segFG) + { + Uint16 segNum = 0; + OFCondition cond = segFG->getReferencedSegmentNumber(segNum); + if (cond.good() && segNum > 0) + { + segment = segNum; + } + else if (segNum == 0) + { + DCMSEG_WARN("getSegmentForFrame(): Referenced Segment Number is 0 (not permitted) for frame #" + << frameNumber << ", ignoring"); + return EC_InvalidValue; + } + else + { + DCMSEG_ERROR( + "getSegmentForFrame(): Referenced Segment Number not found (not permitted) for frame #" + << frameNumber << ", cannot add segment"); + return EC_TagNotFound; + } + } + return EC_Normal; +} + + OFCondition OverlapUtil::buildOverlapMatrix() { // Make 2 dimensional array matrix of Sint8 type for (segment numbers) X (segment numbers). From 90786e39f6ccde6ba8e8c25ad727ea4096e8034e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Spaltenstein?= Date: Tue, 30 Jan 2024 19:50:30 +0000 Subject: [PATCH 3/7] fix bugs revealed by tests --- libsrc/OverlapUtil.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/libsrc/OverlapUtil.cpp b/libsrc/OverlapUtil.cpp index fe478682..b35e8996 100644 --- a/libsrc/OverlapUtil.cpp +++ b/libsrc/OverlapUtil.cpp @@ -121,8 +121,9 @@ OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, OFVecto return EC_IllegalParameter; } Uint32 numFrames = static_cast(m_seg->getNumberOfFrames()); - m_framesForSegment.clear(); - m_framesForSegment.resize(m_seg->getNumberOfSegments()); + // use sets for performance and deduplication while adding frames to each set + OFVector> segmentFrameSet; + segmentFrameSet.resize(m_seg->getNumberOfSegments()); // Get Segmentation FG for each frame and remember the segment number for each frame // in the vector m_segmentsForFrame for (Uint32 f = 0; f < numFrames; f++) @@ -132,8 +133,11 @@ OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, OFVecto result = getSegmentsForFrame(f, segments); if (result.good()) { - if(segments.find(segmentNumber) != segments.end()) { - m_framesForSegment[segmentNumber - 1].push_back(f); // physical frame number for segment + for (std::set::iterator itr = segments.begin(); + itr != segments.end(); + itr++) + { + segmentFrameSet[(*itr) - 1].insert(f); } } else @@ -142,6 +146,17 @@ OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, OFVecto return result; } } + // copy the set back into the OFVector in m_framesForSegment + m_framesForSegment.resize(segmentFrameSet.size()); + for (Uint32 s = 0; s < segmentFrameSet.size(); s++) { + m_framesForSegment[s].reserve(segmentFrameSet[s].size()); + for (std::set::iterator itr = segmentFrameSet[s].begin(); + itr != segmentFrameSet[s].end(); + itr++) + { + m_framesForSegment[s].push_back(*itr); + } + } } frames = m_framesForSegment[segmentNumber - 1]; return EC_Normal; @@ -182,7 +197,7 @@ OFCondition OverlapUtil::getSegmentsForFrame(const Uint32 frameNumber, std::set< else { Uint32 segment; - result = getSegmentForFrame(frameNumber, segment); + result = getSegmentForFrame(f, segment); if (result.good()) { m_segmentsForFrame[f].insert(segment); From 763023f75c62e80ff5530311f7c6ea83579d2b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Spaltenstein?= Date: Tue, 30 Jan 2024 23:26:23 +0000 Subject: [PATCH 4/7] comment fixes --- include/dcmqi/OverlapUtil.h | 23 +++++++++++------------ libsrc/OverlapUtil.cpp | 2 +- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/include/dcmqi/OverlapUtil.h b/include/dcmqi/OverlapUtil.h index 4cc1db26..8fa6ea24 100644 --- a/include/dcmqi/OverlapUtil.h +++ b/include/dcmqi/OverlapUtil.h @@ -93,7 +93,7 @@ class OverlapUtil /// and index 0 is unused. I.e. index i is segment number, value is vector of physical frame numbers. typedef OFVector> FramesForSegment; - // Lists of segments for each frame. Used for Label Maps where each frame can have multiple segments. + // Set of segments present on each frame. typedef OFVector> SegmentsForFrame; /// Implements comparision operator to be used for sorting of frame positions, @@ -196,8 +196,7 @@ class OverlapUtil */ OFCondition getFramesForSegment(const Uint32 segmentNumber, OFVector& frames); - /** Get the all the segments, by segment number (1..n), present on - * a specified frame + /** Get the all the segments present on a specified frame * @param frameNumber The frame number for which to get segments * @param segments Resulting set of segment numbers (1..n) * @return EC_Normal if successful, error otherwise @@ -245,17 +244,17 @@ class OverlapUtil protected: - /** Get the list of segment numbers (1..n) for segments within a labelmap - * segmentation frame. Does not cache the result. To be used only a label map frame. + /** Get the list of segments within a label map segmentation frame. + * Does not cache the result. To be used exclusively on a label map frame. * @param frameNumber The frame number for which to get labels - * @param segments The resulting set of segments on the frame + * @param segments The resulting set of segments on the frame (1..n) * @return EC_Normal if successful, error otherwise */ OFCondition getSegmentsForLabelMapFrame(const Uint32 frameNumber, std::set& segments); - /** Get the segment number (1..n) for a binary or fractional segmentation a frame. - * Does not cache the result. To be used exclusively a binary or fractional segmentation - * frame. + /** Get the segment number (1..n) for a binary or fractional segmentation frame. + * Does not cache the result. To be used exclusively on a binary or fractional + * segmentation frame. * @param frameNumber The frame number for which to get labels * @param segment The resulting segments on the frame * @return EC_Normal if successful, error otherwise @@ -304,8 +303,8 @@ class OverlapUtil */ OFCondition checkFramesOverlap(const Uint32& f1, const Uint32& f2, OFBool& overlap); - /** Checks, on labelmap frames, if a segment as present of a first frame - * overlaps with another segment as present a second frame + /** Checks to see if a segment on a first frame overlaps with a different segment + * on a second frame * @param sf1 Segment number on frame number to check * @param sf2 Segment number on frame number to check * @param overlap Resulting overlap (overlaps if OFTrue, otherwise not) @@ -378,7 +377,7 @@ class OverlapUtil /// segment. FramesForSegment m_framesForSegment; - /// Stores which segments are present on each frame. + /// Stores which segments are present on each frame. SegmentsForFrame m_segmentsForFrame; /// Logical frames, ie. physical frames with the same position are diff --git a/libsrc/OverlapUtil.cpp b/libsrc/OverlapUtil.cpp index b35e8996..eea8739e 100644 --- a/libsrc/OverlapUtil.cpp +++ b/libsrc/OverlapUtil.cpp @@ -187,7 +187,7 @@ OFCondition OverlapUtil::getSegmentsForFrame(const Uint32 frameNumber, std::set< for (Uint32 f = 0; f < numFrames; f++) { OFCondition result; if (m_seg->getSegmentationType() == (DcmSegTypes::E_SegmentationType) 3) // LABELMAP - { + { result = getSegmentsForLabelMapFrame(f, m_segmentsForFrame[f]); if (result.bad()) { From 7507a76f92f77c72f5e2d350d630dbde219634d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Spaltenstein?= Date: Tue, 30 Jan 2024 23:56:03 +0000 Subject: [PATCH 5/7] because I can't let well enough alone --- libsrc/OverlapUtil.cpp | 46 ++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/libsrc/OverlapUtil.cpp b/libsrc/OverlapUtil.cpp index eea8739e..0a724d14 100644 --- a/libsrc/OverlapUtil.cpp +++ b/libsrc/OverlapUtil.cpp @@ -121,11 +121,11 @@ OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, OFVecto return EC_IllegalParameter; } Uint32 numFrames = static_cast(m_seg->getNumberOfFrames()); - // use sets for performance and deduplication while adding frames to each set - OFVector> segmentFrameSet; - segmentFrameSet.resize(m_seg->getNumberOfSegments()); - // Get Segmentation FG for each frame and remember the segment number for each frame - // in the vector m_segmentsForFrame + // use sets for performance and deduplication when adding frames to each segment index + OFVector> frameSetsForSegment; + frameSetsForSegment.resize(m_seg->getNumberOfSegments()); + // Use the helper function getSegmentsForFrame() to pivot the data + // from segments on each frame, to the list of frames with contain each segment for (Uint32 f = 0; f < numFrames; f++) { OFCondition result; @@ -137,7 +137,7 @@ OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, OFVecto itr != segments.end(); itr++) { - segmentFrameSet[(*itr) - 1].insert(f); + frameSetsForSegment[(*itr) - 1].insert(f); } } else @@ -146,12 +146,12 @@ OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, OFVecto return result; } } - // copy the set back into the OFVector in m_framesForSegment - m_framesForSegment.resize(segmentFrameSet.size()); - for (Uint32 s = 0; s < segmentFrameSet.size(); s++) { - m_framesForSegment[s].reserve(segmentFrameSet[s].size()); - for (std::set::iterator itr = segmentFrameSet[s].begin(); - itr != segmentFrameSet[s].end(); + // copy the sets back into the OFVectors in m_framesForSegment + m_framesForSegment.resize(frameSetsForSegment.size()); + for (Uint32 s = 0; s < frameSetsForSegment.size(); s++) { + m_framesForSegment[s].reserve(frameSetsForSegment[s].size()); + for (std::set::iterator itr = frameSetsForSegment[s].begin(); + itr != frameSetsForSegment[s].end(); itr++) { m_framesForSegment[s].push_back(*itr); @@ -352,7 +352,8 @@ OFCondition OverlapUtil::getSegmentsByPosition(SegmentsByPosition& result) { std::set segmentsInFrame; Uint32 frameNumber = m_logicalFramePositions[l][f]; - if (getSegmentsForFrame(frameNumber, segmentsInFrame).good()) + cond = getSegmentsForFrame(frameNumber, segmentsInFrame); + if (cond.good()) { for (std::set::iterator it = segmentsInFrame.begin(); it != segmentsInFrame.end(); @@ -364,9 +365,13 @@ OFCondition OverlapUtil::getSegmentsByPosition(SegmentsByPosition& result) else { DCMSEG_ERROR("getSegmentsByPosition(): Cannot get segments for frame " << frameNumber); - return EC_IllegalCall; + break; } } + if (cond.bad()) + { + break; + } } // print segments per logical frame if debug log level is enabled if (cond.good() && DCM_dcmsegLogger.isEnabledFor(OFLogger::DEBUG_LOG_LEVEL)) @@ -375,7 +380,7 @@ OFCondition OverlapUtil::getSegmentsByPosition(SegmentsByPosition& result) printSegmentsByPosition(ss); DCMSEG_DEBUG(ss.str()); } - DCMSEG_DEBUG("groupFramesByPosition(): Grouping segments by position took " << tm.getDiff() << " s"); + DCMSEG_DEBUG("getSegmentsByPosition(): Getting segments by position took " << tm.getDiff() << " s"); return cond; } @@ -648,14 +653,21 @@ OFCondition OverlapUtil::buildOverlapMatrix() } // Compare pixels of the frames referenced by each segments. // If they overlap, mark as overlapping + OFCondition cond; OFBool overlap = OFFalse; if (m_seg->getSegmentationType() == (DcmSegTypes::E_SegmentationType) 3) // LABELMAP { - checkFramesOverlapLabelMap(*it, *it2, overlap); + cond = checkFramesOverlapLabelMap(*it, *it2, overlap); } else { - checkFramesOverlap(it->m_frameNumber, it2->m_frameNumber, overlap); + cond = checkFramesOverlap(it->m_frameNumber, it2->m_frameNumber, overlap); + } + if (cond.bad()) + { + DCMSEG_ERROR("getOverlappingSegments(): Error checking overlap of frames " + << it->m_frameNumber << " and " << it2->m_frameNumber); + return cond; } // Enter result into overlap matrix From d30215c4895acb32dfa200b59c5b20ca8f58d753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Spaltenstein?= Date: Wed, 31 Jan 2024 11:14:28 +0000 Subject: [PATCH 6/7] only copy the correct segmented pixels --- libsrc/Dicom2ItkConverter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libsrc/Dicom2ItkConverter.cpp b/libsrc/Dicom2ItkConverter.cpp index 16fa8da0..e642e247 100644 --- a/libsrc/Dicom2ItkConverter.cpp +++ b/libsrc/Dicom2ItkConverter.cpp @@ -212,6 +212,7 @@ itk::SmartPointer Dicom2ItkConverter::nextResult() /* WIP */ } + bool labelMapSegmentation = m_segDoc->getSegmentationType() == (DcmSegTypes::E_SegmentationType) 3; // LABELMAP; for (unsigned row = 0; row < m_imageSize[1]; row++) { for (unsigned col = 0; col < m_imageSize[0]; col++) @@ -220,7 +221,7 @@ itk::SmartPointer Dicom2ItkConverter::nextResult() unsigned bitCnt = row * m_imageSize[0] + col; pixel = unpackedFrame->pixData[bitCnt]; ShortImageType::IndexType index; - if (pixel != 0) + if (labelMapSegmentation ? pixel == *segNum : pixel != 0) { index[0] = col; index[1] = row; From 414303667fed3da670a845f37687e4df041188bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Spaltenstein?= Date: Thu, 1 Feb 2024 16:34:25 +0000 Subject: [PATCH 7/7] be tolerant of new segment numbers --- include/dcmqi/OverlapUtil.h | 19 ++++--- libsrc/Dicom2ItkConverter.cpp | 15 ++--- libsrc/OverlapUtil.cpp | 102 ++++++++++++++++++---------------- 3 files changed, 71 insertions(+), 65 deletions(-) diff --git a/include/dcmqi/OverlapUtil.h b/include/dcmqi/OverlapUtil.h index 8fa6ea24..f250181f 100644 --- a/include/dcmqi/OverlapUtil.h +++ b/include/dcmqi/OverlapUtil.h @@ -27,6 +27,7 @@ #include "dcmtk/ofstd/oftypes.h" #include "dcmtk/ofstd/ofvector.h" #include +#include class DcmSegmentation; @@ -91,7 +92,7 @@ class OverlapUtil /// Lists frames for each segment where segment with index i is represented by the vector at index i, /// and index 0 is unused. I.e. index i is segment number, value is vector of physical frame numbers. - typedef OFVector> FramesForSegment; + typedef std::map> FramesForSegment; // Set of segments present on each frame. typedef OFVector> SegmentsForFrame; @@ -119,7 +120,7 @@ class OverlapUtil /// Matrix of N x N segment numbers, where N is the number of segments. /// Value is 1 at x,y if x and y overlap, 0 if they don't overlap, and -1 if not initialized. - typedef OFVector> OverlapMatrix; + typedef std::map> OverlapMatrix; /// Group of non-overlapping segments (each represented by its segment number) typedef OFVector> SegmentGroups; @@ -137,7 +138,7 @@ class OverlapUtil , m_frameNumber(f) { } - /// Segment number as used in DICOM segmentation object (1-n) + /// Segment number as used in DICOM segmentation object Uint16 m_segmentNumber; /// Logical frame number (number of frame in DistinctFramePositions vector) Uint16 m_frameNumber; @@ -190,15 +191,15 @@ class OverlapUtil OFCondition getSegmentsByPosition(SegmentsByPosition& result); /** Get phyiscal frames for a specific segment by its segment number - * @param segmentNumber Segment number to get frames for (1..n) - * @param frames Resulting vector of physical frame numbers (first frame is frame 0) + * @param segmentNumber Segment number for which to get frames + * @param frames Resulting vector of physical frame numbers * @return EC_Normal if successful, error otherwise */ - OFCondition getFramesForSegment(const Uint32 segmentNumber, OFVector& frames); + OFCondition getFramesForSegment(const Uint32 segmentNumber, std::set& frames); /** Get the all the segments present on a specified frame * @param frameNumber The frame number for which to get segments - * @param segments Resulting set of segment numbers (1..n) + * @param segments Resulting set of segment numbers * @return EC_Normal if successful, error otherwise */ OFCondition getSegmentsForFrame(const Uint32 frameNumber, std::set& segments); @@ -247,12 +248,12 @@ class OverlapUtil /** Get the list of segments within a label map segmentation frame. * Does not cache the result. To be used exclusively on a label map frame. * @param frameNumber The frame number for which to get labels - * @param segments The resulting set of segments on the frame (1..n) + * @param segments The resulting set of segments on the frame * @return EC_Normal if successful, error otherwise */ OFCondition getSegmentsForLabelMapFrame(const Uint32 frameNumber, std::set& segments); - /** Get the segment number (1..n) for a binary or fractional segmentation frame. + /** Get the segment number for a binary or fractional segmentation frame. * Does not cache the result. To be used exclusively on a binary or fractional * segmentation frame. * @param frameNumber The frame number for which to get labels diff --git a/libsrc/Dicom2ItkConverter.cpp b/libsrc/Dicom2ItkConverter.cpp index e642e247..837ddf9c 100644 --- a/libsrc/Dicom2ItkConverter.cpp +++ b/libsrc/Dicom2ItkConverter.cpp @@ -124,24 +124,26 @@ itk::SmartPointer Dicom2ItkConverter::nextResult() { // Iterate over frames for this segment, and copy the data into the ITK image. // Afterwards, the ITK image will have the complete data belonging to that segment - OverlapUtil::FramesForSegment::value_type framesForSegment; + OverlapUtil::FramesForSegment::mapped_type framesForSegment; m_overlapUtil.getFramesForSegment(*segNum, framesForSegment); - for (size_t frameIndex = 0; frameIndex < framesForSegment.size(); frameIndex++) + for (std::set::iterator it = framesForSegment.begin(); + it != framesForSegment.end(); + it++) { // Copy the data from the frame into the ITK image ShortImageType::PointType frameOriginPoint; ShortImageType::IndexType frameOriginIndex; - result = getITKImageOrigin(framesForSegment[frameIndex], frameOriginPoint); + result = getITKImageOrigin(*it, frameOriginPoint); if (result.bad()) { - cerr << "ERROR: Failed to get origin for frame " << framesForSegment[frameIndex] << " of segment " + cerr << "ERROR: Failed to get origin for frame " << *it << " of segment " << *segNum << endl; m_groupIterator = m_segmentGroups.end(); return nullptr; } if (!itkImage->TransformPhysicalPointToIndex(frameOriginPoint, frameOriginIndex)) { - cerr << "ERROR: Frame " << framesForSegment[frameIndex] << " origin " << frameOriginPoint + cerr << "ERROR: Frame " << *it << " origin " << frameOriginPoint << " is outside image geometry!" << frameOriginIndex << endl; cerr << "Image size: " << itkImage->GetBufferedRegion().GetSize() << endl; m_groupIterator = m_segmentGroups.end(); @@ -149,7 +151,7 @@ itk::SmartPointer Dicom2ItkConverter::nextResult() } // Handling differs depending on whether the segmentation is binary or fractional // (we have to unpack binary frames before copying them into the ITK image) - const DcmIODTypes::Frame* rawFrame = m_segDoc->getFrame(framesForSegment[frameIndex]); + const DcmIODTypes::Frame* rawFrame = m_segDoc->getFrame(*it); const DcmIODTypes::Frame* unpackedFrame = NULL; if (m_segDoc->getSegmentationType() == DcmSegTypes::ST_BINARY) { @@ -372,7 +374,6 @@ OFCondition Dicom2ItkConverter::getNonOverlappingSegmentGroups(const bool mergeS cout << "Will not merge segments: Splitting segments into " << segmentGroups.size() << " groups" << endl; } return result; - ; } // ------------------------------------------------------------------------------------- diff --git a/libsrc/OverlapUtil.cpp b/libsrc/OverlapUtil.cpp index 0a724d14..94ce7591 100644 --- a/libsrc/OverlapUtil.cpp +++ b/libsrc/OverlapUtil.cpp @@ -52,7 +52,7 @@ OverlapUtil::OverlapUtil() , m_segmentsForFrame() , m_logicalFramePositions() , m_segmentsByPosition() - , m_segmentOverlapMatrix(0) + , m_segmentOverlapMatrix() , m_nonOverlappingSegments() , m_seg() { @@ -99,18 +99,13 @@ OFCondition OverlapUtil::getFramesByPosition(DistinctFramePositions& result) return cond; } -OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, OFVector& frames) +OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, std::set& frames) { if (!m_seg) { DCMSEG_ERROR("getFramesForSegment(): No segmentation object set"); return EC_IllegalCall; } - if ((segmentNumber == 0) || (segmentNumber > m_seg->getNumberOfSegments())) - { - DCMSEG_ERROR("getFramesForSegment(): Segment number " << segmentNumber << " is out of range"); - return EC_IllegalParameter; - } if (m_framesForSegment.empty()) { FGInterface& fg = m_seg->getFunctionalGroups(); @@ -121,9 +116,6 @@ OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, OFVecto return EC_IllegalParameter; } Uint32 numFrames = static_cast(m_seg->getNumberOfFrames()); - // use sets for performance and deduplication when adding frames to each segment index - OFVector> frameSetsForSegment; - frameSetsForSegment.resize(m_seg->getNumberOfSegments()); // Use the helper function getSegmentsForFrame() to pivot the data // from segments on each frame, to the list of frames with contain each segment for (Uint32 f = 0; f < numFrames; f++) @@ -137,7 +129,7 @@ OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, OFVecto itr != segments.end(); itr++) { - frameSetsForSegment[(*itr) - 1].insert(f); + m_framesForSegment[*itr].insert(f); } } else @@ -146,19 +138,8 @@ OFCondition OverlapUtil::getFramesForSegment(const Uint32 segmentNumber, OFVecto return result; } } - // copy the sets back into the OFVectors in m_framesForSegment - m_framesForSegment.resize(frameSetsForSegment.size()); - for (Uint32 s = 0; s < frameSetsForSegment.size(); s++) { - m_framesForSegment[s].reserve(frameSetsForSegment[s].size()); - for (std::set::iterator itr = frameSetsForSegment[s].begin(); - itr != frameSetsForSegment[s].end(); - itr++) - { - m_framesForSegment[s].push_back(*itr); - } - } } - frames = m_framesForSegment[segmentNumber - 1]; + frames = m_framesForSegment[segmentNumber]; return EC_Normal; } @@ -337,7 +318,6 @@ OFCondition OverlapUtil::getSegmentsByPosition(SegmentsByPosition& result) { return cond; } - size_t numSegments = m_seg->getNumberOfSegments(); if (m_logicalFramePositions.empty()) { cond = getFramesByPosition(m_logicalFramePositions); @@ -438,19 +418,21 @@ OFCondition OverlapUtil::getNonOverlappingSegments(SegmentGroups& segmentGroups) // grouped segments. If not, add them to the same group. If yes, create a new group // and add them there. m_nonOverlappingSegments.push_back(OFVector()); - for (size_t i = 0; i < m_segmentOverlapMatrix.size(); ++i) + for (OverlapMatrix::iterator matrixItr = m_segmentOverlapMatrix.begin(); + matrixItr != m_segmentOverlapMatrix.end(); + matrixItr++) { // Loop over all groups and check whether the current segment overlaps with any of them OFBool overlaps = OFFalse; for (size_t j = 0; j < m_nonOverlappingSegments.size(); ++j) { // Loop over all segments in the current group - for (OFVector::iterator it = m_nonOverlappingSegments[j].begin(); + for (SegmentGroups::value_type::iterator it = m_nonOverlappingSegments[j].begin(); it != m_nonOverlappingSegments[j].end(); ++it) { // Check if the current segment overlaps with the segment in the current group - if (m_segmentOverlapMatrix[i][(*it) - 1] == 1) + if (m_segmentOverlapMatrix[matrixItr->first][*it] == 1) { overlaps = OFTrue; break; @@ -459,7 +441,7 @@ OFCondition OverlapUtil::getNonOverlappingSegments(SegmentGroups& segmentGroups) if (!overlaps) { // Add segment to current group - m_nonOverlappingSegments[j].push_back(i + 1); + m_nonOverlappingSegments[j].push_back(matrixItr->first); break; } } @@ -467,7 +449,7 @@ OFCondition OverlapUtil::getNonOverlappingSegments(SegmentGroups& segmentGroups) { // Create new group and add segment to it m_nonOverlappingSegments.push_back(OFVector()); - m_nonOverlappingSegments.back().push_back(i + 1); + m_nonOverlappingSegments.back().push_back(matrixItr->first); } } } @@ -495,7 +477,7 @@ void OverlapUtil::printSegmentsByPosition(OFStringStream& ss) for (size_t i = 0; i < m_segmentsByPosition.size(); ++i) { OFStringStream tempSS; - for (std::set::iterator it = m_segmentsByPosition[i].begin(); + for (SegmentsByPosition::value_type::iterator it = m_segmentsByPosition[i].begin(); it != m_segmentsByPosition[i].end(); ++it) { @@ -530,7 +512,7 @@ void OverlapUtil::printNonOverlappingSegments(OFStringStream& ss) for (size_t i = 0; i < m_nonOverlappingSegments.size(); ++i) { ss << "Group #" << i << ": "; - for (OFVector::iterator it = m_nonOverlappingSegments[i].begin(); + for (SegmentGroups::value_type::iterator it = m_nonOverlappingSegments[i].begin(); it != m_nonOverlappingSegments[i].end(); ++it) { @@ -560,7 +542,7 @@ OFCondition OverlapUtil::getSegmentsForLabelMapFrame(const Uint32 frameNumber, s for (size_t n = 0; n < f_data->length; ++n) { Uint8 segmentNumber = f_data->pixData[n]; - if ((segmentNumber == 0) || (segmentNumber > m_seg->getNumberOfSegments())) + if (segmentNumber > m_seg->getNumberOfSegments()) { DCMSEG_ERROR("getSegmentsForFrame(): Segment number " << segmentNumber << " is out of range"); return EC_IllegalParameter; @@ -605,19 +587,37 @@ OFCondition OverlapUtil::getSegmentForFrame(const Uint32 frameNumber, Uint32& se OFCondition OverlapUtil::buildOverlapMatrix() { - // Make 2 dimensional array matrix of Sint8 type for (segment numbers) X (segment numbers). - // Initialize with -1 (not checked yet) - m_segmentOverlapMatrix.clear(); - m_segmentOverlapMatrix.resize(m_seg->getNumberOfSegments()); - for (size_t i = 0; i < m_segmentOverlapMatrix.size(); ++i) + // TODO This corresponds to the list of segments in a binary or fractional + // segmentation IOD, we still need to get the actual list if this is a labelmap + const Uint32 numSegments = m_seg->getNumberOfSegments(); + std::set segmentNumbers; + for (Uint32 i = 1; i <= numSegments; ++i) { - m_segmentOverlapMatrix[i].resize(m_seg->getNumberOfSegments(), -1); + segmentNumbers.insert(i); } + + // Make 2 dimensional matrix of Sint8 type for (segment numbers) X (segment numbers). + // Initialize with -1 (not checked yet) // Diagonal is always 0 (segment does not interfere/overlap with itself) - for (size_t i = 0; i < m_segmentOverlapMatrix.size(); ++i) + for (std::set::iterator it1 = segmentNumbers.begin(); + it1 != segmentNumbers.end(); + it1++) { - m_segmentOverlapMatrix[i][i] = 0; + for (std::set::iterator it2 = segmentNumbers.begin(); + it2 != segmentNumbers.end(); + it2++) + { + if (*it1 == *it2) + { + m_segmentOverlapMatrix[*it1][*it2] = 0; + } + else + { + m_segmentOverlapMatrix[*it1][*it2] = -1; + } + } } + // Go through all logical frame positions, and compare all segments at each position size_t index1, index2; index1 = index2 = 0; @@ -625,12 +625,12 @@ OFCondition OverlapUtil::buildOverlapMatrix() { DCMSEG_DEBUG("getOverlappingSegments(): Comparing segments at logical frame position " << i); // Compare all segments at this position - for (std::set::iterator it = m_segmentsByPosition[i].begin(); + for (SegmentsByPosition::value_type::iterator it = m_segmentsByPosition[i].begin(); it != m_segmentsByPosition[i].end(); ++it) { index1++; - for (std::set::iterator it2 = m_segmentsByPosition[i].begin(); + for (SegmentsByPosition::value_type::iterator it2 = m_segmentsByPosition[i].begin(); it2 != m_segmentsByPosition[i].end(); ++it2) { @@ -643,7 +643,7 @@ OFCondition OverlapUtil::buildOverlapMatrix() { // Check if we already have found an overlap on another logical frame, and if so, skip Sint8 existing_result - = m_segmentOverlapMatrix[(*it).m_segmentNumber - 1][(*it2).m_segmentNumber - 1]; + = m_segmentOverlapMatrix[(*it).m_segmentNumber][(*it2).m_segmentNumber]; if (existing_result == 1) { DCMSEG_DEBUG("getOverlappingSegments(): Skipping frame comparison on pos #" @@ -671,21 +671,25 @@ OFCondition OverlapUtil::buildOverlapMatrix() } // Enter result into overlap matrix - m_segmentOverlapMatrix[(*it).m_segmentNumber - 1][(*it2).m_segmentNumber - 1] = overlap ? 1 : 0; - m_segmentOverlapMatrix[(*it2).m_segmentNumber - 1][(*it).m_segmentNumber - 1] = overlap ? 1 : 0; + m_segmentOverlapMatrix[(*it).m_segmentNumber][(*it2).m_segmentNumber] = overlap ? 1 : 0; + m_segmentOverlapMatrix[(*it2).m_segmentNumber][(*it).m_segmentNumber] = overlap ? 1 : 0; } } } } // Since we don't compare all segments (since not all are showing up together on a single logical frame), // we set all remaining entries that are still not initialized (-1) to 0 (no overlap) - for (size_t i = 0; i < m_segmentOverlapMatrix.size(); ++i) + for (std::set::iterator it1 = segmentNumbers.begin(); + it1 != segmentNumbers.end(); + it1++) { - for (size_t j = 0; j < m_segmentOverlapMatrix[i].size(); ++j) + for (std::set::iterator it2 = segmentNumbers.begin(); + it2 != segmentNumbers.end(); + it2++) { - if (m_segmentOverlapMatrix[i][j] == -1) + if (m_segmentOverlapMatrix[*it1][*it2] == -1) { - m_segmentOverlapMatrix[i][j] = 0; + m_segmentOverlapMatrix[*it1][*it2] = 0; } } }