DICOM标准学习路径图,数据加载

背景:

上1篇博文DICOM:DICOM万能编辑工具之Sante DICOM
Editor
介绍了DICOM万能编辑工具,在1般使用进度中窥见,“只要Sante DICOM
艾德itor打不开的数量,基本得以判断此DICOM文件格式错误(准确率达9九.999玖%^_^)”
。在感慨Sante
DICOM
Editor神器牛掰的还要,想掌握一下其底层是何等促成的。通过普通使用以及阅读软件协帮手册测度其底层正视库非常大概是dcmtk,就就如本身使用dcmtk、fo-dicom、dcm4che叁等诸多DICOM开源库境遇的包容性难点类似,——dcmtk包容性最强,fo-dicom次之,dcm肆che叁最差

背景:

上1篇博文DICOM:DICOM万能编辑工具之Sante DICOM
艾德itor
介绍了DICOM万能编辑工具,在壹般行使进程中窥见,“只要Sante DICOM
艾德itor打不开的数额,基本得以肯定此DICOM文件格式错误(准确率达9九.999玖%^_^)”
。在感慨Sante
DICOM
艾德itor神器牛掰的同时,想理解一下其底层是什么样贯彻的。通过普通使用以及阅读软件补帮手册臆想其底层注重库很大概是dcmtk,就犹如自个儿使用dcmtk、fo-dicom、dcm四che三等重重DICOM开源库境遇的包容性难题类似,——dcmtk包容性最强,fo-dicom次之,dcm四che三最差

题记:

DICOM管医学图像处理专辑撰写已有多少个年头,积累了近百篇小说。起初只是用来记录本人调查钻探、职业中境遇的疑难难点,专注于图像处理(主假设管军事学图像,那也多亏专栏名称最初的原委);后来逐步延长到了DICOM数据传输动向,专注于医院内影象数据的传导和管制,遂将博文标题依照【DICOM军事学图像处理:XXX】和【DICOM:XXX】划分,分别介绍图像处理和数码传输;到最后又加多了开源工具浅析部分,诸如DICOM开源实现库(dcmtk、dcm4che、fo-dicom)、开源PACS系统(Orthanc、dcm四chee、ClearCanvas)。

问题:

本篇通过对照dcmtk叁.陆与dcm四che三.x解析同1特殊dicom文件带有非标准化准V哈弗的因素)分析dcmtk、dcm4che以及fo-dicom数据加载的兼容性问题。
出奇的dicom文件内容如下:
28
00 20 01 20 20 02
00 30
F捌,具体讲述如下: 
图片 1 
运用dcmtk与fo-dicom加载数据时都未出现谬误,例如dcmtk加载数据时的提示如下: 
图片 2 
通过可以看到dcmtk已经胜利辨识出了非标准VR的元素(0028,0120),并打响加载。 
即使应用fo-dicom加载数据尚未出现谬误,但是对于上述非标准VR的元素(0028,0120)后的要素未顺利加载,如下图所示: 
图片 3 
而dcm4che三加载进度中平素弹出了不当,如下所示: 
图片 4

问题:

本篇通过相比dcmtk三.6与dcm4che三.x解析同1特殊dicom文件包罗非标准化准VR的元素)分析dcmtk、dcm4che以及fo-dicom数据加载的包容性问题。
破例的dicom文件内容如下:
28 00
20 01 20 20 02
00 30
F八,具体讲述如下: 
图片 5 
选择dcmtk与fo-dicom加载数据时都未出现错误,例如dcmtk加载数据时的晋升如下: 
图片 6 
因此能够见见dcmtk已经胜利辨识出了非标准VR的元素(0028,0120),并打响加载。 
固然如此采纳fo-dicom加载数据未有出现谬误,可是对于上述非标准VR的元素(0028,0120)后的成分未意得志满加载,如下图所示: 
图片 7 
而dcm四che三加载进程中央直机关接弹出了不当,如下所示: 
图片 8

背景:

近年壹再收下网络好友邮件或私信希望交给三个简约的认证,方便由简到难的来日趋浏览和读书专栏中的博文。自身依据上述的主线来写,平昔感到逻辑还算清晰,但本人回看起来,对于初学者甚至外行来讲,专栏全体还不够清楚,一时很难找到切入点举行学习。因而近期一向在设想写一篇关于“DICOM学习路径图”的博文,构思许久仍感充满纰漏,如何能够让初大方火速调节DICOM相关文化?如何能够学习知识点的还要进行实际编制程序陶冶?还有大批量的主题材料从未想好、想明白……
前几天一时整理初稿,大概对专栏小说打开三个粗略分类,以便初学者快捷归类定位有关博文,后续会没完没了立异完善,希望达到和谐那时“深远浅出,引领DICOM学习”的设想。

难题分析:

现身该难题的案由是dcm四che3和fo-dicom在解析0028,0120元素时,对于20 20的非标准VR胸中无数甄别。下文元帅通过分析dcm四che3与dcmtk的源码来定位难题的具体地点并付出化解方案(此处方今只相比分析了dcm四che3.三.捌最新版与dmctk三.陆的源码,对于fo-dicom的源码分析待继续整理产生后再补偿)。

主题素材浅析:

并发该难题的缘故是dcm四che三和fo-dicom在分析0028,0120元素时,对于20 20的非标准VR相当小概甄别。下文旅长通过分析dcm4che3与dcmtk的源码来定位难题的具体地方并交由化解方案(此处暂且只比较分析了dcm四che叁.叁.八时髦版与dmctk3.六的源码,对于fo-dicom的源码分析待后续整理造成后再补偿)。

DICOM全体观念导图:

DICOM协议属于开放式系统互联OSI7层模型中的应用层,与我们壹般最常用的HTTP协议(HTTP,大概等同互连网的代名词,当然是因为其安全性难点正在慢慢被HTTPS取代)类似。两者兼有广大形似的地点,想必我们对HTTP协议都怀有通晓,因而决定通过类比DICOM与HTTP来介绍DICOM协议,让大家快速对DICOM协议有一个宏观的握住。

对比 HTTP DICOM
OSI层 应用层 应用层
数据 HTML文件 .DCM文件
服务 GET、POST、HEAD、PUT
PUT、DELETE、TRACE、CONNECT、OPTIONS
C-ECHO、C-FIND、C-STORE、C-MOVE、C-GET
N-GET、N-SET、N-ACTION、N-CREATE、N-DELETE、N-EVENT-REPORT
应用 互联网B/S模式,
也可以用于C/S模式
C/S模式,
也可以用于WADO(B/S模式)

 

简单的讲: style=”color: green;”>将DICOM协议当做是专属于医疗领域的“HTTP”传输协议,常见的HTTP协议是经过上表中的各样服务来促成浏览器服务器之间HTML格式数据的传输;DICOM协议是透过上表中的种种劳动完成了看病设备多少核心之间DCM格式数据的传输。

虽说在互连网中平常会混淆HTTP与HTML三个概念(实际情况能够参见HTTP vs
HTML
),但从缩写上来看照旧比较好界别:3个是网络传输协议(HTTP),一个是数码格式标识语言(HTML),在HTTP协议中发送的便是HTML格式的多寡。 style=”color: red;”>进入到DICOM领域只怕更易于混淆视听,因为在DICOM领域传输使用的协商和协商上传输的数目都称为DICOM,一个叫作DICOM协议,一个称为DICOM图像(即.dcm后缀的文书)。以前HTTP与HTML同属于网络只是由不一致的团队部门制定和发布,而DICOM协议和DICOM数据同时涵盖在DICOM标准中(最新的业内是DICOM3.0)。

如是,为了更加好的上学DICOM标准,根据类似HTTP(协议)和HTML(数据)的章程将DICOM标准进行一个分叉。全体的思辨导图如下:
图片 9

1. dcmtk3.6源码:

使用dcmtk编写本次数据加载测试工程,轻松的以身作则代码如下:

int main()
{
    OFLog::configure(OFLogger::TRACE_LOG_LEVEL);
    char* ifname = "c:\\1.dcm";
    E_FileReadMode readMode = /*ERM_fileOnly*/ERM_autoDetect;
    E_TransferSyntax xfer =  EXS_Unknown;
    Uint32 maxReadLength = DCM_MaxReadLength;
    bool loadIntoMemory = true;
    DcmFileFormat dfile;
    DcmObject *dset = &dfile;
    if (readMode == ERM_dataset) dset = dfile.getDataset();
    OFCondition cond = dfile.loadFile(ifname, xfer, EGL_noChange, maxReadLength, readMode);
    if (cond.bad())
    {
        return 1;
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

单步调节和测试,能够精通dcmtk加载dicom文件的流水生产线如下:

  1. 创建 style=”color: red;”>DcmMetaInfo、DcmDataset元素
  2. 独家加载 style=”color: red;”>DcmMetaInfo、DcmDataset元素
  3. 使用DcmItem中的 style=”color: blue;”>readGroupLength、readTagAndLength、readSubElement稳步加载 style=”color: red;”>DcmMetaInfo、DcmDataset的次第子成分。

在DcmItem类中对于非标准VR元素有对应的警告提醒消息,

/* if the VR which was read is not a standard VR, print a warning */
        if (!vr.isStandard())
        {
            OFOStringStream oss;
            oss << "DcmItem: Non-standard VR '"
                << ((OFstatic_cast(unsigned char, vrstr[0]) < 32) ? ' ' : vrstr[0])
                << ((OFstatic_cast(unsigned char, vrstr[1]) < 32) ? ' ' : vrstr[1]) << "' ("
                << STD_NAMESPACE hex << STD_NAMESPACE setfill('0')
                << STD_NAMESPACE setw(2) << OFstatic_cast(unsigned int, vrstr[0] & 0xff) << "\\"
                << STD_NAMESPACE setw(2) << OFstatic_cast(unsigned int, vrstr[1] & 0xff)
                << ") encountered while parsing element " << newTag << OFStringStream_ends;
            OFSTRINGSTREAM_GETSTR(oss, tmpString)
            /* encoding of this data element might be wrong, try to correct it */
            if (dcmAcceptUnexpectedImplicitEncoding.get())
            {
                DCMDATA_WARN(tmpString << ", trying again with Implicit VR Little Endian");
                /* put back read bytes to input stream ... */
                inStream.putback();
                bytesRead = 0;
                /* ... and retry with Implicit VR Little Endian transfer syntax */
                return readTagAndLength(inStream, EXS_LittleEndianImplicit, tag, length, bytesRead);
            } else {
                DCMDATA_WARN(tmpString << ", assuming " << (vr.usesExtendedLengthEncoding() ? "4" : "2")
                    << " byte length field");
            }
            OFSTRINGSTREAM_FREESTR(tmpString)
        }

        /* set the VR which was read in the above created tag object. */
        newTag.setVR(vr);

        /* increase counter by 2 */
        bytesRead += 2;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

在告诫后,对于非标准VR元素的处理进程如下:

 /* read the value in the length field. In some cases, it is 4 bytes wide, in other */
    /* cases only 2 bytes (see DICOM standard part 5, section 7.1.1) */
    if (xferSyn.isImplicitVR() || nxtobj == EVR_na)   //note that delimitation items don't have a VR
    {
        inStream.read(&valueLength, 4);            //length field is 4 bytes wide
        swapIfNecessary(gLocalByteOrder, byteOrder, &valueLength, 4, 4);
        bytesRead += 4;
    } else {                                       //the transfer syntax is explicit VR
        DcmVR vr(newTag.getEVR());
        if (vr.usesExtendedLengthEncoding())
        {
            Uint16 reserved;
            inStream.read(&reserved, 2);           // 2 reserved bytes
            inStream.read(&valueLength, 4);        // length field is 4 bytes wide
            swapIfNecessary(gLocalByteOrder, byteOrder, &valueLength, 4, 4);
            bytesRead += 6;
        } else {
            Uint16 tmpValueLength;
            inStream.read(&tmpValueLength, 2);     // length field is 2 bytes wide
            swapIfNecessary(gLocalByteOrder, byteOrder, &tmpValueLength, 2, 2);
            bytesRead += 2;
            valueLength = tmpValueLength;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

由上述代码可见,0028,0120VR=20,20,被dcmtk解析为 EVR_UNKNOWN二B类型,就像代码注释中所描述:

/// used internally for elements with
unknown VR with 2-byte length field in explicit VR 
EVR_UNKNOWN2B

DICOM标准PS5的7.1.2有对于非标准化准VOdyssey的连锁描述,如下: 
图片 10

1. dcmtk3.6源码:

应用dcmtk编写本次数据加载测试工程,轻松的演示代码如下:

int main()
{
    OFLog::configure(OFLogger::TRACE_LOG_LEVEL);
    char* ifname = "c:\\1.dcm";
    E_FileReadMode readMode = /*ERM_fileOnly*/ERM_autoDetect;
    E_TransferSyntax xfer =  EXS_Unknown;
    Uint32 maxReadLength = DCM_MaxReadLength;
    bool loadIntoMemory = true;
    DcmFileFormat dfile;
    DcmObject *dset = &dfile;
    if (readMode == ERM_dataset) dset = dfile.getDataset();
    OFCondition cond = dfile.loadFile(ifname, xfer, EGL_noChange, maxReadLength, readMode);
    if (cond.bad())
    {
        return 1;
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

单步调节和测试,能够精通dcmtk加载dicom文件的流水生产线如下:

  1. 创建 style=”color: red”>DcmMetaInfo、DcmDataset元素
  2. 分级加载 style=”color: red”>DcmMetaInfo、DcmDataset元素
  3. 使用DcmItem中的 style=”color: blue”>readGroupLength、readTagAndLength、readSubElement慢慢加载 style=”color: red”>DcmMetaInfo、DcmDataset的相继子成分。

在DcmItem类中对此非标准VR元素有照应的警示提醒消息,

/* if the VR which was read is not a standard VR, print a warning */
        if (!vr.isStandard())
        {
            OFOStringStream oss;
            oss << "DcmItem: Non-standard VR '"
                << ((OFstatic_cast(unsigned char, vrstr[0]) < 32) ? ' ' : vrstr[0])
                << ((OFstatic_cast(unsigned char, vrstr[1]) < 32) ? ' ' : vrstr[1]) << "' ("
                << STD_NAMESPACE hex << STD_NAMESPACE setfill('0')
                << STD_NAMESPACE setw(2) << OFstatic_cast(unsigned int, vrstr[0] & 0xff) << "\\"
                << STD_NAMESPACE setw(2) << OFstatic_cast(unsigned int, vrstr[1] & 0xff)
                << ") encountered while parsing element " << newTag << OFStringStream_ends;
            OFSTRINGSTREAM_GETSTR(oss, tmpString)
            /* encoding of this data element might be wrong, try to correct it */
            if (dcmAcceptUnexpectedImplicitEncoding.get())
            {
                DCMDATA_WARN(tmpString << ", trying again with Implicit VR Little Endian");
                /* put back read bytes to input stream ... */
                inStream.putback();
                bytesRead = 0;
                /* ... and retry with Implicit VR Little Endian transfer syntax */
                return readTagAndLength(inStream, EXS_LittleEndianImplicit, tag, length, bytesRead);
            } else {
                DCMDATA_WARN(tmpString << ", assuming " << (vr.usesExtendedLengthEncoding() ? "4" : "2")
                    << " byte length field");
            }
            OFSTRINGSTREAM_FREESTR(tmpString)
        }

        /* set the VR which was read in the above created tag object. */
        newTag.setVR(vr);

        /* increase counter by 2 */
        bytesRead += 2;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

在警告后,对于非标准VR元素的处理进度如下:

 /* read the value in the length field. In some cases, it is 4 bytes wide, in other */
    /* cases only 2 bytes (see DICOM standard part 5, section 7.1.1) */
    if (xferSyn.isImplicitVR() || nxtobj == EVR_na)   //note that delimitation items don't have a VR
    {
        inStream.read(&valueLength, 4);            //length field is 4 bytes wide
        swapIfNecessary(gLocalByteOrder, byteOrder, &valueLength, 4, 4);
        bytesRead += 4;
    } else {                                       //the transfer syntax is explicit VR
        DcmVR vr(newTag.getEVR());
        if (vr.usesExtendedLengthEncoding())
        {
            Uint16 reserved;
            inStream.read(&reserved, 2);           // 2 reserved bytes
            inStream.read(&valueLength, 4);        // length field is 4 bytes wide
            swapIfNecessary(gLocalByteOrder, byteOrder, &valueLength, 4, 4);
            bytesRead += 6;
        } else {
            Uint16 tmpValueLength;
            inStream.read(&tmpValueLength, 2);     // length field is 2 bytes wide
            swapIfNecessary(gLocalByteOrder, byteOrder, &tmpValueLength, 2, 2);
            bytesRead += 2;
            valueLength = tmpValueLength;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

由上述代码可见,0028,0120VR=20,20,被dcmtk解析为 EVR_UNKNOWN贰B类型,就好像代码注释中所描述:

/// used internally for elements with
unknown VR with 2-byte length field in explicit VR 
EVR_UNKNOWN2B

DICOM标准PS5的7.1.2有对于非标准化准V奇骏的相关描述,如下: 
图片 11

DICOM专栏博文分类:

根据上述思维导图的分割方法,将DICOM军事学图像处理专栏中的博文对应举办1个大致的归类。大约如下:

2. dcm4che3.3.8源码:

再对照dcm四che三.三.8的源码,单步调节和测试发现,对于0028,0120VR=20,20,被dcmtk直接标识为UN类型,

public static VR valueOf(int code) {
        try {
            VR vr = VALUE_OF[indexOf(code)];
            if (vr != null)
                return vr;
        } catch (IndexOutOfBoundsException e) {}
        LOG.warn("Unrecogniced VR code: {0}H - treat as UN",
                Integer.toHexString(code));
        return UN;
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

还要在dcm四che三中对此UN类型定义为 
图片 12 
此处UN类型是参照上述截图中DICOM3.0行业内部对于V奥迪Q5=UN(unknown)类型的标签订契约束来定义的,即,其VRubicon字段应该是多个字节。不过这里0028,0120VR=20,20后的Value Length唯有三个字节02 00。由此变成dcm4che三在加载0028,0120要素时,将其尺寸错误地剖析为4163895298,即十6进制的F8 30 00 02,如下图所示: 
图片 13

2. dcm4che3.3.8源码:

再对照dcm四che三.3.八的源码,单步调节和测试发现,对于0028,0120VR=20,20,被dcmtk直接标志为UN类型,

public static VR valueOf(int code) {
        try {
            VR vr = VALUE_OF[indexOf(code)];
            if (vr != null)
                return vr;
        } catch (IndexOutOfBoundsException e) {}
        LOG.warn("Unrecogniced VR code: {0}H - treat as UN",
                Integer.toHexString(code));
        return UN;
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

还要在dcm四che3中对此UN类型定义为 
图片 14 
此处UN类型是参照上述截图中DICOM三.0正经对于VSportage=UN(unknown)类型的标签约束来定义的,即,其V中华V字段应该是三个字节。但是那里0028,0120VR=20,20后的Value Length只有八个字节02 00。因而形成dcm4che3在加载0028,0120要素时,将其尺寸错误地剖析为4163895298,即十陆进制的F8 30 00 02,如下图所示: 
图片 15

DICOM标准介绍篇:

该有的从全体上对DICOM标准进行介绍,别的还会提到到任何治疗领域的消息化标准,诸如HL七、IHE等,使得读者对DICOM标准有二个完好无损宏观上的握住。
1. DICOM军事学图像处理:周全剖析DICOM叁.0正式中的通讯服务模块 
2. DICOM经济学图像处理:浅析SWF、WML、SPS、MPPS 
3. DICOM理学图像处理:DICOM网络传输 
4. DICOM:DICOM3.0互联网通讯协议(续)

化解方案:

迄今停止我们找到了dcm四che3错误解析0028,0120VR=20,20非标准化准VHummerH二成分的由来。对此那种非标准化准VGL450不能够统一作为V奥迪Q五.UN类型实行拍卖,而相应依照其承袭的Value
Length的切实可行尺寸为二恐怕四来展开分类处理
关于该难题持续博文子禽继续深切剖析,请小心),需求修改的地点有两处:

消除方案:

至此我们找到了dcm四che三错误解析0028,0120VR=20,20非标准化准VENVISION成分的原由。对此那种非标准化准V悍马H2不可能统一作为V奇骏.UN类型进行拍卖,而相应根据其继续的Value
Length的切实可行尺寸为二大概4来进展分类处理
关于该难题持续博文仲继续浓密剖析,请小心),供给修改的地点有两处:

DICOM数据篇:

该部分首要以.dcm后缀的文本为对象,即常常所说的艺术学影像(当然DICOM标准不单单存款和储蓄2维影象,还是能储存一维的心电数据、动态印象、4维超声/CT等等),介绍文件的不荒谬化操作(解析、写入、格式转变)和高等处理(常见的图像处清理计算法,诸如去噪、加强、分割、融合等等)。
1. DCMediaTek开源库类承接结构与DICOM3.0专业成分定义的附和关系图 
2. DC高通开源库的上学笔记壹:将DCM文件保留成BMP文件或数据流(即数组) 
3. DCMediaTek开源库的学习笔记二:直接操作dcm文件中像素数据的品尝 
4. DCMediaTek开源库的求学笔记叁:dcmtk文件中多少元的修改 
5. DCMediaTek开源库类承接结构与DICOM三.0专业元素定义的相应关系图 
6. DICOM工学图像处理:Dcmtk与fo-dicom保存文件的比不上设计方式之“同步VS异步”+“单线程VS二拾102线程” 
7. DICOM军事学图像处理:DICOM存款和储蓄操作之“多幅BMP图像数据存入DCM文件” 
8. DICOM工学图像处理:DICOM存款和储蓄操作之
“多幅JPG图像数据存入DCM文件”
 
9. DICOM:基于fo-dicom的简易DICOM
Viewer
 
10. DICOM:Transfer Syntax传输语义之奇葩GE Private
TS
 
11. DICOM:DICOM叁大开源库相比较分析之“数据加载”

一. 毋庸置疑分析Non-standard VOdyssey:

//VR.java,Line 110
public static VR valueOf(int code) {
        try {
            VR vr = VALUE_OF[indexOf(code)];
            if (vr != null)
                return vr;
        } catch (IndexOutOfBoundsException e) {}
        LOG.warn("Unrecogniced VR code: {0}H - treat as UN",
                Integer.toHexString(code));
        //return UN;
        LOG.warn("zssure:to solve non-standard VR,Unrecogniced VR code: {0}H - treat as UN",
                Integer.toHexString(code));
        return null;//zssure:to solve non-standard VR
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

壹. 正确分析Non-standard V科雷傲:

//VR.java,Line 110
public static VR valueOf(int code) {
        try {
            VR vr = VALUE_OF[indexOf(code)];
            if (vr != null)
                return vr;
        } catch (IndexOutOfBoundsException e) {}
        LOG.warn("Unrecogniced VR code: {0}H - treat as UN",
                Integer.toHexString(code));
        //return UN;
        LOG.warn("zssure:to solve non-standard VR,Unrecogniced VR code: {0}H - treat as UN",
                Integer.toHexString(code));
        return null;//zssure:to solve non-standard VR
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

DICOM协议篇:

该有的以医术设备与数据基本的莫过于交互为对象,介绍装备与PACS(当然也会涉及到RubiconIS、HIS等种类)之间数据的具体传输,例如常见的Q/ENVISION(查询/提取)操作、数据存款和储蓄操作等等。
1. DICOM:基于DCMTK实现C-FIND
SCU
 
2. DICOM法学图像处理:基于DC德州仪器工具包学习和剖析worklist 
3. DICOM医学图像处理:利用fo-dicom发送C-Find查询Worklist 
4. DICOM法学图像处理:storescp.exe与storescu.exe源码剖析,学习C-STORE请求 
5. DICOM历史学图形处理:storescp.exe与storescu.exe源码剖析,学习C-STORE请求(续) 
6. DICOM历史学图像处理:AETitle在C-FIND和C-MOVE请求中的设置难点 
7. DICOM文学图像处理:fo-dicom网络传输之 C-Echo and
C-Store
 
8. DICOM工学图像处理:fo-dicom互联网传输之C-FIND and
C-MOVE
 
9. DICOM工学图像处理:DIMSE音信发送与吸收“内江小异”之DC高通 fo-dicom
mDCM
 
10. DICOM:dcmqrscp.exe与storescu.exe中C-STORE服务的距离 
11. DICOM:fo-dicom之C-STORE再分析‘解决System.ObjectDisposedException异常’ 
12. DICOM:DICOM Print服务中PresentationContext协商之
MetaSOPClass与SOPClass相比较分析
 
13. DICOM:DICOM Print
服务详细介绍
 
14. DICOM:参考dcm4che2扩展fo-dicom(mDCM)中的UserIdentity字段

2. 科学读取Non-standard V奥迪Q7的VL:

//DicomInputStream.java Line 386
 public int readHeader() throws IOException {
        byte[] buf = buffer;
        tagPos = pos; 
        readFully(buf, 0, 8);
        switch(tag = ByteUtils.bytesToTag(buf, 0, bigEndian)) {
        case Tag.Item:
        case Tag.ItemDelimitationItem:
        case Tag.SequenceDelimitationItem:
           vr = null;
           break;
        default:
            if (explicitVR) {
                vr = VR.valueOf(ByteUtils.bytesToVR(buf, 4));
                //zssure:to solve non-standard VR
                //referred:dcmtk/dcitem.cc/readTagAndLength,Line 970
                if(vr == null)
                {
                    length = ByteUtils.bytesToUShort(buf, 6, bigEndian);
                    return tag;                 
                }
                //zssure:end
                if (vr.headerLength() == 8) {
                    length = ByteUtils.bytesToUShort(buf, 6, bigEndian);
                    return tag;
                }
                readFully(buf, 4, 4);
            } else {
                vr = VR.UN;
            }
        }
        length = ByteUtils.bytesToInt(buf, 4, bigEndian);
        return tag;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

2. 不易读取Non-standard V中华V的VL:

//DicomInputStream.java Line 386
 public int readHeader() throws IOException {
        byte[] buf = buffer;
        tagPos = pos; 
        readFully(buf, 0, 8);
        switch(tag = ByteUtils.bytesToTag(buf, 0, bigEndian)) {
        case Tag.Item:
        case Tag.ItemDelimitationItem:
        case Tag.SequenceDelimitationItem:
           vr = null;
           break;
        default:
            if (explicitVR) {
                vr = VR.valueOf(ByteUtils.bytesToVR(buf, 4));
                //zssure:to solve non-standard VR
                //referred:dcmtk/dcitem.cc/readTagAndLength,Line 970
                if(vr == null)
                {
                    length = ByteUtils.bytesToUShort(buf, 6, bigEndian);
                    return tag;                 
                }
                //zssure:end
                if (vr.headerLength() == 8) {
                    length = ByteUtils.bytesToUShort(buf, 6, bigEndian);
                    return tag;
                }
                readFully(buf, 4, 4);
            } else {
                vr = VR.UN;
            }
        }
        length = ByteUtils.bytesToInt(buf, 4, bigEndian);
        return tag;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

DICOM应用篇:

该片段是对DICOM数据篇和DICOM应用篇的实际操作,以DICOM标准为主线,重视介绍种种DICOM开源落成库(包含dcmtk、fo-dicom(mDCM)、dcm4che),以及科学普及的开源新闻种类,诸如Orthanc、ClearCanvas、dcm4chee。
1. DCMediaTek开源库的就学笔记4:利用ini配置文件对dcm印象实行归档 
2. Web版PACS开垦纪要一:关闭动态库中创造的线程 
3. Web版PACS开辟纪要2:消除文件传输数据“丢失”难题 
4. DICOM艺术学图像处理:DC高通在VS二零一一中的配置 
5. DICOM军事学图像处理:开源库mDCM与DC德州仪器的相比较分析(一),JPEG无损压缩DCM图像 
6. DICOM工学图像处理:开源库mDCM与DC高通的比较分析(壹),JPEG无损压缩DCM图像(续) 
7. DICOM农学图像处理:DC德州仪器的wiki资料学习之PACS调节和测试 
8. DICOM经济学图像处理:WEB
PACS初谈
 
9. DICOM文学图像处理:WEB
PACS初谈二,图像的传输
 
10. DICOM管军事学图像处理:WEB
PACS初谈3,PHP扩张骨架
 
11. DICOM文学图像处理:WEB PACS初谈肆,PHP DICOM
Class
 
12. DICOM经济学图像处理:Deconstructed
PACS之Orthanc
 
13. DICOM艺术学图像处理:Deconstructed PACS之Orthanc,Modification &
Anonymization
 
14. DICOM工学图像处理:Orthanc Plugin
SDK达成WADO服务
 
15. DICOM历史学图像处理:深远剖析Orthanc的SQLite,领会WADO & RESTful
API
 
16. DICOM:DC德州仪器工具包分析之dcmqrscp.exe、dcmqridx.exe、dcmqrti.exe 
17. DICOM:剖析Orthanc中的Web Server,
Mongoose
 
18. DICOM:剖析Orthanc中的Web
Server,Mongoose之“连接请求触发的事件系列”(2)
 
19. DICOM:剖析Orthanc中的Web Server,Mongoose之 Flag bit &
Event(三)
 
20. DICOM:开源DICOM服务框架DCM4CHE营造的准备 
21. DICOM:开源DICOM服务框架DCM4CHE
安装
 
22. DICOM:开源DICOM服务框架DCM4CHE
构建
 
23. DICOM:再一次剖析fo-dicom中DicomService的自定义事件绑定 
24. DICOM:Ubuntu1肆条件下安装dcm4chee+oviyam贰.1 
25. DICOM:dcm4chee奇葩逻辑浅析之UID修改 
26. DICOM:C-GET与C-MOVE相比较分析 
27. DICOM:DICOM万能编辑工具之Sante DICOM
艾德itor
 
28. DICOM:dcm四che工具包如何压缩dcm文件钻探(前篇) 
29. DICOM:dcm四che工具包怎样压缩dcm文件研讨(续篇) 
30. DICOM:基于JMeter+dcm四che二测试PACS服务器品质的消除方案(前篇) 
31. DICOM:基于JMeter+dcm四che2测试PACS服务器质量的化解方案(续篇)

测试文件下载:

正文中运用的测试数据已经上传到了自己Github的CSDN仓库中,可机关下载,为了掩护病人隐衷已经进行了匿名化处理。
Download Non-standard VR test dcm
file

测试文件下载:

正文中接纳的测试数据已经上传到了自身Github的CSDN酒店中,可机关下载,为了掩护伤者隐秘已经张开了匿名化处理。
Download Non-standard VR test dcm
file

DICOM翻译篇:

该片段是自家在Github上提倡的DICOM三.0标准汉语版开源书籍系列,由于当下大多数DICOM相关的材质(如上述观念导图中涉嫌的官网、开源论坛)都以英文版,闽南语资料甚少,因而调节发起该类型,以DICOM标准的中文翻译为根基,介绍并推广医疗领域的音讯化本领,关怀医疗改进的腾飞。
1. DICOM:DICOM三.0规范粤语版开源书籍之”本地版本管理方案 
2. DICOM:DICOM三.0正规粤语版开源书籍之“git版本库合并 
3. DICOM:DICOM叁.0规范粤语版开源书籍编辑之”github仓库合并“ 
4. DICOM:DICOM3.0行业内部普通话版开源书籍协同编辑之“Github Pull
Requests”
 
5. DICOM:开源书籍之『DICOM标准中文版』运转铺排

PS: 全部博文的归类也得以参照以前计算的一篇DICOM历史学图像处理:二零1四▪DICOM专栏一览

后续博文介绍:

壹.
由dcm肆che3.x库看Java流操作之”流的正片”

二.
Eclipse自动编写翻译dcm4che叁.x源码

3.
DICOM3大开源库相比较分析之“数据加载”(续)

 

接轨博文介绍:

1.
由dcm4che3.x库看Java流操作之”流的正片”

2.
Eclipse自动编写翻译dcm肆che叁.x源码

三.
DICOM3大开源库比较分析之“数据加载”(续)

备注:

鉴于DICOM标准复杂,体积非常大,因而本博文仅作为DICOM标准学习路径图的初稿,对初学者起到二个轻松的指引功用。后续会日渐翻新完善,敬请期待!

相关文章