如何无需临时保存未压缩DICOM,直接保存JPEG Process 14压缩DICOM?
问题:直接保存JPEG Process 14压缩DICOM失败,报错“Pixel representation not found”
我有一个继承自DcmDataset类的DicomInterface类,设置好DICOM标签后,希望以JPEG Process 14传输语法保存DICOM图像。目前通过先保存临时未压缩DICOM再加载转换的方式可以实现,但省略临时步骤直接保存时会报错“Pixel representation not found”。
可行的临时文件实现代码
void DicomInterface::SaveDicom(const QString &patient_name, const QString &study_number, const QString &img_name){ DcmFileFormat file_format(this); std::string dcm_path = GetSaveDicomPath(patient_name, study_number, img_name); DJEncoderRegistration::registerCodecs(); // Compress DJ_RPLossless representation_parameter; // Save temporal dicom with EXS_LittleEndianExplicit file_format.saveFile(dcm_path.c_str(), EXS_LittleEndianExplicit); // Load the temporal file OFCondition status = file_format.loadFile(dcm_path.c_str()); DcmDataset *dataset = file_format.getDataset(); // Save compressed Dicom status = dataset->chooseRepresentation(EXS_JPEGProcess14SV1, &representation_parameter); status = file_format.saveFile(dcm_path.c_str(), EXS_JPEGProcess14SV1); if (status.bad()) { qDebug() << "\n Error: cannot write DICOM file (" << status.text() << ")"; } DJEncoderRegistration::cleanup(); }
失败的直接保存代码
void DicomInterface::SaveDicom(const QString &patient_name, const QString &study_number, const QString &img_name){ DcmFileFormat file_format(this); std::string dcm_path = GetSaveDicomPath(patient_name, study_number, img_name); DJEncoderRegistration::registerCodecs(); // Compress DJ_RPLossless representation_parameter; status = chooseRepresentation(EXS_JPEGProcess14SV1, &representation_parameter); status = file_format.saveFile(dcm_path.c_str(), EXS_JPEGProcess14SV1); if (status.bad()) { qDebug() << "\n Error: cannot write DICOM file (" << status.text() << ")"; } DJEncoderRegistration::cleanup(); }
解决方案
问题原因
报错“Pixel representation not found”是因为直接调用chooseRepresentation时,数据集内的像素数据相关元信息(如PixelRepresentation、位深等)未完成内部初始化。临时保存再加载的过程会触发DCMTK对数据集的完整解析,自动初始化这些元信息,因此能正常执行压缩操作。
修改后的直接保存代码
void DicomInterface::SaveDicom(const QString &patient_name, const QString &study_number, const QString &img_name){ DcmFileFormat file_format(this); std::string dcm_path = GetSaveDicomPath(patient_name, study_number, img_name); DJEncoderRegistration::registerCodecs(); // 注册JPEG编解码器 DJ_RPLossless representation_parameter; // 关键步骤:强制加载所有数据到内存,完成元数据初始化 OFCondition status = loadAllDataIntoMemory(); if (status.bad()) { qDebug() << "\n Error: failed to load data into memory (" << status.text() << ")"; DJEncoderRegistration::cleanup(); return; } // 选择JPEG Process 14无损压缩表示 status = chooseRepresentation(EXS_JPEGProcess14SV1, &representation_parameter); if (status.bad()) { qDebug() << "\n Error: cannot choose compressed representation (" << status.text() << ")"; DJEncoderRegistration::cleanup(); return; } // 保存压缩后的DICOM文件 status = file_format.saveFile(dcm_path.c_str(), EXS_JPEGProcess14SV1); if (status.bad()) { qDebug() << "\n Error: cannot write DICOM file (" << status.text() << ")"; } DJEncoderRegistration::cleanup(); }
关键要点说明
loadAllDataIntoMemory():这个方法会遍历数据集所有元素(包括像素数据),确保数据被正确解析并加载到内存,初始化所有必要的内部状态,让chooseRepresentation能找到PixelRepresentation等关键元信息。- 确保必要标签已设置:需提前确认
PixelRepresentation(0x0028,0x0003)、BitsAllocated(0x0028,0x0100)、BitsStored(0x0028,0x0101)、HighBit(0x0028,0x0102)、Rows(0x0028,0x0010)、Columns(0x0028,0x0011)等图像相关标签已正确配置,这些是JPEG压缩器正常工作的前提。
内容的提问来源于stack exchange,提问作者Phạm Hồng Nhung
相关产品推荐
相关产品推荐

