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

1.定位线概念:某个方位的影像在另一个方向的影像上的投影相交线,例如横断面(从头到脚的方向)在矢状面(从左手到右手)上的影像投影面交线。

举个例子:右边的是MR(核磁共振)的某一帧切片,这是从头开始扫描,扫描到眼睛这个位置,

而左边图像是从左手到右手的扫描切片,那么右边图像的位置就恰好在左边图像的眼睛的位置,用红线标出的位置则为定位线,一般用于医生参考病灶在矢状面、冠状面和横断面的具体方位。

2.检查设备示意图

在笛卡尔空间直角坐标系中,Y 右肩膀到左肩膀,X 后背到前胸,Z 足到头

3.算法流程

4.代码实现:

创建图像结构

publicFrameGeometry(DicomDataset image)

:this(image.GetString(DicomTag.FrameOfReferenceUID),

image.GetValues(DicomTag.ImagePositionPatient),

image.GetValues(DicomTag.ImageOrientationPatient),

image.GetValues(DicomTag.PixelSpacing),

image.GetSingleValue(DicomTag.Columns),

image.GetSingleValue(DicomTag.Rows))

{//TODO:

FrameOfReferenceUID:图片UID

ImagePositionPatient:病人方向

ImageOrientationPatient:图片方向

PixelSpacing:像素间距

Columns:宽度

Rows:高度

}

判断是否符合定位条件:

/// ///判断是否可以画定位线///

/// 源图像结构

/// 目标图像结构

///

public static boolCanDrawLocalizer(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;

}

计算交线点:

///

///回两个图像相交处公共像素线

///

/// 源图像结构

/// 目标图像结构

/// 起点输出

/// 重点输出

///

public static bool CalcualteIntersectionLocalizer(FrameGeometry sourceFrame, FrameGeometry destinationFrame, out Point2 startPoint, outPoint2 endPoint)

{double t; //平面方程系数

doublenA, nB, nC, nD, nP;var lstProj = new List();//初始化

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医学影像处理系统

目录整理:

(一)PACS客户端:

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影像色彩增强(伪彩)

C#开发PACS医学影像处理系统(十九):Dicom影像反色处理(负片)

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

(二)PACS三维:MRP、MIP、VR

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

(三)PACS网页端:开发Web版本的PACS

C#开发Web端PACS(一):基于PACS客户端思想重写Web端

(四)PACS移动端:开发基于HTML5移动端版本的PACS

C#开发移动端PACS(一):使用HTML5和CSS3开发PACS手机端页面

C#开发移动端PACS(二):使用 .Net MVC 开发手机端PACS服务端

(五)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交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508178.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图片饱和度_摄影后期完全调色指南(三):饱和度与自然饱和度有什么区别?...

泼辣年度大课 | 摄影后期完全调色指南(一)摄影后期完全调色指南(二)&#xff1a;详解色温与色调在上一篇教程里面我们讲到了全局色彩调整中的色温和色调工具&#xff0c;今天来讲解剩下的两个工具&#xff1a;饱和度与自然饱和度工具&#xff0c;这两个工具使用的频率也非常的高…

2023年大模型回顾

大家好&#xff0c;这里是最佳拍档&#xff0c;我是大飞 一年前的今天&#xff0c;ChatGPT发布 仅仅花了5天时间 ChatGPT的注册用户数量达到100万 创了互联网历史记录 两个月后&#xff0c;2023年1月 ChatGPT的月活用户数量达到1亿 火箭般蹿升的用户数量 预示了今年生成…

windows 下的文件对比工具

deffinity,一款专用于文件对比的工具,安装简单,使用方便 下载链接如下: https://www.appinn.com/diffinity-for-win/

18c分布式事务 oracle_浅谈ORACLE的分布式事务

平台环境&#xff1a; suk: linux as4 oracle 9201 primary: windows xp oracle 10.2.0.3 首先在primary数据库上建立测试数据。 SQL create table test as select * from dba_objects; Table created. SQL insert into test select * from test; 9873 rows created. SQ平台环境…

shell 中去掉末尾换行符

# 多行为一行 echo "aaa\ bbb\ ccc" # 结果 #aaabbbccc#多行还是多行 echo "aaa bbb ccc" #结果 #aaa #bbb #ccc

python五子棋游戏15*15_在STM32上运行五子棋小游戏(15x15)

本程序算法资料来自下面网站.----https://www.cnblogs.com/buptzym/archive/2012/06/20/2556052.html----先定义一个数组 用于存储整个棋盘的数据.u16 ChessBoard[15][15];//棋盘数据.一.己方下棋 基础函数.1.在屏幕上显示出来一个15*15的棋盘.void DrawTable(void)//画出15x15…

点名册_骑士新书《万界点名册》十万收藏火爆气势不减当年修真聊天群

最近好多人都在讨论圣骑士的传说新书《万界点名册》&#xff0c;新书还没有发布&#xff0c;起点就给了闪屏推荐&#xff0c;引得的很多读者心痒痒的想要看看到底是怎样的神作。所以才发布两万多字的新书投资人就快一万人了&#xff0c;收藏也突破了十万。这速度好像是坐了火箭…

hadoop重启后 9000端口不在

原因可能是hadoop的namenode还未启动成功,可以去查看namenode的日志,是否有错误日志,如果没有错误日志,耐心等待namenode的恢复

500张思维导图记38000单词_思维导图记单词,环环相扣难遗忘——2020奇速英语夏令营第三天...

2020年8月6日&#xff0c;是奇速英语19期夏令营第二批单词阅读营正式上课的第3天&#xff0c;为了激发各班学员学习兴趣&#xff0c;保证学习效果&#xff0c;奇速英语专门制定了小组PK的积分奖励制在今天的学习当中发挥了极大的效果。在这一机制的刺激和奇速英语老师们的高效教…

语音识别热词_出门问问 TWS 耳机语音交互解决方案

随着芯片、算法商在技术及应用方面的演进&#xff0c;尤其是连接、降噪方向的重大突破&#xff0c;越来越多的手机及耳机厂商推出了自家功能丰富、交互舒适的 TWS 耳机。近日&#xff0c;出门问问新品发布会上推出的 TicPods 2 系列产品&#xff0c;在人机交互和语音助理方面&a…

egret 变量_egret性能优化总结

## 来自官方的优化建议(1) 少使用Alpha混合。(2) 显式停止计时器&#xff0c;让它们准备好进行垃圾回收。(3)使用事件侦听器并在不需要时删除这些侦听器。(4) 在不需要触摸交互性时显式禁用触摸交互性。(5) 合理使用dispatchEvents 函数。(6) 尽可能重用对象&#xff0c;建立对…

go tcp连接_TCP漫谈之keepalive和time_wait

TCP是一个有状态通讯协议&#xff0c;所谓的有状态是指通信过程中通信的双方各自维护连接的状态。一、TCP keepalive先简单回顾一下TCP连接建立和断开的整个过程。(这里主要考虑主流程&#xff0c;关于丢包、拥塞、窗口、失败重试等情况后面详细讨论。)首先是客户端发送syn(Syn…

纠错码较副本优势与minio纠错码配置

1. 优势 纠错码是什么,怎么保障数据不丢失 纠错码采用数据块校验块方式进行存储,副本采用真实副本存储纠错码更利于存储,副本更利于计算 2. 业界配置 EMC对象存储系统ECS 12 4 和 102 冗余度分别为 1.33 、 1.2 阿里云盘古集群chunk存储 83 冗余度1.375 Google RS(6,3) i…

mysql update 联合更新_Mysql update多表联合更新的方法小结

下面我建两个表&#xff0c;并执行一系列sql语句&#xff0c;仔细观察sql执行后表中数据的变化&#xff0c;很容易就能理解多表联合更新的用法student表 class表1. 执行 UPDATE student s , class c SET s.class_nametest00,c.stu_nametest00 WHERE s.class_id c.idstudent表 …

java mysql读取多条数据_myeclipse 使用Java访问mysql数据库,数据库中有多条记录,为何只能读出一条数据??...

Java源代码如下&#xff1a;publicListgetAllMsgList(){ListmsgListnewArrayList();DBConnectiondbnewDBConnection();Connectionconndb.getConn();Stringsql"select*frommsg...Java 源代码如下&#xff1a;public List getAllMsgList() { List msgList new ArrayList();…

基于corundumstudio建立websocket长连接

依赖 <!--socket io --><dependency><groupId>io.socket</groupId><artifactId>socket.io-client</artifactId><version>1.0.1</version></dependency><dependency><groupId>com.corundumstudio.socketio&…

mysql查询开启事务_MySQL中的查询事务问题

之前帮同学做个app的后台&#xff0c;使用了MySQLMyBatis&#xff0c;遇到了一个查询提交的问题&#xff0c;卡了很久&#xff0c;现在有时间了来复盘下环境情况假设有学生表&#xff1a;USE test;CREATE TABLE student (Id int NOT NULL PRIMARY KEY AUTO_INCREMENT,Name varc…