【C#】使用fo-dicom完成BMP,JPG,PNG图片转换为DICOM文件

最近研究了一下DICOM和BMP文件转换的问题,也是很头大。度娘了很久,也在CSDN等论坛看到一些断断续续的文件,最主要的是代码只是片断,不是完整的实现。头大了。
首先,了解一下BMP文件格式,BMP文件的显示是从左下开始显示,而DICOM显示图像是从左上开始。所以如果你直接解析BMP文件的话,记得数据区工反转一下,否则生成DICOM时看到的图像是倒着的。只需要反转BMP图像的行,列不需要反转。
不过好在Microsoft的C#给我们提供了一个较好的类库叫Bitmap类,使用它可以不用管这个反转了。
首先要从BMP图中获取图像数据区,代码如下:

        public static byte[] GetPixels(Bitmap bitmap)
        {
            byte[] bytes = new byte[bitmap.Width * bitmap.Height*3];
            int wide = bitmap.Width;
            int i = 0;
            int height = bitmap.Height;
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < wide; x++)
                {
                    var srcColor = bitmap.GetPixel(x, y);
                    //bytes[i] = (byte)(srcColor.R * .299 + srcColor.G * .587 + srcColor.B * .114);
                    bytes[i] = srcColor.R;
                    i++;
                    bytes[i] = srcColor.G;
                    i++;
                    bytes[i] = srcColor.B;
                    i++;
                }
            }
            return bytes;
        }

申请的数据为什么是图像的宽高乘积的3倍,这是因为R,G,B各占一个Byte。如果采用上面代码中注释的行,生成的DICOM文件图像就是灰度图像(黑白图了)。
然后是真正的转存DICOM文件了。代码如下:

        public static void ImportImage(string file)
        {
            Bitmap bitmap = new Bitmap(file);
            //bitmap = GetValidImage(bitmap);


            byte[] pixels = GetPixels(bitmap);
            MemoryByteBuffer buffer = new MemoryByteBuffer(pixels);
            DicomDataset dataset = new DicomDataset();
            //FillDataset(dataset);
            dataset.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Rgb.Value);
            dataset.Add(DicomTag.Rows, (ushort)bitmap.Height);
            dataset.Add(DicomTag.Columns, (ushort)bitmap.Width);
            dataset.Add(DicomTag.BitsAllocated, (ushort)8);
            dataset.Add(DicomTag.SOPClassUID, "1.2.840.10008.5.1.4.1.1.2");
            dataset.Add(DicomTag.SOPInstanceUID, "1.2.840.10008.5.1.4.1.1.2.20181120090837121314");
            DicomPixelData pixelData = DicomPixelData.Create(dataset, true);
            pixelData.BitsStored = 8;
            //pixelData.BitsAllocated = 8;
            pixelData.SamplesPerPixel = 3;
            pixelData.HighBit = 7;
            pixelData.PixelRepresentation = 0;
            pixelData.PlanarConfiguration = 0;
            pixelData.AddFrame(buffer);

            DicomFile dicomfile = new DicomFile(dataset);
            dicomfile.Save(@"e:\dicomfile.dcm");
            SaveDicomFile2(pixels, bitmap.Height, bitmap.Width);
        }

其中传入参数就是BMP/JPG/PNG图像的路径。这样你只需要一个入口程序(比如控制台的Main函数)就可以将一个图片转为DICOM还是彩色的。
这里只设置了DICOM必须的几个字段,这几个字段的意义可以参考官方标准说明。部分说明如下:
DICOM文件格式:
1)Samples Per Pixel:

    标签为(0028,0002),具体的介绍在DICOM3.0标准第3部分的附录C7.6.3.1。含义表示【the number of separate planes in this image】,就像PhotoShop中的通道,每个通道表示一种颜色(除了RGB三个通道以外,也会存在第四个通透性通道)。对于灰度图像(monochrome或gray)和颜色表图像(palette,就是BMP格式中介绍的有调色板的BMP文件),该标签值为1,RGB图像或其他色彩模式图像,该标签值为3。本实例中使用的BMP图像是RGB格式的,因此SamplePerPixel=3,起初的文件格式错误就是由于该字段设置为1所致。

2)Photometric Interpretation:

    标签为(0028,0004),具体介绍在DICOM3.0标准第3部分的附录C7.6.3.1.2。该字段常见的值有MONOCHROME1、MONOCHROME2、PALETTE COLOR、RGB,其中MONOCHROME1和MONOCHROME2表示单通道灰度图像,只是两者对黑色和白色的映射相反而已;PALETTE COLOR就是BMP中提到的调色板图像,此时需要SamplesPerPixel字段为1,;RGB是常见的R(红)、G(绿)、B(蓝)三通道彩色图像,此时SamplesPerPixel字段值为3,这就是我们实例中使用的图像。除此以外DICOM3.0标准中还给出了YBR_FULL、HSV、ARGB、CMYK等方式,此处就不详细介绍了。

3)Planar Configuration:

    标签为(0028,0006),具体介绍在DICOM3.0标准第3部分附录C7.6.3.1.3。当Samples Per Pixel字段的值大于1时,Planar Configuration字段规定了实际像素信息的存储方式,具体如下:

20150727112322434
BitsAllocated 每一种颜色值所分配的存储位数,一般彩色是8,灰度可以设置到16,不能大于16。
BitsStored 像素值的实际存储位数
HighBit 像素值存储的最高位(一般是BitsStored-1)。
关于BMP文件格式说明可参照:https://blog.csdn.net/zjq_1314520/article/details/53830349

  • 0
    点赞
  • 1
    评论
  • 6
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值