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).