如何正确地将dicom图像转换为opencv

时间:2017-08-08 23:20:30

标签: image opencv bitmap dicom dcmtk

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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

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

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

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

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