如何从原始心电图数据写入 DICOM 文件

How to write a DICOM file from raw ecg data

我有 csv 格式的原始心电图电压样本,例如:

time    voltage (mV)
0.000   9.169110459
0.001   9.144672532
0.002   9.144672532
0.003   9.169110459
0.004   9.169110459
0.005   9.169110459
0.006   9.169110459
0.007   9.144672532
0.008   9.217986315
0.009   9.169110459
0.01    9.169110459
0.011   9.169110459
0.012   9.169110459
0.013   9.144672532
0.014   9.144672532
0.015   9.169110459
0.016   9.169110459
0.017   9.169110459
0.018   9.169110459
0.019   9.169110459
0.02    9.169110459
0.021   9.169110459
0.022   9.144672532
0.023   9.169110459

并想将其转换为 DICOM 文件,以便我可以在 ecg 查看器中查看它,例如 ECG toolkit for c#:https://sourceforge.net/projects/ecgtoolkit-cs/

我将如何进行此转换?我已经进行了一些谷歌搜索,但还没有找到能够从原始数据写入 dicom 文件的工具。

编辑:

我最终选择了 SCP 文件,因为这样更容易。我最终使用上面的库创建了一个 scp 文件。代码如下:

using System;
using System.Linq;
using ECGConversion;
using ECGConversion.ECGDemographics;
using ECGConversion.ECGSignals;

namespace SCPWriter
{
    public static class CreateScpEcg
    {
        public static void CreateScpEcgFile(double[] voltages, int sampleRate, string directory, string patientId)
        {
            var rhythm = voltages;

            var filePath = directory + patientId;

            // get an empty ECG format file
            IECGFormat format = ECGConverter.Instance.getFormat("SCP-ECG");
            if (format != null)
            {
                // five required actions for the demographic info.
                format.Demographics.Init();
                format.Demographics.PatientID = patientId;
                format.Demographics.LastName = "";
                format.Demographics.TimeAcquisition = DateTime.Now;
                // make an AcquiringDeviceID object
                AcquiringDeviceID acqID = new AcquiringDeviceID(true);

                // can also specify your own acquiring device info
                Communication.IO.Tools.BytesTool.writeString("MYDEVI", acqID.ModelDescription, 0, acqID.ModelDescription.Length);
                // set the Acquiring Device ID (required)
                format.Demographics.AcqMachineID = acqID;
                // declare the signal part.
                var leadType = new LeadType[] { LeadType.I };
                var rhythmAVM = 1;
                var rhythmSPS = sampleRate;
                Signals sigs = new Signals((byte)leadType.Length);
                sigs.RhythmAVM = rhythmAVM;
                sigs.RhythmSamplesPerSecond = rhythmSPS;

                for (int i = 0; i < sigs.NrLeads; i++)
                {
                    // very important to assign signal.

                    sigs[i] = new Signal();
                    sigs[i].Type = leadType[i];
                    sigs[i].Rhythm = rhythm.Select(Convert.ToInt16).ToArray();
                    sigs[i].RhythmStart = 0;
                    sigs[i].RhythmEnd = rhythm.Length - 1;
                }
                // store signal to the format.
                if (format.Signals.setSignals(sigs) != 0)
                {
                    Console.Error.WriteLine("setSignals failed!");
                    return;
                }
                // write the file
                var outputFile = filePath + ".scp";


                ECGWriter.Write(format, outputFile, true);
                if (ECGWriter.getLastError() != 0)
                {
                    Console.Error.WriteLine("Writing failed: {0}!", ECGWriter.getLastErrorMessage());
                    return;
                }
            }
        }


    }
}

注意:我只对 "lead I" 感兴趣,但您可以在此行中添加更多线索: var leadType = new LeadType[] { LeadType.I }

注意:这不是我的代码,这是来自上面 sourceforge link 中的讨论之一。

我的建议:

  1. 选择 DICOM 工具包 自己实现DICOM数据的二进制编码没有任何意义
  2. 看看 DICOM Information Object Definition for ECG Waveform 上面的link定义了12-Lead-WaveformObject。如果您的数据不是 12 导联,请选择 this。我提供的 links 指向模块表,通过遵循 links,您可以看到这种类型的 object.
  3. 强制/允许的属性
  4. 您将不可避免地需要了解有关 DICOM 术语的一些基础知识以及在标准中的何处可以找到信息。我强烈推荐 this 文档作为起点。对于此任务,请确保了解信息 Object 定义 (IOD)、模块、属性类型(类型 1、2、3)和值表示 (VR)

那么它就非常简单了。浏览您选择的 IOD(我提到的两个之一)的强制属性,并使用您选择的工具包填充它们。然后使用工具包将文件写入磁盘就大功告成了。确保将数据写入带有 meta-header 的 DICOM 文件。一个好的工具包在将数据集写入磁盘时提供了该选项。

请注意,简单地将 DICOM 文件写入磁盘并不是 "official DICOM interface"。要在不同的 DICOM 应用程序之间交换数据,您要么必须使用网络协议(在您的情况下为存储服务 Class),要么创建符合 DICOM 标准的媒体(这对使用的媒体、文件格式、文件名施加了一些限制,并且需要包括列出媒体内容的 DICOM 目录文件)。

由于您正在寻求工具,因此您可能需要查看 DCMTK。有不同的方法来完成任务。 dcmdump 或 dcmodify 将是需要仔细研究的工具。但是,这样做很麻烦,您可能必须将 ECG-data 转换为 dcmtk 可用于填充波形序列的格式。我不是建议你那样做,但这可能是一种避免编写大量代码的方法。