【转】胶片曝光时的排版!!!!!!!

这个本来没啥 不是什么算法 绝技。 都不值得一提。

其实这个是医学影像胶片曝光时排版的一个逻辑。

dicom标准第三部分 主要是讲IOD定义 在第166页有这样的描述:

表C.13.5-1图象盒象素描述组件
属性名称    标记          说明
图象位置    (2020,0010)     基于图象显示格式(2010,0010)的胶片的图象位置。
参阅C.13.5.1的规范。

这个所谓的“基于图象显示格式(2010,0010)的胶片的图象位置”到底是啥意思呢 ?还是像往常一样拿个实例瞧瞧:
20 20 10 00     ............  ..
00000010    02 00 00 00 02 00
20 20 10 00     ............  ..
00000010    02 00 00 00 03 00

dicom数据元素的结构就不多说了哈 详情请查看dicom标准。只看最后两位,可见这个所谓的“基于图象显示格式(2010,0010)的胶片的图象位置” 就是一个个的从前到后的排序。从设备工作站发送胶片曝光作业的时候 根据dicom协议 图像传输 那么它就是以这种 “序列”的方式发送的。
再看dicom标准另外一段 第三部分167页 :

C.13.5.1图象位置


胶片中图象的位置;图象位置序列的编码是基于选择的图象显示格式
(2010,0010)。图象位置序列以值1递增。
图象位置(2020,0010)定义如下:
-    标准显示格式:                 图象盒序列是主要行顺序(从左到右或从上到下);左上图象位置等于1。
-    行显示格式:                    图象盒序列是主要行顺序(从左到右或从上到下);左上图象位置等于1。
-    列显示格式:                    图象盒序列是主要列顺序(从左到右或从上到下);左上图象位置等于1。
-    SLIDE显示格式:             图象盒序列是主要行顺序(从左到右或从上到下);左上图象位置等于1。
-    SUPERSLIDE显示格式:图象盒序列是主要行顺序(从左到右或从上到下);左上图象位置等于1。

关于ImgBox 的几种方式的细节我们暂时不去管 只管第一种 ,因为就我遇到的 90%以上都是 “标准显示格式”在胶片曝光dimse的过程中 createFilmBox 的时候 会收到一个参数 command元素0x20100010, 它的值是类似这样STANDARD\1,1  这个standard 就是表示 这是一个“标准显示格式” 逗号分隔开的两个数字 第一个是列数 第二个是行数。标准显示格式就是: (在一个指定行数列数的网格里把图像按从左到右从上到下的方式排列)
如图:

说到底我们要实现的就是根据dicom标准 把这种依次编号的图像拼接成 一个整幅的网格图像 让它打印出来看上去跟工作站上阅片时的所见即所得,可以根据编号获取指定图像 可以根据几行几列或许指定图像 可以根据编号获知他是第几行第几列 可以根据第几行第几列获知他的编号。就这样简单。

来简单分析下,可以通过STANDARD\colNum,rowNum 来确定行数跟列数。这就容易了

他是一个“持续堆叠的过程”

第一行堆满了堆第二行 从左往右的不断堆。
以x表示列 y表示行 从1开始,num表示编号 从1开始 , 可以得出这样的结论:
for(1 to num)
{
    if(num%colNum!=0)//不能除尽
     {
        y=num/colNun+1;
         x=num%colNum;
    else
     {
        y=num/colNun;
        x=colNum;
     }
}
你能理解这个过程么 ?什么, 能用么 你可以验证下:
num=7
7%3!=0
{
  y=7/3+1=>3
  x=7%3=>1
}

num=6
6%3==0
{
  y=6/3=>2
  x=3=>3
}

num=5
5%3!=0
{
  y=5/3+1=>3
  x=5%3=>2
}

为什么要确定x跟y呢,因为输出的时候要给单幅图像定位 就是左上角 有了x跟y 才能够实现。可以有一个image的数组 用来存储接收到的图像 它们按照编号从前到后排列。

解决一个问题了

还有另外一个问题 图像的缩放。

如果我假设输出区域是宽度=297 高度=420。胶片的分格是4行3列 。那么单幅图像的尺寸是 宽度=297/3 高度=420/4 但是每个分格的图像尺寸通常是不固定的,就像普通的看图软件都有个显示比例叫“缩放到显示区域” 我们要做的就是这个 这一过程可以用这个图说明:

预先就设定图像都有两种等比例缩放尺寸 高度对齐(让高度跟可显示区域相等) 宽度对齐(让宽度跟可显示区域相等)。
这里有一个简单的等比例公式 缩放前后
宽度对齐情况下:
显示区域宽(缩放后的宽度)/原图宽=缩放后的高度/原图高
高度对齐情况下:
显示区域高(缩放后的高度)/原图高=缩放后的宽度/原图宽
分别得出两种情况另一边的长度
显示区域宽(缩放后的宽度)*原图高/原图宽=缩放后的高度
显示区域高(缩放后的高度)*原图宽/原图高=缩放后的宽度

然后对两种情况进行判断,如果哪种情况缩放后的图像区域超出了显示范围 则被否决。
如下图 蓝色框代表图像 ,黑色框代表显示区域:

就这样就达到了适应显示范围的等比例缩放。简单吧。
怎么把上述思路整合 然后用代码实现,首先我们得定义一个类 这个类叫Paper 相当于一张胶片 他是待打印区域 。
然后相应的要有 行数列数 显示区域高度宽度 等变量, 还要有一个image数组用来存储顺序编号排列的图像。

 

 1 public class Paper2 {3     int row, col;//行数 与 列数4     int width, height;//胶片宽度 高度5     IList<Image> images;//顺序编号的图像6 7     public Paper(int _width, int _height, int _row, int _col)8     {9         width = _width; height = _height; row = _row; col = _col;
10         images = new List<Image>(row * height);
11     }
12     //初始化显示区域
13     public Paper(int _row, int _col)
14     {
15         //width = 345 * 9; height = 420 * 9; row = _row; col = _col;//14INx17IN
16         width = 297 * 9; height = 420 * 9; row = _row; col = _col;//A3
17         images = new List<Image>(row * height);
18     }
19     //新增图像
20     public void addImg(Image img)
21     {
22         if (images.Count >= row * col)
23             return;
24         else
25         {
26             images.Add(img);
27         }
28     }
29 }

 

这相当于又是定义了一个数据模型的框架 初始化一个实例代表输出一张新的胶片。面向对象的分析设计是多么的好 哇哈哈。
材料有了 。下面这个函数才是重头戏,用于实现第一部分 分析的所有逻辑[胶片排版 跟 图像缩放],请对照第一部分的说明来看:

 

 1 //排版后的输出2 //排版方式为从上到下从左到右3 public Image layout()4 {5     Image layouted = new Bitmap(width, height);6 7     Graphics g = Graphics.FromImage(layouted);8     g.Clear(Color.Green);9     for (int i = 0; i < images.Count; i++)
10     {
11         int _row, _col;
12         if ((i + 1) % col != 0)
13         {
14             _row = (i + 1) / col + 1 - 1;  //    _row = (i + 1) / col + 1 - 1;
15             _col = (i + 1) % col - 1;  //    _col = (i + 1) / col - 1;
16         }
17         else
18         {
19             _row = (i + 1) / col - 1;
20             _col = col - 1;
21         }
22         if (_col < 0)
23         {
24             _col = 0;
25         }
26         if (_row < 0)
27         {
28             _row = 0;
29         }
30         GraphicsUnit u = GraphicsUnit.Pixel;
31         RectangleF recSrc = images[i].GetBounds(ref u);//原图像大小
32         RectangleF recDst;//缩放后大小并调整偏移位置
33 
34         //宽比宽 =长比长 超出的那一边需要固定长度 缩小以调整到视野内
35         float recH = ((width / col) * recSrc.Height) / recSrc.Width,
36             recW = ((height / row) * recSrc.Width) / recSrc.Height;
37 
38         if (recW > (width / col))//宽度超出 固定宽度调整高度
39             recDst = new RectangleF((width / col) * _col + 0,
40                 (height / row) * _row + ((height / row) - recH) / 2,
41                 (width / col), recH);
42         else//高度超出 固定高度调整宽度
43             recDst = new RectangleF((width / col) * _col + ((width / col) - recW) / 2,
44                 (height / row) * _row + 0,
45                 recW, (height / row));
46 
47         g.DrawImage(images[i], recDst, images[i].GetBounds(ref u), u);
48         //if (i == 4)
49         images[i].Save(i + "out.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
50     }
51 
52     //layouted.Save("layout.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
53     g.Dispose();
54 
55     return layouted;
56 }

 

调用:

 

1 Paper film = new Paper(3, 2);
2 film.addImg(Image.FromFile("1.jpg"));
3 film.addImg(Image.FromFile("2.jpg"));
4 film.addImg(Image.FromFile("3.jpg"));
5 film.addImg(Image.FromFile("4.jpg"));
6 film.addImg(Image.FromFile("5.jpg"));
7 film.addImg(Image.FromFile("6.jpg"));
8 
9 film.layout();

 


一直说想要讲下dicom协议的通讯 ,看来下次吧。
源码及测试文件下载猛击此处

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

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

相关文章

计算机课数学,这4个专业,对数学要求很高,数学不好的慎选!

建筑学专业这个专业就是典型数学课程比较多的专业&#xff0c;如果数学成绩不好&#xff0c;真心建议千万不要选择这个专业&#xff0c;因为学习的课程与大多与数学有关&#xff0c;而且难度较大。像代数&#xff0c;微积分&#xff0c;线性规划&#xff0c;统计学等课程都是在…

架构师之路(5)---IoC框架

1 IoC理论的背景 我们都知道在面向对象的应用中&#xff0c;软件系统都是由N个对象组成的&#xff0c;它们通过彼此的合作&#xff0c;最终实现业务逻辑。 图1&#xff1a;耦合在一起的对象 如果我们打开机械式手表的后盖&#xff0c;就会看到与上面类似的情形&#xff0c;各…

【转】数据库软考笔记(一)第一章 计算机硬件基础知识笔记总结

转自&#xff1a;https://blog.csdn.net/qq_36411874/article/details/115057569 目录 运算器&#xff1a;ALU、AC、DR、PSW 控制器&#xff1a;IR、PC、AR、ID 寄存器组&#xff08;了解即可&#xff09; 存储器 存储器与总线&#xff08;了解&#xff0c;考分类&#xf…

Vlan的转发过程

untag就是普通的ethernet报文&#xff0c;普通PC机的网卡是可以识别这样的报文进行通讯&#xff1b; tag报文结构的变化是在源mac地址和目的mac地址之后&#xff0c;加上了4bytes的vlan信息&#xff0c;也就是vlan tag头&#xff1b; 一般来说这样的报文普通PC机的网卡是不能…

翻转课堂说教案计算机,计算机学院崔海文:对翻转课堂的进一步认识与思考

近期我有幸参加了学校教师发展中心组织的信息化教学培训班&#xff0c;认真聆听了各位教授的讲座&#xff0c;收获颇多。傅钢善教授的报告《信息技术环境下如何上好一堂课》让我的收获最大&#xff0c;教授的讲座宛如一顿丰盛的大餐&#xff0c;生动且不失严谨的呈现在大家面前…

Dos下命令运行带有包名的Java类

这几天在回顾原来的知识,发现知识一段时间不整理的话很多东西手生的很,今天刚刚想在dos下运行一个java类却出错了.Exception in thread "main" java.lang.NoClassDefFoundError 为什么呢?后面找了许久发现是类中带有包名的问题. 1.当类没有包…

嵌入式的基础知识

1.嵌入式操作系统结构 一般情况下分为硬件子系统和软件子系统&#xff1b; 硬件子系统主要包括&#xff1a;CPU小系统&#xff0c;电源模块&#xff0c;调试模块&#xff0c;时钟模块&#xff0c;接口模块&#xff0c;复位和配置模块&#xff1b; 软件子系统主要包括&#x…

【转】DICOM医学图像处理:开源库mDCM与DCMTK的比較分析(一),JPEG无损压缩DCM图像

转自&#xff1a;https://www.cnblogs.com/mfrbuaa/p/4004114.html 有修订 背景介绍&#xff1a; 近期项目需求&#xff0c;需要使用C#进行最新的UI和相关DICOM3.0医学图像模块的开发。在C语言下&#xff0c;我使用的是应用最广泛的DCMTK开源库&#xff0c;在本专栏的起初阶段…

量子计算机的核心元件简称,计算机文化基础复习题(含答案).doc

计算机文化基础复习题(含答案)整理计算机文化基础复习题第一套一、单项选择题(每题1分&#xff0c;共30分)1、在Powerpoint2003中&#xff0c;若为幻灯片中的对象设置"驶入效果"&#xff0c;应选择对话框 (? )???? A、自定义放映???? B、幻灯片版式????…

xfire客户端对返回list很挑剔,所以需要使用泛型。

casldap异常分析 | xfirewebservice(服务器配置篇) 2008-12-31xfirewebservice(客户端调用篇) 服务接口&#xff0c;就是用来调用的&#xff0c;所以客户端显得尤为重要&#xff0c;xfire客户端对返回list很挑剔&#xff0c;所以需要使用泛型。 如何建立webservice client 步骤…

C语言关键字----Const

C中CONST的使用&#xff1a;   虽然这听起来很简单&#xff0c;但实际上&#xff0c;const的使用也是c语言中一个比较微妙的地方&#xff0c;微妙在何处呢&#xff1f;请看下面几个问题。   问题&#xff1a;const变量 & 常量   为什么下面的例子在使用一个const变量…

【转】DICOM的常用Tag分类和说明!!!!

转自&#xff1a;https://www.cnblogs.com/stephen2014/p/4579443.html 有删改 1. 前言&#xff1a; 基于DICOM3.0标准的医学图像中&#xff0c;每一张图像中都携带着许多的信息&#xff0c;这些信息主要可以分为Patient, Study, Series和Image四类。每一个DICOM Tag都是…

计算机卡在无法显示网页,我的电脑上网上银行一直“无法显示网页”

首先&#xff1a;打开一个网页&#xff0c;点击“工具”&#xff0d;&#xff0d;internet选项&#xff0d;&#xff0d;高级&#xff0d;&#xff0d;还原默认设置&#xff0d;&#xff0d;应用&#xff0d;&#xff0d;确定 其次&#xff1a;使用这个修复工具试一试&#xff…

在虚拟机上运行vxWorks

Vxworks是一个嵌入式系统&#xff0c;主要运行在arm、ppc、mips等嵌入式处理器上&#xff0c;它同样可以运行在X86处理器上。风河公司开发的tornado开发环境就 包括了pentium版本&#xff0c;并且发布了相应的bsp。因此我们可在vmware虚拟机上运行vxworks&#xff0c;利用虚拟机…

【转】成熟的医学影像“调窗”(window-leveling)算法详解

转自&#xff1a;http://blog.sina.com.cn/s/blog_4bce5f4b0100o9iy.html 图像显示和打印面临的一个问题是&#xff1a;图像的亮度和对比度能否充分突出关键部分。这里所指的“关键部分”在 CT 里的例子有软组织、骨头、脑组织、肺、腹部等等。 技术问题&#xff1a; 显示…

南京大学计算机系副教授名单,2018年度国际“人工智能10大新星”名单公布:南京大学俞扬副教授国内高校入选者...

中公考研小编为各位考研小伙伴们整理了关于2018年度国际“人工智能10大新星”名单公布&#xff1a;南京大学俞扬副教授国内高校唯一入选者的相关资讯文章&#xff0c;一起了解一下吧~日前&#xff0c;国际人工智能领域著名杂志 IEEE Intelligent Systems 发布了2018年度“人工智…

使用SDL打造游戏世界之入门篇 - 7

打开和显示图片在这个例子里我们将学习如何使用SDL程序中打开和显示图片。示例程序将绘制一个漂亮的背景&#xff0c;上面显示一个正方形图案&#xff0c;并可以使用键盘的方向键移动它。如果比较熟悉“推箱子”这个游戏&#xff0c;可以看出这个程序实际就是推箱子游戏的基础。…

WDB

1. 符号表同步貌似只能是target shell下载后&#xff0c;能够在host shell下更新&#xff0c;当host shell下载的话&#xff0c;target shell是无法更新的。 2. host shell下执行某一个函数的时候&#xff0c;WDB会自动生成一个新的任务来运行&#xff0c;这个任务的IO将被重定…

【转】GPS从入门到放弃(一) --- GPS基础原理

转自&#xff1a;https://blog.csdn.net/tyst08/article/details/100529424 GPS从入门到放弃&#xff08;一&#xff09; — GPS基础原理 GPS&#xff0c;全称Global Positioning System&#xff0c;已经广泛应用于我们的日常生活中了&#xff0c;现在的智能手机 里都会自带G…

计算机系统的物质实体,计算机基础-(-第1次-).pdf

计算机基础 -(- 第 1 次-)第 1 次作业一、填空题(本大题共 30 分&#xff0c;共 10 小题&#xff0c;每小题 3 分)1. 二进制数求积 011 ______ 。2. 计算机系统是由 _ ______ 和 ______ _ 两大部分组成的。3. 八个二进制位称为一个 ______ &#xff0c;是计算机的最小存储单元。…