C++中有没有替代np.concatenate实现DICOM图像通道拼接的方法?
问题结论
cv::merge的功能就是将多个单通道cv::Mat沿通道维度拼接为多通道Mat,和np.concatenate(axis=2)对单通道数组的拼接效果完全一致,你遇到的结果差异是代码其他逻辑错误导致的,和merge功能无关。
代码错误点
- OpenCV Mat构造参数顺序错误
OpenCV的cv::Mat构造函数参数顺序为Mat(行数, 列数, 类型, 数据指针),其中行数对应图像高度nHeight,列数对应图像宽度nWidth。你的代码里写反了宽高参数,写成Mat(nWidth, nHeight, CV_8UC1, pixeldata_brain),会导致图像直接转置变形,是结果差异的核心原因之一。 - 窗处理逻辑重复且错误
Python代码中是直接对经RescaleSlope、RescaleIntercept转换后的HU值做窗宽窗位裁剪、归一化。而你使用DCMTK的DicomImage::setWindow()设置窗参数后,调用getOutputData(8)已经自动完成了HU值到0-255 Uint8灰度的映射,后续你又对已经映射完成的8位像素做了一次裁剪和归一化,属于重复错误处理,和Python逻辑完全不匹配。 - 冗余的split操作
不需要先创建空三通道Mat再split赋值,直接将三个单通道Mat放入vector调用merge即可,属于不影响结果的冗余代码。
修正方案
- 修正所有Mat构造的宽高参数,将
Mat(nWidth, nHeight, ...)全部替换为Mat(nHeight, nWidth, ...) - 删除
getOutputData(8)之后的像素遍历处理逻辑,直接使用返回的Uint8数据构造单通道Mat即可;如果需要完全对齐Python逻辑,可以直接读取原始16位像素,自行计算HU值、做窗处理。 - 简化merge调用:
vector<Mat> channels; channels.push_back(brain); // B通道,和Python拼接顺序对应 channels.push_back(subdural);// G通道 channels.push_back(bone); // R通道 cv::merge(channels, image);
上述代码实现的效果和np.concatenate([b,g,r], axis=2)完全一致。
内容的提问来源于stack exchange,提问作者許煜承 Wistar
相关产品推荐
相关产品推荐

