C#开发PACS医学影像处理系统(六):加载Dicom影像

对于一款软件的扩展性和维护性来说,上层业务逻辑和UI表现一定要自己开发才有控制权,否则项目上线之后容易被掣肘,

而底层图像处理,我们不需要重复造轮子,这里推荐使用fo-dicom,同样基于Dicom3.0协议。

根据以上原则,后台影像处理完成之后,即可使用自己开发的控件来呈现。

1.先准备好自己的dcm文件,可以是单个文件或序列文件或DicomDir文件。

2.在VS编辑器里打开NUGET搜索fo-dicoman安装即可。

3.使用fo-dicom读取影像。

 //将图像处理模式设置为全局WPF模式
        Dicom.Imaging.ImageManager.SetImplementation(Dicom.Imaging.WPFImageManager.Instance);

        //实例化文件处理对象并打开文件
        DicomFile dicomFile = DicomFile.Open(@"C:\101\1.dcm");
        //获取dicom图像对象
        DicomImage dicomImage = new DicomImage(dicomFile.Dataset);
        //不使用LUT
        dicomImage.UseVOILUT = false;

        //转换成一般图像格式,bmp,png等,
        //在WPF中我们转换成WriteableBitmap
        dicomImage.RenderImage().AsWriteableBitmap() :

4.设置缩放比例,通常dcm影像的大小是不固定的,由设备和技师拍摄手法决定,所以我们要将图像大小缩小或放大到最佳尺寸。

dicomImage对象中的Scale属性决定了缩放比例,方法参数中Border是边框容器,也可以使用Grid或其他可以呈现图像的容器。

/// <summary>
 /// 计算图片在容器中的缩放比例
 /// </summary>
 /// <param name="dicomImage">图片</param>
 /// <param name="imgBoxDock">容器</param>
 /// <param name="width">实际长度</param>
 /// <param name="height">实际高度</param>
public static void SetImageScale(DicomImage dicomImage, Border imgBoxDock, double width = 0, double height = 0)
{
    double maxWidth = imgBoxDock.Width;
    double maxHeight = imgBoxDock.Height;
    if (double.IsNaN(imgBoxDock.Width) || double.IsNaN(imgBoxDock.Height))
    {
        maxWidth = width;
        maxHeight = height;
    }
    dicomImage.Scale = Math.Min(maxWidth / dicomImage.Width, maxHeight / dicomImage.Height);
}

5.设置图像对齐方式,图像的长宽一般是不能恰好填充容器的,尤其是设置缩放比例之后,那我们需要在容器中将图像按照一定规则对齐。

/// <summary>
        /// 在图片容器中显示一张图片
        /// </summary>
        /// <param name="sourceImg">图片源</param>
        /// <param name="imgBox">图片控件</param>
        /// <param name="imgBoxDock">图片容器</param>
        /// <param name="align">对齐方式</param> 
        /// <param name="width">实际长度</param>
        /// <param name="height">实际高度</param>
        public static void ShowImage(WriteableBitmap sourceImg, InkCanvas imgBox, Border imgBoxDock, ImageAlignment align,  double width = 0, double height = 0)
        {
            try
            {
                if (sourceImg != null)
                {
                    ImageBrush ib = new ImageBrush(sourceImg);
                    imgBox.Background = ib;
                }

                double w = 0;
                double h = 0;
                if (double.IsNaN(imgBoxDock.Width) || double.IsNaN(imgBoxDock.Height))
                {
                    w = width;
                    h = height;
                }
                else
                {
                    if (sourceImg != null)
                    {
                        w = imgBoxDock.Width - sourceImg.Width;
                        h = imgBoxDock.Height - sourceImg.Height;
                    }           else return;
                }

                if (align == ImageAlignment.Center)
                {
                    imgBox.Margin = new Thickness(
                        w / 2,
                        h / 2,
                        w / 2,
                        h / 2);
                }
                else if (align == ImageAlignment.Left)
                {
                    imgBox.Margin = new Thickness(
                        0,
                        h / 2,
                        w,
                        h / 2);
                }
                else if (align == ImageAlignment.Right)
                {
                    imgBox.Margin = new Thickness(
                        w,
                        h / 2,
                        0,
                        h / 2);
                }
                else if (align == ImageAlignment.Top)
                {
                    imgBox.Margin = new Thickness(
                        w / 2,
                        0,
                        w / 2,
                        h);
                }
                else if (align == ImageAlignment.Bottom)
                {
                    imgBox.Margin = new Thickness(
                        w / 2,
                        h,
                        w / 2,
                        0);
                }
            }
            catch (Exception e)
            {
                LogApi.WriteErrLog(e);
            }
        }

    /// <summary>
    /// 图像对齐方式
    /// </summary>
    public enum ImageAlignment
    {
        /// <summary>
        /// 居左
        /// </summary>
        Left = 0,

        /// <summary>
        /// 置顶
        /// </summary>
        Top = 1,

        /// <summary>
        /// 居右
        /// </summary>
        Right = 2,

        /// <summary>
        /// 置底
        /// </summary>
        Bottom = 3,

        /// <summary>
        /// 居中
        /// </summary>
        Center = 4,

        /// <summary>
        /// 跟随父级(仅用于Cell中dicom容器)
        /// </summary>
        Parent = 5,

    }

最终呈现效果:

 

注:一些特殊的类型对齐方式是不一样的,需要对应的挂片协议来控制,详情请参考本系列文章的挂片协议章节。

例如:钼靶(modality:MG)类型,是按照居左居右对齐。

 C#开发PACS、RIS、3D医学影像处理系统系列教程 目录整理:

菜鸟入门篇

C#开发PACS医学影像处理系统(一):开发背景和功能预览

C#开发PACS医学影像处理系统(二):界面布局之菜单栏

C#开发PACS医学影像处理系统(三):界面布局之工具栏

C#开发PACS医学影像处理系统(四):界面布局之状态栏

C#开发PACS医学影像处理系统(五):查询病人信息列表

C#开发PACS医学影像处理系统(六):加载Dicom影像

C#开发PACS医学影像处理系统(七):读取影像Dicom信息

C#开发PACS医学影像处理系统(八):单元格变换

C#开发PACS医学影像处理系统(九):序列控件与拖拽

C#开发PACS医学影像处理系统(十):Dicom影像下载策略与算法

C#开发PACS医学影像处理系统(十一):Dicom影像挂片协议

C#开发PACS医学影像处理系统(十二):绘图处理之图形标记

C#开发PACS医学影像处理系统(十三):绘图处理之病灶测量

C#开发PACS医学影像处理系统(十四):处理Dicom影像窗宽窗位

C#开发PACS医学影像处理系统(十五):Dicom影像交叉定位线算法

C#开发PACS医学影像处理系统(十六):2D处理之影像平移和缩放

C#开发PACS医学影像处理系统(十七):2D处理之影像旋转和翻转

C#开发PACS医学影像处理系统(十八):Dicom使用LUT色彩增强和反色

C#开发PACS医学影像处理系统(十九):Dicom影像放大镜

医学影像三维篇

C#开发PACS医学影像三维重建(一):使用VTK重建3D影像

C#开发PACS医学影像三维重建(二):使用VTK进行体绘制

C#开发PACS医学影像三维重建(三):纹理映射与颜色传输

C#开发PACS医学影像三维重建(四):3D网格平滑效果

C#开发PACS医学影像三维重建(五):基于梯度透明的组织漫游

C#开发PACS医学影像三维重建(六):三维光源与阴影效果

C#开发PACS医学影像三维重建(七):空间测量与标注

C#开发PACS医学影像三维重建(八):VR体绘制

C#开发PACS医学影像三维重建(九):MPR三视图切面重建

C#开发PACS医学影像三维重建(十):MIP最小密度投影

C#开发PACS医学影像三维重建(十一):CPR曲面重建

C#开发PACS医学影像三维重建(十二):VE虚拟内镜技术

C#开发PACS医学影像三维重建(十三):基于人体CT值从皮肤渐变到骨骼的梯度透明思路

C#开发PACS医学影像三维重建(十四):基于能量模型算法将曲面牙床展开至二维平面

熟手进阶篇

C#处理医学影像(一):基于Hessian矩阵的血管肺纹理骨骼增强对比

C#处理医学影像(二):基于Hessian矩阵的医学影像增强与窗宽窗位

C#处理医学影像(三):基于漫水边界自动选取病灶范围的实现思路

C#处理医学影像(四):基于Stitcher算法拼接人体全景脊柱骨骼影像

胶片打印:

C#开发医学影像胶片打印系统(一):万能花式布局的实现思路

C#开发医学影像胶片打印系统(二):胶片打印机通讯

C#开发医学影像胶片打印系统(三):Pacs二维功能在排版中的应用

登峰造极篇

C#开发基于Python人工智能的肺结节自动检测

C#开发基于Python人工智能的脊柱侧弯曲率算法

C#开发基于Python机器学习的医学影像骨骼仿真动画

C#开发基于Python机器学习的术后恢复模拟

C#开发基于U3D的VR眼镜设备虚拟人体三维重建

C#开发基于全息投影的裸眼3D医学影像显示技术

免费下载

免费下载使用本教程PACS软件

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值