• DICOM医学图像处理:WEB PACS初谈


    背景:

            周末看到了一篇原公司同事的文章。讲的是关于新的互联网形势下的PACS系统。

    正好上一篇专栏文章也提到了有想搭建一个worklistserver的冲动,所以就翻箱倒柜将原本学生时代做课题时搭建的简易Web PACS找了出来,借着再次搭建的机会学习一下Web PACS相关的技术,比如WADO标准、CGI或者FastCGI等技术。

    WEB PACS技术浅谈:

            WEB PACS是一种利用互联网技术。跨越了医院和地域限制的,可任意查询和获取DICOM对象的PACS系统。眼下常见的方式有两种:第一种是通过Webserver提供查询定位,将相应DICOM影像存储server(通常为FTP)的地址与路径返回,client再向DICOM影像存储server请求对象。另外一种是通过Webserver统一提供查询及返回请求对象。

    两者各有利弊,第一种通过分别部署Webserver和FTP文件server,减轻了Webserver的负担,加快了响应时间,可是该方案也存在着诸多缺点,比如获取图像须要发送两次请求。FTPserver安全性维护代价高。要求在浏览器下载可以解析DICOM图像的插件等等;另外一种Webserver整合了查询与返回,去除了FTPserver。部署方便。它的缺点是因为Webserver返回的数据是真实DCM转换过来的BMPJPEG文件。因此某些依赖于DICOM文件其它信息的操作(比如窗宽窗位调整)须要又一次请求服务端,要求更新数据。因此对server的处理能力消耗较大,对带宽也有一定要求。

    两种方式的示意图例如以下:


    (摘自文献《DICOM WADO原理及应用研究》)

    1WADO

            WADOWeb Access to DICOM Persistent Object),是DICOM标准中的一部分,提供了一种通过HTTPHTTPS协议并利用DICOM的标识符从HTML页或XML文档中存取与重现DICOM对象的机制,用于解决在互联网环境下訪问DICOM对象——这也能够觉得是Web PACS的终极目标。与标准的基于HTTPHTTPS的网络訪问方式同样。用户在浏览器地址栏中输入URL,向server发送WEB请求。server接收到请求后依据URL中提供的參数,在服务端定位要求的图像或报告回送给浏览器,示意图例如以下(摘自DICOM标准第18章)。

            事实上WADO标准就是定义了client和服务端之间交互的规则。能够简单的理解为双向交互时的參数约定,即服务端能够依据浏览器端发送參数的不同来实现常见的单机版PACSC-FINDC-MOVEC-STORE等功能。

    DICOM标准中关于WADO部分的介绍也主要是各种參数规则的说明,以及部分URL实例,这里截取一个来简单的说明一下:


            如上图所看到的,URL採用常见的GET方式。将传统的PACS系统client发送查询时的參数发送给服务端,比如studyUIDseriesUIDobjectUID(事实上就是DICOM图像中的SOP Instance UID)。

    2CGI

            CGICommon Gateway Interface),是WWW技术中最重要的技术之中的一个。有着不可代替的重要地位。

    CGI定义了外部应用程序(CGI程序)与Webserver之间的接口标准,独立于开发语言。给用户提供了一种从网页浏览器向运行在server上的程序请求数据的方式——Web PACS的实现提供了一种途径。

            为了理解CGI的含义。必需要搞清楚WEB开发中常见的前端和后端。前端就是Web应用中用户能够看得见碰的着的东西。服务端接收到请求后大多直接将传输数据到浏览器。后端很多其它的是用户看不到的(这里指的看不到不是操作后的结果看不到,而是操作的流程看不到),接收到请求后需要服务端进一步操作的。比如查询数据库、算法运算等等。而CGI就是实现这样的由浏览器的输入触发在WEBserver上执行的程序的标准。

    实际环境搭建:

            正如博文第一部分所述,因为第一类Web PACS须要浏览器安装第三方插件,须要单独部署FTPserver,因此在课题起初没有採用该方案。

    另外一种Web PACS服务端在接受请求后会再向影像server发送请求,这正是上文中提到的CGI技术的一种非常好的应用场景。以下就详细介绍一下怎样搭建CGI应用环境:

    1WampServer+FastCGI

    Webserver搭建:

            WampServer安装包下载http://www.wampserver.com/en/#wampserver-64-bits-php-5-5

            安装过程中有可能会遇到缺少msvcr110.dll,程序无法启动错误。能够參照http://jingyan.baidu.com/article/ed2a5d1f3303d709f7be1776.html中给出的方法解决,须要提醒的是下载的Visual C++ Redistributable for VisualStudio 2012 Update 4版本号不是由电脑的操作系统类型(32or64位)来决定,而是应该依据WampServer安装包的类型来选择。

    安装完Visual C++ Redistributable for VisualStudio 2012 Update 4后须要又一次安装WampServer

    配置FastCGI环境:

    參考http://www.admin10000.com/Document/53.htmlhttp://my.oschina.net/Twitter/blog/210044Apacheserver进行配置。在配置完毕后重新启动WampServer居然失败,出现例如以下错误:

            更悲剧的是查看ApacheErrorLog居然没有提示,所以仅仅能对改动的httpd.conf配置文件逐行排查,通过逐行凝视的本方法最后找到了问题所在。因为改动DirectoryIndex引发的错误,恢复到原本的顺序后,重新启动WampServer居然奇迹般的成功了,小有成就感啊。至于详细的原因兴许在慢慢查找,确定了再补充上来。

    2C语言CGI实例

            配置完开发环境后,给出一个简单的測试,因为电脑中没有安装PHP,所以这里就讨巧一下,直接利用Apache自带的cgi来调用一下C语言开发的程序。关于C语言CGI的配置比較简单。在Apache文件夹下的modules中已经包括了cgi模块,仅仅须要在httpd.conf配置文件里指定c-cgi执行的文件夹就可以,加入例如以下代码:

    ScriptAlias /cgi-bin/"C:/wamp/www/c-cgi/"
    AddHandler cgi-script .exe .pl .cgi
    <Directory"C:/wamp/www/c-cgi/">
    Options Indexes FollowSymLinks ExecCGI
    AllowOverride all
    Order allow,deny
    Allow from all
    Require local
    </Directory>
            详细的配置可參考http://blog.sina.com.cn/s/blog_66ec4d660100rd2h.html,实例的话就不要用该博文中的了。用我以下给出的完整演示样例。

    GET方法实例源代码

    #include <stdio.h>
    #include <stdlib.h>
    int main(void)
    {
            char *data;
            char a[10],b[10];
            printf("Content-Type:text/html
    
    ");
            printf("<HTML>
    ");
            printf("<HEAD>
    <TITLE >Get Method</TITLE>
    </HEAD>
    ");
            printf("<BODY>
    ");
            printf("<div style="font-size:12px">
    ");
            data = getenv("QUERY_STRING");
    		if(data==NULL)
    			return 1;
            if(sscanf(data,"a=%[^&]&b=%s",a,b)!=2){
                    printf("<DIV STYLE="COLOR:RED">Error parameters should be entered!</DIV>
    ");
            }
            else{
                   printf("<DIV STYLE="COLOR:GREEN; font-size:15px;font-weight:bold">a + b = %d</DIV>
    ",atoi(a)+atoi(b));
            }
            printf("<HR COLOR="blue" align="left" width="100">");
            printf("<input type="button" value="Back CGI" onclick="javascript:window.location='../cgitest-c.html'">");
            printf("</div>
    ");
            printf("</BODY>
    ");
            printf("</HTML>
    ");
            return 0;
    }
    利用VS编译后的可运行文件为gettest.exe。放到/www/cgitest-c文件夹下。

    POST方法实例源代码

    #include <stdio.h>
    #include <stdlib.h>
    int main(void){
            int len;
            char *lenstr,poststr[20];
            char m[10],n[10];
            printf("Content-Type:text/html
    
    ");
            printf("<HTML>
    ");
            printf("<HEAD>
    <TITLE >post Method</TITLE>
    </HEAD>
    ");
            printf("<BODY>
    ");
            printf("<div style="font-size:12px">
    ");
            lenstr=getenv("CONTENT_LENGTH");
            if(lenstr == NULL)
                    printf("<DIV STYLE="COLOR:RED">Error parameters should be entered!</DIV>
    ");
            else{
                    len=atoi(lenstr);
                    fgets(poststr,len+1,stdin);
                    if(sscanf(poststr,"m=%[^&]&n=%s",m,n)!=2){
                            printf("<DIV STYLE="COLOR:RED">Error: Parameters are not right!</DIV>
    ");
                    }
                    else{
                           printf("<DIV STYLE="COLOR:GREEN; font-size:15px;font-weight:bold">m * n = %d</DIV>
    ",atoi(m)*atoi(n));
                    }
            }
            printf("<HR COLOR="blue" align="left" width="100">");
            printf("<input type="button" value="Back CGI" onclick="javascript:window.location='../cgitest-c.html'">");
            printf("</div>
    ");
            printf("</BODY>
    ");
            printf("</HTML>
    ");
            fflush(stdout);
            return 0;
    }
    利用VS编译后的可运行文件为posttest.exe。相同放到/www/cgitest-c文件夹下。

    測试网页源代码

    <html>
    <head>
    <title>CGI Testing</title>
    </head>
    <body>
    <table width="200" height="180" border="0" style="font-size:12px">
    <tr><td>
    <div style="font-weight:bold; font-size:15px">Method: GET</div>
    <div>please input two number:<div>
    <form method="get" action="./c-cgi/gettest.exe">
    <input type="txt" size="3" name="a">+
    <input type="txt" size="3" name="b">=
    <input type="submit" value="sum">
    </form>
    </td></tr>
    <tr><td>
    <div style="font-weight:bold; font-size:15px">Method: POST</div>
    <div>please input two number:<div>
    <form method="post" action="./c-cgi/posttest.exe">
    <input type="txt" size="3" name="m">*
    <input type="txt" size="3" name="n">=
    <input type="submit" value="resu">
    </form>
    </td></tr>
    <tr><td><input type="button" value="Back Home" onclick='javascript:window.location="./index.php"'></td></tr>
    </table>
    </body>
    </html>
    放到Apacheserver根文件夹下,在浏览器中通过localhost/cgitest-c.html能够訪问到。

    实际执行结果

            上述通过一个简单的计算来演示了CGI技术的实现和开发流程。当然对于简单的数字计算WEB前端自己就搞定了,此处仅仅是为了说明CGI流程。至此整个Web PACSWeb服务端就已经搭建的几乎相同了,利用CGIFastCGI我们能够使用服务端的其它语言开发的程序来实现我们想要的功能,那么兴许的工作就跟开发C/S模式的PACS一样了。用C/C++C#JAVA等高级语言开发PACS服务相关的程序供Webserver调用就可以。本博文中演示的是调用exe可运行文件,这样的方式有风险,兴许我会介绍在FastCGI模式下的利用PHP调用C++C#JAVA动态库的更安全的实现方式。


    兴许博文介绍

    利用DCMTK搭建WMLserver

    利用oracle直接操作DICOM数据

    C#的异步编程模式在fo-dicom中的应用

    VMWare三种网络连接模式的实际測试




    作者:zssure@163.com

    时间:2014-10-19

  • 相关阅读:
    Wonderful hyperlinks of MVVM(ModelViewViewModel)Design Pattern Virus
    [Translation]Silverlight 4MVVM with Commanding and WCF RIA Services Virus
    微软企业库4.1学习笔记(一)开篇乱弹 Virus
    根据总用量计算每种包装规格的购买量和总价 Virus
    微软企业库4.1学习笔记(二)各功能之间的依赖关系以及对象创建 Virus
    silverlight+wcf:relation entity VS. relation entity's code Virus
    根据总用量计算每种包装规格的购买量和总价 后续篇(一)并且使得用户花费最少 Virus
    Team Build Workflow 资源汇总
    VSTF Build Workflow(3)Hello World!
    初探798
  • 原文地址:https://www.cnblogs.com/llguanli/p/6835090.html
Copyright © 2020-2023  润新知