繁体   English   中英

如何从dicom文件中读取二进制数据?

[英]How to read binary data from dicom file?

如何从未压缩的 DICOM 文件中读取原始图像数据并将其转储到文件中。 我只是将以下代码用于压缩文件。 使用 dcmtk 库

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;

如何使用 dcmtk 库从 C++ 中具有许多帧的未压缩文件中获取原始图像数据.....?

基本上,您可以使用相同的代码,但无需压缩(这实际上是更简单的情况...)

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;

(这是我的头脑,所以不能保证完整性)
你得到的是原始二进制数据。 如果要从中创建像 JPG 这样的图像文件,则需要相应的图像功能,尽管这与 dcmtk 无关。

如果您知道图像未压缩,那么您可以使用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

如果您需要第二帧或图像被压缩,那么您应该使用 imebra::DataSet::getImage() 并让 imebra 找到合适的内存区域并为您解压缩图像。

请注意,连续的未压缩图像未在字节边界上对齐,但第二帧的第一位可能位于包含第一帧最后一位的同一字节上。 对于压缩图像,您可能必须处理指向包含图像的缓冲区的偏移表。

免责声明:我是 Imebra 的作者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM