1
votes

How to read raw image data from uncompressed DICOM file and dump it to a file. I just use the following code for compressed files. using dcmtk library

dataSet->findAndGetElement(DCM_PixelData, element);
pixDataElem = OFstatic_cast(DcmPixelData*, element);

DcmPixelSequence *pixelSequence = NULL;
E_TransferSyntax tran_Syntax = EXS_Unknown;
const DcmRepresentationParameter *representation = NULL;

// Find the key that is needed to access the right representation of the data within DCMTK
pixDataElem->getOriginalRepresentationKey(tran_Syntax, representation);
//pixDataElem->getCurrentRepresentationKey(tran_Syntax, representation);

// Access original data representation and get result within pixel sequence
pixDataElem->getEncapsulatedRepresentation(tran_Syntax, representation, pixelSequence);


    DcmPixelItem *pixelItem = NULL;
    //Access the First frame by skipping the offset table...
    pixelSequence->getItem(pixelItem, 1);

    Uint8 *pixels = NULL;
    pixDataElem = (DcmPixelData*)pixelItem;
    pixDataElem->getUint8Array(pixels);
    Uint8 *pixels = NULL;
    pixDataElem->getUint8Array(pixels);
    //Writing the Raw data to a file...
    FILE *file;
    file = fopen("D:\\DicomImage.jpeg", "wb");
    fwrite(pixels, sizeof(char), imageSize, file);
    cout << "File write Completed and the File is closed Successfully" << endl;

How can I raw image data from the uncompressed files with many frames in c++ using dcmtk library.....?

2
Exactly the same way you read binary data from any other file: it's just a sequence of bytes. Unless you want to interpret the data somehow, in which case, you should probably explain that in the question.Useless
@Useless DICOM standard is rather different from the normal binary file. You can't just read byte sequence from a file and expect it to be an image.Long Nguyen
The question doesn't say anything about an image, which is why I asked for clarification. It says "read binary data" and "dump it to a file", which you can do with open, read and write.Useless
@Useless I see your point. He said something about "read binary pixel data", but I think it is easy to oversee that if you are not familiar with DICOM.Long Nguyen
@LongNguyen yes i need to read the raw image data from the uncompressed dicom file. can you help me ?gregory jithin

2 Answers

1
votes

Basically, you can use the same code, but without compression (this is actually the easier case...)

dataSet->findAndGetElement(DCM_PixelData, element);
pixDataElem = OFstatic_cast(DcmPixelData*, element);

Uint8 *pixels = NULL;
pixDataElem->getUint8Array(pixels);

//Writing the Raw data to a file...
FILE *file;
file = fopen("D:\\DicomImage.raw", "wb");
// frameSize is the size of a single frame
fwrite(pixels + frameSize * frameIndex, sizeof(char), frameSize, file);
cout << "File write Completed and the File is closed Successfully" << endl;

(this is out of my head, so no guarantee for completeness)
What you get, is the raw binary data. If you want to create an image file like JPG from that, you need the respective image functionality, though that has nothing to do with dcmtk.

0
votes

If you know that the images are not compressed, then you could access the first frame's raw data in this way with Imebra:

imebra::DataSet loadedDataSet = imebra::CodecFactory::Load("pathToFileName);

size_t imageWidth = loadedDataSet.getUint32(imebra::TagId(imebra::tagId_t::Columns_0028_0011), 0);
size_t imageHeight = loadedDataSet.getUint32(imebra::TagId(imebra::tagId_t::Rows_0028_0010), 0);
size_t channels = loadedDataSet.getUint32(imebra::TagId(imebra::tagId_t::SamplesPerPixel_0028_0002), 0);
size_t allocatedBits = loadedDataSet.getUint32(imebra::TagId(imebra::tagId_t::BitsAllocated_0028_0100), 0);
size_t totalSizeBytes = (imageWidth * imageHeight * allocatedBits * channels + 7) / 8;

ReadingDataHandlerNumeric rawData = loadedDataSet.getReadingDataHandlerNumeric(TagId(PixelData_7FE0_0010), 0);

size_t dataSize(0);
const char* pMemory = rawData.data(&dataSize);
// Now pMemory points to the raw data, dataSize holds the memory size

If you need the second frame or the images are compressed then you should use imebra::DataSet::getImage() and let imebra find the proper memory area and decompress the image for you.

Please note that consecutive uncompressed images are not aligned on byte boundary but the first bit of the second frame may be on the same byte containing the last bit of the first frame. For compressed images you may have to deal with a offset table pointing to the buffers containing the images.

Disclaimer: I'm the author of Imebra.