我想用c或c++写一个脚本来提取DICOM文件的头信息,我不想使用像dicomsdl这样的外部库... 当我用 Bloc-notes 打开文件时,我看到特殊字符和字符串作为患者姓名 .. 如果有人可以帮助我阅读此文件。
最佳答案
是的,我会以二进制形式打开文件,即使它可能包含字符序列。没有太深入,请考虑编写以下内容 输出到文件的记录(我将记录显示为 C 结构):
struct rec_tag
{
int id;
char name[50];
};
现在,假设我使用该结构创建一个文件,如以下代码所示:
文件1.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 进程的计算机上创建了文件,因此整数以小端形式存储在内存中,因此序列 14 00 00 00
需要被读取...向后(因为缺少更好的术语)作为 00 00 00 14
这是 20 的 32 位十六进制表示。
另外,请注意,由于我在处理字符数组的方式上没有特别小心,所以文件中存在多余的垃圾字节。
现在,如果不知道文件的格式(即数据是如何写入文件的),我将很难弄清楚如何读入它。但是,因为我们知道格式我们可以编写一个简单的程序来读取它:
文件1.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 - 将错误检查和处理保持在最低限度,以防止此帖子成为文字墙(确实如此)。
希望对您有所帮助,
关于c++ - 我如何从 DICOM 文件中提取信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29173386/