【问题标题】:How to properly convert dicom image to opencv如何正确地将dicom图像转换为opencv
【发布时间】:2017-08-08 23:20:30
【问题描述】:

我在将 .dcm 图像从 dcmtk 格式转换为 opencv 时遇到问题。 我的代码:

DicomImage dcmImage(in_file.c_str());
int depth = dcmImage.getDepth();
std::cout << "bit-depth: " << depth << "\n";    //this outputs 10
Uint8* imgData = (uchar*)dcmImage.getOutputData(depth);
std::cout << "size: " << dcmImage.getOutputDataSize() << "\n";    //this outputs 226100
cv::Mat image(int(dcmImage.getWidth()), int(dcmImage.getHeight()), CV_32S, imgData);
std::cout << dcmImage.getWidth() << " " << dcmImage.getHeight() << "\n";  //this outputs 266 and 425

imshow("image view", image);  //this shows malformed image

所以我不确定CV_32SgetOutputData 参数。我应该放什么?也是 226100/(266*425) == 2 所以它应该是 2 字节前像素 (?)

【问题讨论】:

    标签: image opencv bitmap dicom dcmtk


    【解决方案1】:

    当 getDepth() 返回 10 时,这意味着每个像素有 10 位(很可能是灰度)。

    根据 DICOM 图像的像素表示 (0x0028,0x0103),您必须为矩阵类型指定有符号或无符号 16 位整数: CV_16UC2 或 CV_16SC2。

    注意:由于只使用了 2 字节的 10 位,您可能会在高 6 位中发现垃圾,在将缓冲区传递给垫子之前应该将其屏蔽掉。

    更新: 关于你的 cmets 和你的源代码:

    1. DicomImage::getInterData()::getPixelRepresentation() 不会返回在 DICOM 标头中找到的像素表示,而是同时表示位深度和有符号/无符号的内部枚举。要获取标头中的值 - 使用 DcmDataset 或 DcmFileFormat
    2. 我不是 openCV 专家,但我认为您将 8 位位掩码应用于无法正常工作的 16 位图像
    3. 位掩码应为 (1 >> 11) - 1

    【讨论】:

    • 感谢您的回答!好的,我试着玩了一下,但没有结果。我可能什么都没有。我的代码:pastebin.com/NGsUn3tN 我不知道为什么,但表示是 2,它应该是 0 或 1(无符号/签名)。而且我也不确定将 (1
    • 还有一个问题:我是否将 DICOM 图像的像素表示提取为 dcmImage.getInterData()->getRepresentation() 正确?
    • 相应地更新了我的答案
    【解决方案2】:

    问题是您是否真的需要 DicomImage::getOutputData() 返回的渲染像素数据,或者您是否需要来自 DICOM 图像的原始像素数据(另请参阅@kritzel_sw 的答案)。使用 getOutputData() 时,您应该将请求的位深度作为参数传递(例如,每个样本 8 位),而不是 getDepth() 返回的值。

    在处理 CT 图像时,您可能希望使用以 Hounsfield 单位表示的像素数据(这是一个有符号整数值,是 Modality LUT 转换的结果)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-06
      • 2019-11-23
      • 2020-04-27
      • 1970-01-01
      相关资源
      最近更新 更多