Skip to content

Commit

Permalink
Merge pull request QIICR#484 from michaelonken/switch_to_framesorter_…
Browse files Browse the repository at this point in the history
…class

Switch to framesorter class
  • Loading branch information
fedorov authored Dec 6, 2023
2 parents 7ae0873 + 3614ed3 commit c9738ca
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 136 deletions.
5 changes: 1 addition & 4 deletions include/dcmqi/OverlapUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,7 @@ class OverlapUtil
void printNonOverlappingSegments(OFStringStream& ss);

protected:
/** Collect all physical frame positions in m_FramePositions
* @return EC_Normal if successful, error otherwise
*/
OFCondition collectPhysicalFramePositions();


/** Group physical frame positions into logical positions. This is done by sorting
* frames after *that* position coordinate that in its mean position difference is
Expand Down
60 changes: 47 additions & 13 deletions include/dcmqi/framesorter.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
#include <stdlib.h>
#include <math.h>

typedef OFVector<Float64> ImagePosition; // Image Position Patient
typedef OFPair<Uint32, Float64> FrameWithPos; // DICOM frame number and Image Position Patient

/** Abstract class for sorting a set of frames in a functional group. The
* sorting criteria are up to the actual implementation classes.
*/
Expand Down Expand Up @@ -69,7 +72,11 @@ class FrameSorter
/// The error code should be set in any case (default: EC_Normal)
OFCondition errorCode;
/// The frame numbers, in sorted order (default: empty)
OFVector<Uint16> frameNumbers;
OFVector<Uint32> frameNumbers;
/// The frame positions, in sorted order, if provided
/// by the sorter (default: empty). If not empty, contains the same number
/// of items as frameNumbers.
OFVector<ImagePosition> framePositions;
/// Tag key that contains the information that was crucial for sorting.
/// This is especially useful for creating dimension indices. Should be
/// set to (0xffff,0xfff) if none was used (default).
Expand All @@ -87,6 +94,11 @@ class FrameSorter
OFString fgPrivateCreator;
};

struct FramePositions
{
OFVector<ImagePosition> positions;
};

/** Default constructor, does nothing
*/
FrameSorter(){};
Expand Down Expand Up @@ -126,6 +138,12 @@ class FrameSorter
FGInterface* m_fg;
};

/** Dummy sorter implementing the FrameSorter interface,
* but not doing any sorting at all. As a result it provides
* a list of frames in their natural order, as found in the underlying
* DICOM dataset. The results will not contain frame position
* to make this implementation as lightweight and "stupid" as possible.
*/
class FrameSorterIdentity : public FrameSorter
{

Expand All @@ -143,7 +161,11 @@ class FrameSorterIdentity : public FrameSorter
return "Returns frames in the order defined in the functional group, i.e. as defined in the image file";
}


/** Performs actual sorting. Does only set Results.frameNumbers and errorCode,
* leaving the rest untouched.
* @param results The results produced by dummy sorter (list of frame numbers as
* found in the underlying DICOM dataset, and EC_Normal as error code)
*/
virtual void sort(Results& results)
{
if (m_fg == NULL)
Expand All @@ -168,6 +190,11 @@ class FrameSorterIdentity : public FrameSorter

};

/** Sorter implementing the FrameSorter interface that sorts frames
* by their Image Position (Patient) attribute. The sorting is done
* by projecting the Image Position (Patient) on the slice direction
* (as defined by the Image Orientation (Patient) attribute).
*/
class FrameSorterIPP : public FrameSorter
{
public:
Expand All @@ -179,10 +206,15 @@ class FrameSorterIPP : public FrameSorter
frameId()
{}

Float32 key;
unsigned frameId;
/// The key relevant for sorting
Float64 key;
/// The DICOM frame number
Uint32 frameId;
/// The frame position as found in Image Position (Patient)
ImagePosition framePos;
};


FrameSorterIPP(){};

~FrameSorterIPP(){};
Expand All @@ -201,7 +233,7 @@ class FrameSorterIPP : public FrameSorter
return;
}

OFVector<Float32> dirX, dirY;
OFVector<Float64> dirX, dirY;
OFString orientStr;
for(int i=0;i<3;i++){
if(planorfg->getImageOrientationPatient(orientStr, i).good()){
Expand Down Expand Up @@ -253,7 +285,7 @@ class FrameSorterIPP : public FrameSorter
return;
}

OFVector<Float32> sOrigin;
ImagePosition sOrigin;
for(int j=0;j<3;j++){
OFString planposStr;
if(planposfg->getImagePositionPatient(planposStr, j).good()){
Expand All @@ -264,17 +296,19 @@ class FrameSorterIPP : public FrameSorter
}
}

Float32 dist;
Float64 dist;
dist = dot(sliceDirection, sOrigin);
orderedFrameItems[frameId].key = dist;
orderedFrameItems[frameId].frameId = frameId;
orderedFrameItems[frameId].framePos = sOrigin;
}

qsort(&orderedFrameItems[0], numFrames, sizeof(OrderedFrameItem), &compareIPPKeys);

for(Uint32 count=0;count<numFrames;count++)
{
results.frameNumbers.push_back(orderedFrameItems[count].frameId);
results.framePositions.push_back(orderedFrameItems[count].framePos);
}

delete [] orderedFrameItems;
Expand All @@ -284,20 +318,20 @@ class FrameSorterIPP : public FrameSorter

private:

OFVector<Float32> cross_3d(OFVector<Float32> v1, OFVector<Float32> v2){
OFVector<Float32> result;
OFVector<Float64> cross_3d(OFVector<Float64> v1, OFVector<Float64> v2){
OFVector<Float64> result;
result.push_back(v1[1]*v2[2]-v1[2]*v2[1]);
result.push_back(v1[2]*v2[0]-v1[0]*v2[2]);
result.push_back(v1[0]*v2[1]-v1[1]*v2[0]);

return result;
}

Float32 dot(OFVector<Float32> v1, OFVector<Float32> v2){
return Float32(v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]);
Float64 dot(OFVector<Float64> v1, OFVector<Float64> v2){
return Float64(v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]);
}

void normalize(OFVector<Float32> &v){
void normalize(OFVector<Float64> &v){
double norm = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
v[0] = v[0]/norm;
v[1] = v[1]/norm;
Expand All @@ -306,7 +340,7 @@ class FrameSorterIPP : public FrameSorter

static int compareIPPKeys(const void *a, const void *b);

OFVector<Float32> sliceDirection;
OFVector<Float64> sliceDirection;

};

Expand Down
Loading

0 comments on commit c9738ca

Please sign in to comment.