验证DICOM文件

5
我需要从文件夹中挑选出所有有效的DICOM文件。我可以递归地从具有*.DCM扩展名的文件夹中选择所有文件。但是,任何带有*.DCM扩展名的文件都会被选择,而这样的文件并不是有效的DICOM文件。
最好的方法是什么?
我考虑读取文件的几个字节并进行验证。
或者
其他方法或我们拥有的任何其他EXE进行验证。
谢谢, Harsha
编辑:问题的解决方案: 我最终使用了dcmftest.exe进行验证。希望我走在正确的轨道上。 -Harsha
6个回答

11
您想识别DICOM文件,而不是验证。两者之间存在很大的区别。验证至少意味着其SOP类所需的所有标签都存在。
识别很容易,因为DICOM文件必须在偏移量0x80处包含文本“ DICM”,因此标签从文件的偏移量0x84开始。
请注意,有时仅存储序列化数据集(从文件偏移量0开始的标签组8),这些更难识别,但不是标准。
编辑:以RAR归档为例。它很容易被识别,因为它以 “Rar!”开头。但是,要确定它是有效的RAR归档,您必须解压缩所有文件并检查它们的CRC,而这只能由RAR本身完成(并且很慢)。

识别并不容易!有些DICOM文件没有前导和魔数。 - phuclv

7

我知道这个问题已经有答案了,但是我有类似的需求,所以我编写了一些扩展方法来完成这个任务。它可以处理文件、文件流、内存流和通用流。只读取需要验证文件类型的特定4个字节。非常高效,我能够在几秒钟内浏览数千个文件。

C#

public static class Dicom
{
    public static bool IsDicomFile(this Stream s)
    {
        //Create an empty 4 byte array
        byte[] dba = new byte[4];

        //Seek to 0x80
        s.Seek(128, SeekOrigin.Begin);

        //Read the following 4 dba
        s.Read(dba, 0, 4);

        //Compare to 'DICM'
        return dba.SequenceEqual(new byte[4] {68, 73, 67, 77});
    }

    public static bool IsDicomFile(this MemoryStream ms)
    {
        return ((Stream)ms).IsDicomFile();
    }

    public static bool IsDicomFile(this FileStream fs)
    {
        return ((Stream)fs).IsDicomFile();
    }

    public static bool IsDicomFile(this FileInfo fi)
    {
        return fi.OpenRead().IsDicomFile();
    }
}

VB.NET

<Extension()> _
Public Function IsDicomFile(ByVal s As Stream) As Boolean
    'Create an empty 4 byte array
    Dim dba() As Byte = New Byte(3) {}

    'Seek to 0x80
    s.Seek(128, SeekOrigin.Begin)

    'Read the subsequent 4 bytes
    s.Read(dba, 0, 4)

    'Compare to 'DICM'
    Return dba.SequenceEqual(New Byte(3) {68, 73, 67, 77})
End Function

<Extension()> _
Public Function IsDicomFile(ByVal ms As MemoryStream) As Boolean
    Return DirectCast(ms, Stream).IsDicomFile
End Function

<Extension()> _
Public Function IsDicomFile(ByVal fs As FileStream) As Boolean
    Return DirectCast(fs, Stream).IsDicomFile
End Function

<Extension()> _
Public Function IsDicomFile(ByVal fi As FileInfo) As Boolean
    Return fi.OpenRead().IsDicomFile
End Function

5

请注意,扩展名为.dcm的文件并不是真正合法的DICOM格式,尽管出于遗留原因,编写程序以接受这些文件仍然是一个好主意(但您不应该在应用程序导出的DICOM文件上放置3个字符的文件名扩展名)。根据DICOM标准有关媒体交换的部分,“不得使用ISO 9660文件名扩展名”。此外,除了标准的第10和12部分中描述的特殊DICOMDIR文件之外,不应从文件名或目录结构中推断任何语义。

ruslik的答案给出了识别DICOM文件的正确方法。如果文件前导中指定位置有DICM,则它是DICOM文件。否则,它不是。


4

考虑到不同IOD中存在不同的强制和可选标签,验证DICOM文件并不是一项容易的任务。我认为最好使用现有的解决方案来完成这项工作。您可以查看DCMTK中的DCMCHECK(http://dicom.offis.de/dcmcheck.php.en)来实现。


1
DCMCHECK模块不是免费提供的,必须单独获得许可证。 - Andrei Krasutski
这个链接页面给我返回了404错误。 - lnogueir

2
针对Java用户 dcm4che-tool-dcmvalidate 用法: dcmvalidate --iod [..][..] 这是一个实用工具,可以根据指定的信息对象定义(Information Object Definition)验证DICOM对象。 - 选项: -h,--help 显示此帮助并退出 --iod xml文件的路径,其中包含信息对象定义 -V,--version 输出版本信息并退出 示例: $ dcmvalidate --iod etc/dcmvalidate/dicomdir-iod.xml DICOMDIR
根据etc/dcmvalidate/dicomdir.xml中指定的IOD验证DICOMDIR。 点击此处获取更多参考信息

2
注意:检查“DICM”的前导内容仅检查文件是否为DICOM v3文件。早期版本的DICOM没有前导内容。可以查看所有必需的DICOM标签等,并可导入DICOM节点的100%有效的DICOM文件没有前导内容。
我正在与OFFIS联系,以了解经许可的DCMCHECK版本是否也具有此限制,但尚未收到他们的回复。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接