findAndGetString() in DCMTK returns null for the tag

1.9k Views Asked by At

I am developing a quick DICOM viewer using DCMTK library and I am following the example provided in this link.

The buffer from the API always returns null for any tag ID, eg: DCM_PatientName. But the findAndGetOFString() API works fine but returns only the first character of the tag in ASCII, is this how this API should work?

Can someone let me know why the buffer is empty the former API?

Also the DicomImage API also the same issue.

Snippet 1:

DcmFileFormat fileformat;
OFCondition status = fileformat.loadFile(test_data_file_path.toStdString().c_str());
if (status.good())
{
   OFString  patientName;
   char* name;
   if (fileformat.getDataset()->findAndGetOFString(DCM_PatientName, patientName).good())
    {
      name = new char[patientName.length()];
      strcpy(name, patientName.c_str());
    }
    else
    {
      qDebug() << "Error: cannot access Patient's Name!";
    }
 } 
 else
 {
    qDebug() << "Error: cannot read DICOM file (" << status.text() << ")";
 }

In the above snippet name has the ASCII value "50" and the actual name is "PATIENT".

Snippet 2:

DcmFileFormat file_format;  
OFCondition status = file_format.loadFile(test_data_file_path.toStdString().c_str());
std::shared_ptr<DcmDataset> dataset(file_format.getDataset());
qDebug() << "\nInformation extracted from DICOM file: \n";
const char* buffer = nullptr;
DcmTagKey key = DCM_PatientName;
dataset->findAndGetString(key,buffer);
std::string tag_value = buffer;
qDebug() << "Patient name: " << tag_value.c_str();

In the above snippet, the buffer is null. It doesn't read the name.

NOTE:

This is only a sample. I am just playing around the APIs for learning purpose.

2

There are 2 best solutions below

6
On

The following sample method reads the patient name from a DcmDataset object:

std::string getPatientName(DcmDataset& dataset)
{
    // Get the tag's value in ofstring
    OFString ofstring;
    OFCondition condition = dataset.findAndGetOFString(DCM_PatientName, ofstring);
    if(condition.good())
    {
        // Tag found. Put it in a std::string and return it
        return std::string(ofstring.c_str());
    }

    // Tag not found
    return ""; // or throw if you need the tag
}
0
On

I have tried your code with your datasets. I just replaced the output to QT console classes to std::cout. It works for me - i.e. it prints the correct patient name (e.g. "PATIENT2" for scan2.dcm). Everything seems correct, except for the fact that you apparently want to transfer the ownership for the dataset to a smart pointer.

To obtain the ownership for the DcmDataset from the DcmFileFormat, you must call getAndRemoveDataset() instead of getDataset(). However, I do not think that your issue is related that. You may want to try my modified snippet:

DcmFileFormat file_format;
OFCondition status = file_format.loadFile("d:\\temp\\StackOverflow\\scan2.dcm");
std::shared_ptr<DcmDataset> dataset(file_format.getAndRemoveDataset());
std::cout << "\nInformation extracted from DICOM file: \n";
const char* buffer = nullptr;
DcmTagKey key = DCM_PatientName;
dataset->findAndGetString(key, buffer);
std::string tag_value = buffer;
std::cout << "Patient name: " << tag_value.c_str();

It probably helps you to know that your code and the dcmtk methods you use are correct, but that does not solve your problem. Another thing I would recommend is to verify the result returned by file_format.loadFile(). Maybe there is a surprise in there.

Not sure if I can help you more, but my next step would be to verify your build environment, e.g. the options that you use for building dcmtk. Are you using CMake to build dcmtk?