博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【C#】使用fo-dicom完成BMP,JPG,PNG图片转换为DICOM文件
阅读量:6715 次
发布时间:2019-06-25

本文共 3554 字,大约阅读时间需要 11 分钟。

最近研究了一下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文件格式说明可参照:

转载地址:http://meelo.baihongyu.com/

你可能感兴趣的文章
E - Trees on the level
查看>>
【CSS3】Advanced9:Transformation
查看>>
博客搬家
查看>>
实例化物体
查看>>
漢譯Promises/A+規範
查看>>
IO阻塞与IO非阻塞2
查看>>
设计模式——桥接模式
查看>>
1120: 最值交换
查看>>
windows 系统变量大全
查看>>
GL_GL系列 - 会计科目管理分析(案例)(未完成)
查看>>
python逻辑运算符
查看>>
线段树模板(洛谷P3372)
查看>>
django02配置相关
查看>>
SCU4436 Easy Math
查看>>
git LF CRLF
查看>>
Beta阶段对团队成员公开感谢
查看>>
2016年终总结
查看>>
KindEditor
查看>>
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".错误的解决方法
查看>>
图像处理之基础---卷积,滤波,平滑
查看>>