You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需临时保存未压缩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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 14:20:05