如何从 DICOM 文件中提取信息?

Posted

技术标签:

【中文标题】如何从 DICOM 文件中提取信息?【英文标题】:How i can extract information from DICOM file ? 【发布时间】:2015-05-24 06:24:36 【问题描述】:

我想编写一个脚本来使用c或c ++提取DICOM文件的头信息,我不想使用像dicomsdl这样的外部库...... 当我用 Bloc-notes 打开文件时,我看到特殊字符和字符串作为患者姓名.. 如果有人可以帮助我阅读此文件。

【问题讨论】:

"当我使用 Bloc-notes 打开文件时,我看到特殊字符和字符串作为患者姓名" 这可能是二进制格式,您必须解析该信息字节明智的。 您需要从 NEMA 获取标准,并由我们来指导您阅读文件。给你写的东西,你可能需要以二进制模式打开文件并以这种方式读取。 @thurizas 虽然它包含链可见字符我用二进制打开它? 【参考方案1】:

是的,我会以二进制文件打开文件,即使它可能包含字符序列。没有太深入,请考虑编写以下内容 输出到文件的记录(我将记录显示为 C 结构):

    struct rec_tag
    
         int    id;
         char   name[50];
    ;

现在,假设我使用该结构来创建一个文件,如下代码所示:

file1.c:

/* compile as: gcc -ansi -pedantic -Wall file.c -o file_test */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


struct rec_tag

    int   id;
    char  name[50];
;

int main(int argc, char** argv)

    FILE*          fp = NULL;
    struct rec_tag rec1;
    struct rec_tag rec2;

    rec1.id = 20;
    strcpy(rec1.name, "thurizas");

    rec2.id = 345689;
    strcpy(rec2.name, "Marouane");

    if(NULL != (fp = fopen("./short.dat", "ab")))
    
         fwrite(&rec1, sizeof(struct rec_tag), 1, fp);
         fwrite(&rec2, sizeof(struct rec_tag), 1, fp);

         fclose(fp);
    
    return 0;


现在,假设我在 emacs 中打开这个文件,其中有很多特殊符号(例如 ^T 和 ^@),字符串中穿插着字符串。在十六进制编辑器(比如 okteta)中打开文件可能是有益的,我们看到:

    14 00 00 00 74 68 75 72 69 7A 61 73 00 00 00 00 01 00 00 00 00 00
    00 00 ED 06 40 00 00 00 00 00 C2 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 A0 06 40 00 00 00 00 00 59 46 05 00 4D 61 72 6F 75 61 
    6E 65 00 7F 00 00 2E 4E 3D F6 00 00 00 00 67 03 40 00 00 00 00 00 
    FF FF FF FF 00 00 00 00 C0 B5 B3 C5 FF 7F 00 00 38 F1 CA BE 31 7F 
    00 00

现在,十六进制数字序列74 68 75 72 69 7A 61 73 是“thurizas”的 ASCII 码(大多数编辑器都会显示)。现在文件中的前四个字节是 id 号。现在这是另一个(潜在的)问题,我在具有 x86_64 进程的计算机上创建了文件,因此整数以 little-endian 形式存储在内存中,因此需要读取序列 14 00 00 00 ......向后(因为没有更好的术语)00 00 00 14,它是 20 的 32 位十六进制表示。

另外,请注意,由于我没有特别注意处理字符数组的方式,因此文件中有多余的垃圾字节。

现在,如果不知道文件的格式(ie 数据是如何写入文件的),我很难弄清楚如何读入它。但是,因为我们知道格式我们可以写一个简单的程序来读取它:

file1.c:

/* compile as: gcc -ansi -pedantic -Wall file1.c -o read_test */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct rec_tag

    int   id;
    char  name[50];
;

int main(int argc, char** argv)

     FILE*          fp = NULL;
     struct rec_tag rec1;
     struct rec_tag rec2;

     if(NULL != (fp = fopen("./short.dat", "rb")))
     
          fread(&rec1, sizeof(struct rec_tag), 1, fp);
          fread(&rec2, sizeof(struct rec_tag), 1, fp);

          printf("id: %d, name: %s\n", rec1.id, rec1.name);
          printf("id: %d, name: %s\n", rec2.id, rec2.name);

          fclose(fp);
     

     return 0;
 

当运行时,产生这个结果:

    [******@broadsword junk]$ ./read_test
    id: 20, name: thurizas
    id: 345689, name: Marouane

希望这有助于如何解释文件并显示一种读取文件的方式。所以在你的情况下,我会执行以下步骤

    获取并阅读 DICOM 文件的正式规范。 尝试“手动”读取文件。在十六进制编辑器中打开文件,并使用规范查看是否可以逐步浏览文件并确定数据的存储方式。 编写程序来读取数据。

最后,免责声明:

    所有代码均使用 gcc 版本 4.8.2 编译并在 Centos 7 系统上运行。 我知道 fopen 和 fread 的 b 标志在所有 POSIX 兼容系统(包括 Linux)上都被忽略了,我把它放在那里以防代码在非 POSIX 系统上运行,并且要明确指出我在做二进制 I/O 将错误检查和处理保持在最低限度,以防止此帖子成为文字墙(它确实如此)。

希望这会有所帮助, T.

【讨论】:

我觉得你的回答对我很有帮助,非常感谢【参考方案2】:

DICOM 格式相对复杂。如果您不熟悉它,我建议您使用第三方库打开图像并提取标题。

考虑使用gdcm。它已经有一个示例(gdcmdump),可以打开文件并将标题转换为文本以供显示。

【讨论】:

以上是关于如何从 DICOM 文件中提取信息?的主要内容,如果未能解决你的问题,请参考以下文章

python 读取dicom tag 结果为空值

Dicom文件基本操作

ps怎么打开 DICOM 文件,ps如何制作 DICOM 文件动画

DICOM-RT:放疗系统的坐标系统DICOM-RT Coordinate System

python医学影像2Ddicom文件转成3Dnii文件(保留原始dicom信息)

如何从 XCUITest(来自 Xcode 11)中的 xcresult 文件中提取详细信息?