To parse and display a DCM image, it is necessary to parse part of its label information first.

There are three types of tag confidence: Meta Info, normal tag, and pixel Tag, which are read as needed

Reading dicOM tags using DCMKT is a simple matter

Meata Info tag read

Meta information in group 0002

There are three ways to read, the simplest of which is shown here

    DcmMetaInfo metainfo;
    OFCondition status;
    status = metainfo.loadFile("G:/dicomFile/3.dcm");

    if (status.good())
    {
        OFString sopClassUID, xferUID;
        if (metainfo.findAndGetOFString(DCM_MediaStorageSOPClassUID, sopClassUID).good())
            COUT << "SOP Class UID: " << sopClassUID << OFendl;
        if (metainfo.findAndGetOFString(DCM_TransferSyntaxUID, xferUID).good())
            COUT << "Transfer Syntax UID: " << xferUID << OFendl;

        metainfo.print(COUT);
    }
Copy the code

Output result information:

The SOP Class UID: 1.2.840.10008.5.1.4.1.1.2 Transfer Syntax UID: 1.2.840.10008.1.2.4.51 # dicom-meta-information -Header # Used TransferSyntax: Little Endian Explicit (0002000), UL 202 # 4, 1 FileMetaInformationGroupLength (0002000 1) OB 00, 01 # 2, 1 FileMetaInformationVersion (0002000 2) UI = CTImageStorage # 26. 1 MediaStorageSOPClassUID (0002000 3) UI [1.2.276.0.7230010.3.1.4.2012715.17328.1511764633.841627] # 56. 1 MediaStorageSOPInstanceUID (0002001) UI = JPEGExtended: Process2 + 4 # 22. 1 TransferSyntaxUID (0002001 2) UI 1.2.276.0.7230010.3.0.3.6.1 # 28, 1 ImplementationClassUID (0002001 3) SH OFFIS_DCMTK_361 # 16, 1 ImplementationVersionNameCopy the code

Official Reference Materials

Normal Tag reading

Take reading a patient’s name as an example

DcmFileFormat dcmFormat; OFCondition ofResult = dcmFormat.loadFile("G:/dicomFile/3.dcm"); if (! ofResult.good()) { qDebug() << "dcmFormat read fail..." << ofResult.text(); return false; } DcmDataset *pDataSet = dcmFormat.getDataset(); if (nullptr == pDataSet) { return false; } OFString strPatientName; ofResult = pDataSet->findAndGetOFString(DCM_PatientName, strPatientName); if (! ofResult.good()) { return false; } qDebug() << "patientName:" << strPatientName.c_str();Copy the code

Results output

patientName: Zhang xxx
Copy the code

In actual development, parsing needs to correspond to different types and encapsulate corresponding parsing methods separately

For example, parsing a string tag

bool getStringTagValue(DcmDataset* pDataSet,const DcmTag& pTag, QString &value) { if (nullptr == pDataSet) { return false; } const char* strValue = nullptr; Uint32 lLength = 0; OFCondition ofResult = pDataSet->findAndGetString(pTag, strValue, lLength); if (! ofResult.good()) { return false; } value = QLatin1String(strValue, lLength); return true; }Copy the code

Such as parsing a floating point tag

bool getU16TagValue(DcmDataset* pDataSet,const DcmTag& pTag, quint16 &nValue)
{
    Uint16	uint16 = 0;

    if ( pDataSet->findAndGetUint16( pTag, uint16).good() )
    {
        nValue = uint16;

        return true;
    }

    return false;
}
Copy the code

The DcmFileFormat object contains Pointers to DcmMetaInfo and DcmDataset objects, which are automatically created in the initial constructor and stored in a double-linked list

DcmFileFormat::DcmFileFormat()
  : DcmSequenceOfItems(InternalUseTag),
    FileReadMode(ERM_autoDetect)
{
    DcmMetaInfo *MetaInfo = new DcmMetaInfo();
    DcmSequenceOfItems::itemList->insert(MetaInfo);
    MetaInfo->setParent(this);

    DcmDataset *Dataset = new DcmDataset();
    DcmSequenceOfItems::itemList->insert(Dataset);
    Dataset->setParent(this);
}
Copy the code

conclusion

Of course, the above method is to use DCMTK open source library to read, their own wheels can also be read step by step, is a bit more trouble

GitHub has a long open source project QDCM, also based on Qt implementation, can refer to

Github.com/Archie3d/qd…

Such as reading a file to determine whether it contains header code

bool DcmFile::hasHeader(const QString &path) { QFile file(path); if (! file.open(QFile::ReadOnly)) { return false; } QDataStream ds(&file); int s = ds.skipRawData(128); if (s ! = 128) { file.close(); return false; } char signature[4]; s = ds.readRawData(signature, 4); if (s ! = 4) { file.close(); return false; } file.close(); if (signature[0] == 'D' && signature[1] == 'I' && signature[2] == 'C' && signature[3] == 'M') { return true; } return false; }Copy the code