I am using dcmtk
to read a dicom. This dicom file contains 100 image. Each image has a PatientPosition
. How can I get these 100 PatientPosition
?
If DicomImage
can provide the 100 PatientPosition
?
If findAndGetSequenceItem
can provide the 100 PatientPosition
?
Hope some c++ code to fetch 100 PatientPosition
.
Any suggestion is appreciated~~~
I assume that you are referring to an enhanced DICOM object (e.g. Enhanced CT Image, Enhanced MR Image or the like). In this case the frame-specific tags can be found in the Per-Frame Functional Group Sequence (the link show the reference for an Enhanced MR Image). Each item of the sequence refers to a separate frame.
I also assume that by PatientPosition
you actually mean PatientPositionPatient
, which would be the related tag for MR, CT and a few other types of images, but the handling of frame-specific tags is the same regardless of the tag. Each frame-specific tag is embedded into another sequence, which groups together related tags - in the case of PatientPositionPatient
this is the Plane Position Sequence. As dcmtk allows to search for tags recursively in sub-sequences, you even don't have to know that - it is enough to search for the tag in the relevant sequence item:
auto dcmFile = new DcmFileFormat;
auto cond = dcmFile->loadFile(filePath);
if (cond.good()) {
// load the dataset from the DICOM file
auto* dataset = dcmFile->getDataset();
DcmSequenceOfItems* sequence;
// search for the per-frame functional groups sequence
OFResult result = dataset->findAndGetSequence(DCM_PerFrameFunctionalGroupsSequence, sequence);
if (result.good() && sequence && !sequence->isEmpty()) {
// iterate over all items until none remains
// this will correspond to the number of frames
for (int frameNr = 0;; ++frameNr) {
auto* item = sequence->getItem(frame);
if (!item) { // could instead get NumberOfFrames first
break;
}
// Image Position Patient has 3 components
double pos[3];
for (i = 0; i < 3; ++i) {
// findAndGetFloat64 automatically converts the strings to double
if (!item->findAndGetFloat64(DCM_ImagePositionPatient, pos, i, /*searchIntoSub=*/OFTrue ).good()) {
// do some error handling here
}
}
// do something sensible with the result
std::cout << "Position: " << pos[0] << ", " << pos[1] << ", " << pos[2];
}
}
}
Note that this is just out of my head and may contain errors. In reality, you need at least better error handling, you will probably directly access the tag in the containing sequence instead of recursively searching for it, and of course save the position somewhere sensible.