在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#图形和图像处理 → DCM文件转图像,并高清处理图像

DCM文件转图像,并高清处理图像

C#图形和图像处理

下载此实例
  • 开发语言:C#
  • 实例大小:0.80M
  • 下载次数:5
  • 浏览次数:95
  • 发布时间:2021-01-28
  • 实例类别:C#图形和图像处理
  • 发 布 人:597642281
  • 所需积分:20
 相关标签: 图像处理 DC 图像

实例介绍

【实例简介】

DCM文件转图像,并高清处理图像

【实例截图】

from clipboard

【核心代码】

  #region DicomHandler 医学图像解析
        class DicomHandler
        {
            string fileName = "";
            Dictionary<string, string> tags = new Dictionary<string, string>();//dicom文件中的标签
            BinaryReader dicomFile;//dicom文件流

            //文件元信息
            public Bitmap gdiImg;//转换后的gdi图像
            UInt32 fileHeadLen;//文件头长度
            long fileHeadOffset;//文件数据开始位置
            UInt32 pixDatalen;//像素数据长度
            long pixDataOffset = 0;//像素数据开始位置
            bool isLitteEndian = true;//是否小字节序(小端在前 、大端在前)
            bool isExplicitVR = true;//有无VR

            //像素信息
            int colors;//颜色数 RGB为3 黑白为1
            public int windowWith = 2048, windowCenter = 2048 / 2;//窗宽窗位
            int rows, cols;
            public void readAndShow(out string textBox1)
            {
                textBox1 = "";
                if (fileName == string.Empty)
                {
                    textBox1 = "请选择文件";
                }
                else
                {
                    dicomFile = new BinaryReader(File.OpenRead(fileName));

                    //跳过128字节导言部分
                    dicomFile.BaseStream.Seek(128, SeekOrigin.Begin);

                    if (new string(dicomFile.ReadChars(4)) != "DICM")
                    {
                        textBox1 = "没有dicom标识头,文件格式错误";
                    }
                    else
                    {
                        tagRead();
                        IDictionaryEnumerator enor = tags.GetEnumerator();
                        while (enor.MoveNext())
                        {
                            if (enor.Key.ToString().Length > 9)
                            {
                                textBox1 = enor.Key.ToString() "\r\n";
                                textBox1 = enor.Value.ToString().Replace('\0', ' ');
                            }
                            else
                                textBox1 = enor.Key.ToString() enor.Value.ToString().Replace('\0', ' ') "\r\n";
                        }
                        dicomFile.Close();
                    }
                }
            }
            public DicomHandler(string _filename)
            {
                fileName = _filename;
            }

            public void saveAs(string filename)
            {
                switch (filename.Substring(filename.LastIndexOf('.')))
                {
                    case ".jpg":
                        gdiImg.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg);
                        break;
                    case ".bmp":
                        gdiImg.Save(filename, System.Drawing.Imaging.ImageFormat.Bmp);
                        break;
                    case ".png":
                        gdiImg.Save(filename, System.Drawing.Imaging.ImageFormat.Png);
                        break;
                    default:
                        break;
                }
            }
            public bool getImg()//获取图像 在图像数据偏移量已经确定的情况下
            {
                if (fileName == string.Empty)
                    return false;

                int dataLen, validLen;//数据长度 有效位
                int imgNum;//帧数

                rows = int.Parse(tags["0028,0010"].Substring(5));
                cols = int.Parse(tags["0028,0011"].Substring(5));

                colors = int.Parse(tags["0028,0002"].Substring(5));
                dataLen = int.Parse(tags["0028,0100"].Substring(5));
                validLen = int.Parse(tags["0028,0101"].Substring(5));

                gdiImg = new Bitmap(cols, rows);

                BinaryReader dicomFile = new BinaryReader(File.OpenRead(fileName));

                dicomFile.BaseStream.Seek(pixDataOffset, SeekOrigin.Begin);

                long reads = 0;
                for (int i = 0; i < gdiImg.Height; i )
                {
                    for (int j = 0; j < gdiImg.Width; j )
                    {
                        if (reads >= pixDatalen)
                            break;
                        byte[] pixData = dicomFile.ReadBytes(dataLen / 8 * colors);
                        reads = pixData.Length;

                        Color c = Color.Empty;
                        if (colors == 1)
                        {
                            int grayGDI;

                            double gray = BitConverter.ToUInt16(pixData, 0);
                            //调窗代码,就这么几句而已
                            //1先确定窗口范围 2映射到8位灰度
                            int grayStart = (windowCenter - windowWith / 2);
                            int grayEnd = (windowCenter windowWith / 2);

                            if (gray < grayStart)
                                grayGDI = 0;
                            else if (gray > grayEnd)
                                grayGDI = 255;
                            else
                            {
                                grayGDI = (int)((gray - grayStart) * 255 / windowWith);
                            }

                            if (grayGDI > 255)
                                grayGDI = 255;
                            else if (grayGDI < 0)
                                grayGDI = 0;
                            c = Color.FromArgb(grayGDI, grayGDI, grayGDI);
                        }
                        else if (colors == 3)
                        {
                            c = Color.FromArgb(pixData[0], pixData[1], pixData[2]);
                        }

                        gdiImg.SetPixel(j, i, c);
                    }
                }

                dicomFile.Close();
                return true;
            }
            void tagRead()//不断读取所有tag 及其值 直到碰到图像数据 (7fe0 0010 )
            {
                bool enDir = false;
                int leve = 0;
                StringBuilder folderData = new StringBuilder();//该死的文件夹标签
                string folderTag = "";
                while (dicomFile.BaseStream.Position 6 < dicomFile.BaseStream.Length)
                {
                    //读取tag
                    string tag = dicomFile.ReadUInt16().ToString("x4") ","
                    dicomFile.ReadUInt16().ToString("x4");

                    string VR = string.Empty;
                    UInt32 Len = 0;
                    //读取VR跟Len
                    //对OB OW SQ 要做特殊处理 先置两个字节0 然后4字节值长度
                    //------------------------------------------------------这些都是在读取VR一步被阻断的情况
                    if (tag.Substring(0, 4) == "0002")//文件头 特殊情况
                    {
                        VR = new string(dicomFile.ReadChars(2));

                        if (VR == "OB" || VR == "OW" || VR == "SQ" || VR == "OF" || VR == "UT" || VR == "UN")
                        {
                            dicomFile.BaseStream.Seek(2, SeekOrigin.Current);
                            Len = dicomFile.ReadUInt32();
                        }
                        else
                            Len = dicomFile.ReadUInt16();
                    }
                    else if (tag == "fffe,e000" || tag == "fffe,e00d" || tag == "fffe,e0dd")//文件夹标签
                    {
                        VR = "**";
                        Len = dicomFile.ReadUInt32();
                    }
                    else if (isExplicitVR == true)//有无VR的情况
                    {
                        VR = new string(dicomFile.ReadChars(2));

                        if (VR == "OB" || VR == "OW" || VR == "SQ" || VR == "OF" || VR == "UT" || VR == "UN")
                        {
                            dicomFile.BaseStream.Seek(2, SeekOrigin.Current);
                            Len = dicomFile.ReadUInt32();
                        }
                        else
                            Len = dicomFile.ReadUInt16();
                    }
                    else if (isExplicitVR == false)
                    {
                        VR = getVR(tag);//无显示VR时根据tag一个一个去找 真烦啊。
                        Len = dicomFile.ReadUInt32();
                    }
                    //判断是否应该读取VF 以何种方式读取VF
                    //-------------------------------------------------------这些都是在读取VF一步被阻断的情况
                    byte[] VF = { 0x00 };

                    if (tag == "7fe0,0010")//图像数据开始了
                    {
                        pixDatalen = Len;
                        pixDataOffset = dicomFile.BaseStream.Position;
                        dicomFile.BaseStream.Seek(Len, SeekOrigin.Current);
                        VR = "UL";
                        VF = BitConverter.GetBytes(Len);
                    }
                    else if ((VR == "SQ" && Len == UInt32.MaxValue) || (tag == "fffe,e000" && Len == UInt32.MaxValue))//靠 遇到文件夹开始标签了
                    {
                        if (enDir == false)
                        {
                            enDir = true;
                            folderData.Remove(0, folderData.Length);
                            folderTag = tag;
                        }
                        else
                        {
                            leve ;//VF不赋值
                        }
                    }
                    else if ((tag == "fffe,e00d" && Len == UInt32.MinValue) || (tag == "fffe,e0dd" && Len == UInt32.MinValue))//文件夹结束标签
                    {
                        if (enDir == true)
                        {
                            enDir = false;
                        }
                        else
                        {
                            leve--;
                        }
                    }
                    else
                        VF = dicomFile.ReadBytes((int)Len);

                    string VFStr;

                    VFStr = getVF(VR, VF);

                    //----------------------------------------------------------------针对特殊的tag的值的处理
                    //特别针对文件头信息处理
                    if (tag == "0002,0000")
                    {
                        fileHeadLen = Len;
                        fileHeadOffset = dicomFile.BaseStream.Position;
                    }
                    else if (tag == "0002,0010")//传输语法 关系到后面的数据读取
                    {
                        switch (VFStr)
                        {
                            case "1.2.840.10008.1.2.1\0"://显示little
                                isLitteEndian = true;
                                isExplicitVR = true;
                                break;
                            case "1.2.840.10008.1.2.2\0"://显示big
                                isLitteEndian = false;
                                isExplicitVR = true;
                                break;
                            case "1.2.840.10008.1.2\0"://隐式little
                                isLitteEndian = true;
                                isExplicitVR = false;
                                break;
                            default:
                                break;
                        }
                    }
                    for (int i = 1; i <= leve; i )
                        tag = "--" tag;
                    //------------------------------------数据搜集代码
                    if ((VR == "SQ" && Len == UInt32.MaxValue) || (tag == "fffe,e000" && Len == UInt32.MaxValue) || leve > 0)//文件夹标签代码
                    {
                        folderData.AppendLine(tag "(" VR "):" VFStr);
                    }
                    else if (((tag == "fffe,e00d" && Len == UInt32.MinValue) || (tag == "fffe,e0dd" && Len == UInt32.MinValue)) && leve == 0)//文件夹结束标签
                    {
                        folderData.AppendLine(tag "(" VR "):" VFStr);
                        tags.Add(folderTag "SQ", folderData.ToString());
                    }
                    else
                        tags.Add(tag, "(" VR "):" VFStr);
                }
            }

            string getVR(string tag)
            {
                switch (tag)
                {
                    case "0002,0000"://文件元信息长度
                        return "UL";
                        break;
                    case "0002,0010"://传输语法
                        return "UI";
                        break;
                    case "0002,0013"://文件生成程序的标题
                        return "SH";
                        break;
                    case "0008,0005"://文本编码
                        return "CS";
                        break;
                    case "0008,0008":
                        return "CS";
                        break;
                    case "0008,1032"://成像时间
                        return "SQ";
                        break;
                    case "0008,1111":
                        return "SQ";
                        break;
                    case "0008,0020"://检查日期
                        return "DA";
                        break;
                    case "0008,0060"://成像仪器
                        return "CS";
                        break;
                    case "0008,0070"://成像仪厂商
                        return "LO";
                        break;
                    case "0008,0080":
                        return "LO";
                        break;
                    case "0010,0010"://病人姓名
                        return "PN";
                        break;
                    case "0010,0020"://病人id
                        return "LO";
                        break;
                    case "0010,0030"://病人生日
                        return "DA";
                        break;
                    case "0018,0060"://电压
                        return "DS";
                        break;
                    case "0018,1030"://协议名
                        return "LO";
                        break;
                    case "0018,1151":
                        return "IS";
                        break;
                    case "0020,0010"://检查ID
                        return "SH";
                        break;
                    case "0020,0011"://序列
                        return "IS";
                        break;
                    case "0020,0012"://成像编号
                        return "IS";
                        break;
                    case "0020,0013"://影像编号
                        return "IS";
                        break;
                    case "0028,0002"://像素采样1为灰度3为彩色
                        return "US";
                        break;
                    case "0028,0004"://图像模式MONOCHROME2为灰度
                        return "CS";
                        break;
                    case "0028,0010"://row高
                        return "US";
                        break;
                    case "0028,0011"://col宽
                        return "US";
                        break;
                    case "0028,0100"://单个采样数据长度
                        return "US";
                        break;
                    case "0028,0101"://实际长度
                        return "US";
                        break;
                    case "0028,0102"://采样最大值
                        return "US";
                        break;
                    case "0028,1050"://窗位
                        return "DS";
                        break;
                    case "0028,1051"://窗宽
                        return "DS";
                        break;
                    case "0028,1052":
                        return "DS";
                        break;
                    case "0028,1053":
                        return "DS";
                        break;
                    case "0040,0008"://文件夹标签
                        return "SQ";
                        break;
                    case "0040,0260"://文件夹标签
                        return "SQ";
                        break;
                    case "0040,0275"://文件夹标签
                        return "SQ";
                        break;
                    case "7fe0,0010"://像素数据开始处
                        return "OW";
                        break;
                    default:
                        return "UN";
                        break;
                }
            }

            string getVF(string VR, byte[] VF)
            {
                string VFStr = string.Empty;
                switch (VR)
                {
                    case "SS":
                        VFStr = BitConverter.ToInt16(VF, 0).ToString();
                        break;
                    case "US":
                        VFStr = BitConverter.ToUInt16(VF, 0).ToString();

                        break;
                    case "SL":
                        VFStr = BitConverter.ToInt32(VF, 0).ToString();

                        break;
                    case "UL":
                        VFStr = BitConverter.ToUInt32(VF, 0).ToString();

                        break;
                    case "AT":
                        VFStr = BitConverter.ToUInt16(VF, 0).ToString();

                        break;
                    case "FL":
                        VFStr = BitConverter.ToSingle(VF, 0).ToString();

                        break;
                    case "FD":
                        VFStr = BitConverter.ToDouble(VF, 0).ToString();

                        break;
                    case "OB":
                        VFStr = BitConverter.ToString(VF, 0);
                        break;
                    case "OW":
                        VFStr = BitConverter.ToString(VF, 0);
                        break;
                    case "SQ":
                        VFStr = BitConverter.ToString(VF, 0);
                        break;
                    case "OF":
                        VFStr = BitConverter.ToString(VF, 0);
                        break;
                    case "UT":
                        VFStr = BitConverter.ToString(VF, 0);
                        break;
                    case "UN":
                        VFStr = Encoding.Default.GetString(VF);
                        break;
                    default:
                        VFStr = Encoding.Default.GetString(VF);
                        break;
                }
                return VFStr;
            }
        }
        #endregion



标签: 图像处理 DC 图像

实例下载地址

DCM文件转图像,并高清处理图像

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
;
报警