1.定位线概念:某个方位的影像在另外一个方向的影像上的投影相交线,例如横断面(从头到脚的方向)在矢状面(从左手到右手)上的影像投影面交线。html
举个例子:右边的是MR(核磁共振)的某一帧切片,这是从头开始扫描,扫描到眼睛这个位置,算法
而左边图像是从左手到右手的扫描切片,那么右边图像的位置就刚好在左边图像的眼睛的位置,用红线标出的位置则为定位线,通常用于医生参考病灶在矢状面、冠状面和横断面的具体方位。微信
2.检查设备示意图架构
在笛卡尔空间直角坐标系中,Y 右肩膀到左肩膀,X 后背到前胸,Z 足到头并发
3.算法流程机器学习
4.代码实现:高并发
建立图像结构工具
public FrameGeometry(DicomDataset image) : this(image.GetString(DicomTag.FrameOfReferenceUID), image.GetValues<double>(DicomTag.ImagePositionPatient), image.GetValues<double>(DicomTag.ImageOrientationPatient), image.GetValues<double>(DicomTag.PixelSpacing), image.GetSingleValue<int>(DicomTag.Columns), image.GetSingleValue<int>(DicomTag.Rows)) { // TODO:
FrameOfReferenceUID:图片UID
ImagePositionPatient:病人方向
ImageOrientationPatient:图片方向
PixelSpacing:像素间距
Columns:宽度
Rows:高度
}
判断是否符合定位条件:布局
/// <summary>/// 判断是否能够画定位线 /// </summary> /// <param name="sourceFrame">源图像结构</param> /// <param name="destinationFrame">目标图像结构</param> /// <returns></returns> public static bool CanDrawLocalizer(FrameGeometry sourceFrame, FrameGeometry destinationFrame) { // 检查图像结构 if (sourceFrame == null) return false; if (destinationFrame == null) return false; // 若是两个帧中的任何一个不是空间坐标系,则没法定位 if (sourceFrame.Orientation == FrameOrientation.None || destinationFrame.Orientation == FrameOrientation.None) return false; // 只有正交图像才能绘制,方向相同则退出 if (sourceFrame.Orientation == destinationFrame.Orientation) return false; // 检查FrameOfReferenceUid if (string.IsNullOrEmpty(sourceFrame.FrameOfReferenceUid) || string.IsNullOrEmpty(destinationFrame.FrameOfReferenceUid)) return false; if (sourceFrame.FrameOfReferenceUid != destinationFrame.FrameOfReferenceUid) return false; return true; }
计算交线点:学习
/// <summary> ///回两个图像相交处公共像素线 /// </summary> /// <param name="sourceFrame">源图像结构</param>
/// <param name="destinationFrame">目标图像结构</param>
/// <param name="startPoint">起点输出</param> /// <param name="endPoint">重点输出</param> /// <returns></returns> public static bool CalcualteIntersectionLocalizer(FrameGeometry sourceFrame, FrameGeometry destinationFrame, out Point2 startPoint, out Point2 endPoint) { double t; // 平面方程系数 double nA, nB, nC, nD, nP; var lstProj = new List<Point3D>(); // 初始化 startPoint = Point2.Origin; endPoint = Point2.Origin; // 验证 if (destinationFrame.DirectionNormal.IsZero) return false; nP = destinationFrame.DirectionNormal * destinationFrame.PointTopLeft; nA = destinationFrame.DirectionNormal * sourceFrame.PointTopLeft; nB = destinationFrame.DirectionNormal * sourceFrame.PointTopRight; nC = destinationFrame.DirectionNormal * sourceFrame.PointBottomRight; nD = destinationFrame.DirectionNormal * sourceFrame.PointBottomLeft; // AB if (Math.Abs(nB - nA) > Constants.Epsilon) { t = (nP - nA) / (nB - nA); if (t > 0 && t <= 1) lstProj.Add(sourceFrame.PointTopLeft + t * (sourceFrame.PointTopRight - sourceFrame.PointTopLeft)); } // BC if (Math.Abs(nC - nB) > Constants.Epsilon) { t = (nP - nB) / (nC - nB); if (t > 0 && t <= 1) lstProj.Add(sourceFrame.PointTopRight + t * (sourceFrame.PointBottomRight - sourceFrame.PointTopRight)); } // CD if (Math.Abs(nD - nC) > Constants.Epsilon) { t = (nP - nC) / (nD - nC); if (t > 0 && t <= 1) lstProj.Add(sourceFrame.PointBottomRight + t * (sourceFrame.PointBottomLeft - sourceFrame.PointBottomRight)); } // DA if (Math.Abs(nA - nD) > Constants.Epsilon) { t = (nP - nD) / (nA - nD); if (t > 0 && t <= 1) lstProj.Add(sourceFrame.PointBottomLeft + t * (sourceFrame.PointTopLeft - sourceFrame.PointBottomLeft)); } if (lstProj.Count != 2) return false; // 从空间坐标系返回平面坐标系 startPoint = destinationFrame.TransformPatientPointToImage(lstProj[0]); endPoint = destinationFrame.TransformPatientPointToImage(lstProj[1]); return true; }
获得坐标以后就能够利用绘图操做类(参考本系列教程之图形标记)来本身绘制定位线。
看效果:
对于较复杂的身体部位,也能够同时绘制定位线范围,来肯定当前序列的定位范围,思路是先计算第一帧和最后一帧,用黄色虚线标出,再计算当前帧。
看效果:
C#开发PACS、RIS、3D医学影像处理系统系列教程目录整理:
菜鸟入门篇:
PACS客户端:
C#开发PACS医学影像处理系统(七):读取影像Dicom信息
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影像放大镜
PACS三维处理医学图像:
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#处理医学图像(一):基于Hessian矩阵的血管肺纹理骨骼加强对比
C#处理医学图像(二):图像锐化加强对比
PACS网页端 开发Web版本的PACS:
C#开发Web端PACS(一):基于PACS客户端思想重写Web端
C#开发Web端PACS(二):使用 .Net MVC 开发手机端PACS服务端
C#开发Web端PACS(三):使用HTML5和CSS3开发PACS手机端页面
C#开发Web端PACS(四):Web端与服务端的DICOM传输
C#开发Web端PACS(五):Web端的平移缩放旋转2D操做
C#开发Web端PACS(六):Web端的窗宽窗位调整
C#开发Web端PACS(七):将移动端接入微信公众号实现医院云胶片
登峰造极篇:
C#开发基于Python人工智能的肺结节自动检测
C#开发基于Python人工智能的脊柱侧弯曲率算法
C#开发基于Python机器学习的医学影像骨骼仿真动画
C#开发基于Python机器学习的术后恢复模拟
C#开发基于U3D的VR眼镜设备虚拟人体三维重建
C#开发基于全息投影的裸眼3D医学影像显示技术
周边附加篇:
胶片打印:
C#开发医学影像胶片打印系统(一):功能与胶片排版
C#开发医学影像胶片打印系统(二):胶片打印机通信
C#开发医学影像胶片打印系统(三):不规则排版打印
PACS服务端:
C#开发PACS医学影像处理系统服务端(一):医疗设备的链接与收图
C#开发PACS医学影像处理系统服务端(二):高并发架构
PACS与RIS系统的通讯与集成
在RIS系统中调起PACS并打开Dicom影像
云PACS与远程会诊
C#开发PACS医学影像处理系统之云PACS(区域PACS)(一):架构概述
C#开发PACS医学影像处理系统之云PACS(区域PACS)(二):远程会诊与双向转诊
科幻级视频特效:
使用Adobe After Effects 制做PACS影像处理系统宣传视频
![]() |
QQ:1850969244 近10年开发经验,主攻C#、ASP MVC,HTML5, B/S C/S 皆可,目前研究医疗领域医学影像相关技术, 任何技术问题欢迎加QQ交流。 |