1

我在将 .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 字节前像素(?)

4

2 回答 2

1

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

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

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

更新: 关于您的评论和源代码:

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

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

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

于 2017-08-10T13:50:15.663 回答