DICOM切片缩放后写入PixelData无显示问题求助
DICOM切片缩放后写入文件无内容问题
我正在处理分辨率为10241024(行列)的DICOM切片缩放操作,已成功完成缩放(保存为JPG能正常查看),但将缩放后的切片转换为字节数组写入DICOM文件后,无法看到任何内容。
原代码
var renderImage = new DicomImage(@"D:\11_29_2022_17_21_52\"+i); renderImage.Scale = 0.5;//缩放因子 Bitmap renderdImageAsBitmap =renderImage.RenderImage().As<Bitmap>(); renderdImageAsBitmap.Save(@"D:\test\"+i+".jpg", ImageFormat.Jpeg); //尝试过将图像转为JPG或Bitmap两种格式 using (IImage renderedImage = renderImage.RenderImage()) { Bitmap bitmap = renderedImage.As<Bitmap>(); // 通过MemoryStream将图像复制到字节数组 using (MemoryStream targetStream = new MemoryStream()) { bitmap.Save(targetStream, ImageFormat.Jpeg); newRawBytes = targetStream.ToArray(); // 获取图像字节数组用于写入DICOM文件 } } dicomFile.Dataset.AddOrUpdate(DicomTag.PixelData, newRawBytes); // 将字节数组添加到DICOM文件
问题原因
直接把JPEG格式的字节写入DICOM的PixelData标签是错误的:
- DICOM的像素数据有严格的格式要求,JPEG是压缩后的文件格式,包含文件头和编码信息,无法被DICOM阅读器直接解析为像素数据。
- 缩放后图像分辨率变为512512,但原DICOM的
Rows、Columns等元数据未更新,阅读器会用旧的10241024尺寸去解析新数据,导致显示异常。
解决方法
核心要点
- 同步更新DICOM元数据,匹配缩放后的图像尺寸和像素格式。
- 将图像转换为符合DICOM要求的原始像素格式字节数组,而非压缩的JPEG字节流。
修正后的代码示例
// 打开原始DICOM文件 var dicomFile = DicomFile.Open(@"D:\11_29_2022_17_21_52\" + i); var renderImage = new DicomImage(dicomFile.Dataset); renderImage.Scale = 0.5; // 获取缩放后的Bitmap using (var bitmap = renderImage.RenderImage().As<Bitmap>()) { // 将Bitmap转换为8位灰度的原始字节数组 var bitmapData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed ); var byteCount = bitmapData.Stride * bitmap.Height; var newRawBytes = new byte[byteCount]; System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, newRawBytes, 0, byteCount); bitmap.UnlockBits(bitmapData); // 更新DICOM元数据,匹配缩放后的图像 dicomFile.Dataset.AddOrUpdate(DicomTag.Rows, (ushort)bitmap.Height); dicomFile.Dataset.AddOrUpdate(DicomTag.Columns, (ushort)bitmap.Width); dicomFile.Dataset.AddOrUpdate(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Monochrome2); dicomFile.Dataset.AddOrUpdate(DicomTag.BitsAllocated, (ushort)8); dicomFile.Dataset.AddOrUpdate(DicomTag.BitsStored, (ushort)8); dicomFile.Dataset.AddOrUpdate(DicomTag.HighBit, (ushort)7); dicomFile.Dataset.AddOrUpdate(DicomTag.PixelRepresentation, (ushort)0); // 无符号整数 // 更新像素数据 dicomFile.Dataset.AddOrUpdate(DicomTag.PixelData, newRawBytes); } // 保存修改后的DICOM文件 dicomFile.Save(@"D:\test\" + i + "_scaled.dcm");
额外注意事项
- 如果原始DICOM是16位灰度图像,需将Bitmap转换为16位格式,并调整
BitsAllocated为16、BitsStored为12或16、HighBit为11或15等对应参数。 - 若要使用JPEG压缩存储,需设置
TransferSyntaxUID为对应的JPEG传输语法(如TransferSyntax.JPEGBaseline1),并确保所有压缩相关标签配置正确,不推荐直接写入JPEG文件字节。
内容的提问来源于stack exchange,提问作者Anasse
相关产品推荐
相关产品推荐

