多帧Dicom文件获取ImagePosition、Intercept、Slope、PixelSpacing

开发环境

VS2022

Win11

Fo-Dicom 5.0.3(当前最新已经更新到了5.1.2)

 

背景

在做Dicom文件读取时,发现对于多帧Dicom文件的一些Tag的读取总是会出问题(读取不到),但同类软件却是没有问题的,甚是疑惑。

通过多天的摸索,终是找到了解决办法,能顺利读取多帧Dicom中的某帧图片的ImagePosition及整个序列的Intercept、Slope、 PixelSpacing 。

 

Fo-Dicom读取多帧ImagePosition、Intercept、Slope

获取某帧的 Image Position

下图中的高量为Image Position

多帧ImagePosition,需要到PerFrameFunctionalGroupsSequence中去找,然后进入PlanePositionSequence中,在这个sequence下即可找到ImagePosition标签。

ImagePositon标签是计算层间距的关键标签,若直接通过SpaceBetweenSlice读取到的层间距,是不准确的(实际CT中,这个标签的值可能不正确) ;通过ImagePosition标签的获取,然后通过相邻两张图片的位置数据相减,即可计算出层间距。

 

获取Intercept、Slope

下图中高亮为当前查看病例的Intercept,其下即为Slope。

 Intercept与Slope在多帧获取时,需要到SharedFunctionalGroupsSequence中去找,然后找到PixelValueTransformationSequence中,即可找到RescaleIntercept和RescaleSlope标签。

Intercept与Slope是重建图像的关键标签,其决定了图像显示的像素的显示效果。

 

获取PixlSpacing

下图中高亮为当前查看病例PixlSpacing

 获取时如下:

多帧DICOM中 PixelSpacing的获取,同样是需要先找到SharedFunctionalGroupsSequence,然后从PixelMeasuresSequence标签中找到PixelSpacing标签去获取。

此标签决定了重建CT的像素大小是否与原图像的大小是否一致。

 

获取示例代码:

        private static void GetPixelSpacing(DicomDataset dataset, ref CaseDTO patientCase)
        {
            if (dataset.TryGetSingleValue<double>(DicomTag.PixelSpacing, out double pixelSpacing))
            {
                patientCase.PixelSpacing = pixelSpacing;
            }
            else
            {
                //多帧Dicom的读取pixelSpacing
                if (dataset.TryGetSequence(DicomTag.SharedFunctionalGroupsSequence, out DicomSequence sharedFunctionalGroupsSequence))
                {

                    var seq = GetTagDicomDataset(sharedFunctionalGroupsSequence, DicomTag.PixelMeasuresSequence);

                    if (seq is not null && seq.TryGetSequence(DicomTag.PixelMeasuresSequence, out DicomSequence pixelMeasuresSequence))
                    {
                        var ds = GetTagDicomDataset(pixelMeasuresSequence, DicomTag.PixelSpacing);
                        if (ds is not null && ds.TryGetValues<double>(DicomTag.PixelSpacing, out double[] px))
                        {
                            patientCase.PixelSpacing = px[0];
                        }
                        else
                        {
                            //提示异常
                        }
                    }
                    else
                    {
                        //提示异常
                    }
                }
                else
                {
                    patientCase.PixelSpacing = 0;//最好是直接提示异常
                }
            }
        }

        private static DicomDataset GetTagDicomDataset(DicomSequence dicomSequence, DicomTag dicomTag)
        {
            var lists = dicomSequence.Items;
            foreach (var e in lists)
            {
                if (e.Contains(dicomTag))
                {
                    return e;
                }
            }
            return null;
        }

 

posted @ 2025-04-28 18:50  盛沧海  阅读(100)  评论(0)    收藏  举报