【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字段规定了实际像素信息的存储方式,具体如下:
BitsAllocated 每一种颜色值所分配的存储位数,一般彩色是8,灰度可以设置到16,不能大于16。
BitsStored 像素值的实际存储位数
HighBit 像素值存储的最高位(一般是BitsStored-1)。
关于BMP文件格式说明可参照:https://blog.csdn.net/zjq_1314520/article/details/53830349
- 点赞
- 收藏
- 关注作者
评论(0)