如何使用 C# 将普通 jpeg 图像字节转换为 DICOM 本机图像字节

发布于 2024-12-07 21:39:11 字数 163 浏览 2 评论 0原文

目前我正在编写一个用于将 JPEG 转换为 DICOM 图像 的模块。经过分析,我已经完成了标签渲染,现在图像在 DICOM 文件中未正确渲染。

是否有任何算法可以将JPEG转换为DICOM

Currently I'm writing a module for the conversion of JPEG to DICOM Image Conversion. On analysis I've completed the tag rendering, now the image is not properly rendered in the DICOM file.

Is there any algorithm to convert the JPEG to DICOM.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

沉默的熊 2024-12-14 21:39:11

继续Matthieu的回应,这里有一个非常简单的方法,使用优秀的GDCM库和他引用的示例为JPEG流创建DICOM信封(注意我使用了一些辅助类,但非常简单):

       ImageReader r = new ImageReader();
        gdcm.Image image = r.GetImage();
        image.SetNumberOfDimensions(2);
        DataElement pixeldata = DataElementHelper.PixelData;
        string file1 = @"D:\testfil.jpeg";

        System.IO.FileStream infile =
            new System.IO.FileStream(file1, System.IO.FileMode.Open, System.IO.FileAccess.Read);
        //uint fsize = gdcm.PosixEmulation.FileSize(file1);

        //byte[] jstream = new byte[fsize];
        //infile.Read(jstream, 0, jstream.Length);

        byte[] jstream = System.IO.File.ReadAllBytes(file1);
        uint fsize = (uint) jstream.Length;

        SmartPtrFrag sq = SequenceOfFragments.New();
        Fragment frag = new Fragment();
        frag.SetByteValue(jstream, new gdcm.VL((uint)jstream.Length));
        sq.AddFragment(frag);
        pixeldata.SetValue(sq.__ref__());

        // insert:
        image.SetDataElement(pixeldata);


        PhotometricInterpretation pi = new PhotometricInterpretation(PhotometricInterpretation.PIType.MONOCHROME2);
        image.SetPhotometricInterpretation(pi);

        // FIXME hardcoded:
        PixelFormat pixeltype = new PixelFormat(PixelFormat.ScalarType.UINT8);
        image.SetPixelFormat(pixeltype);

        TransferSyntax ts = new TransferSyntax(TransferSyntax.TSType.JPEGBaselineProcess1);
        image.SetTransferSyntax(ts);

        image.SetDimension(0, (uint)1700);
        image.SetDimension(1, (uint)2200);

        ImageWriter writer = new ImageWriter();
        gdcm.File file = writer.GetFile();


        var ds = file.GetDataSet();
        DataElement patientID = DataElementHelper.PatientID;
        DataElement patientName = DataElementHelper.PatientName;
        DataElement accessionNumber = DataElementHelper.AccessionNumber;
        DataElement studyDate = DataElementHelper.StudyDate;
        DataElement studyTime = DataElementHelper.StudyTime;
        DataElement studyInstanceUID = DataElementHelper.StudyInstanceUID;
        DataElement seriesInstanceUID = DataElementHelper.SeriesInstanceUID;
        DataElement mediaStorage = DataElementHelper.SOPClassUID;

        string studyUID = new gdcm.UIDGenerator().Generate();
        string seriesUID = new gdcm.UIDGenerator().Generate();

        //pixelData.SetArray(b, (uint)b.Length);
        DataElementHelper.SetDataElement(ref patientName, "TEST^MARCUS");
        DataElementHelper.SetDataElement(ref patientID, "0000000801");
        DataElementHelper.SetDataElement(ref accessionNumber, "0000000801-12345");
        DataElementHelper.SetDataElement(ref studyDate, DateTime.Now.ToString("yyyyMMdd"));
        DataElementHelper.SetDataElement(ref studyTime, DateTime.Now.ToString("HHmmss"));
        DataElementHelper.SetDataElement(ref studyInstanceUID, studyUID);
        DataElementHelper.SetDataElement(ref seriesInstanceUID, seriesUID);
        DataElementHelper.SetDataElement(ref mediaStorage, "1.2.840.10008.5.1.4.1.1.7");
        ds.Insert(patientID);
        ds.Insert(patientName);
        ds.Insert(accessionNumber);
        ds.Insert(studyDate);
        ds.Insert(studyTime);
        ds.Insert(studyInstanceUID);
        ds.Insert(seriesInstanceUID);
        ds.Insert(mediaStorage);

        writer.SetImage(image);
        writer.SetFileName("gdcm_test.dcm");
        bool ret = writer.Write();

Continuing from Matthieu's response, here is a very simple way of creating a DICOM envelope for a JPEG stream using the excellent GDCM library and his referenced example (note I have used some helper classes, but is quite simple):

       ImageReader r = new ImageReader();
        gdcm.Image image = r.GetImage();
        image.SetNumberOfDimensions(2);
        DataElement pixeldata = DataElementHelper.PixelData;
        string file1 = @"D:\testfil.jpeg";

        System.IO.FileStream infile =
            new System.IO.FileStream(file1, System.IO.FileMode.Open, System.IO.FileAccess.Read);
        //uint fsize = gdcm.PosixEmulation.FileSize(file1);

        //byte[] jstream = new byte[fsize];
        //infile.Read(jstream, 0, jstream.Length);

        byte[] jstream = System.IO.File.ReadAllBytes(file1);
        uint fsize = (uint) jstream.Length;

        SmartPtrFrag sq = SequenceOfFragments.New();
        Fragment frag = new Fragment();
        frag.SetByteValue(jstream, new gdcm.VL((uint)jstream.Length));
        sq.AddFragment(frag);
        pixeldata.SetValue(sq.__ref__());

        // insert:
        image.SetDataElement(pixeldata);


        PhotometricInterpretation pi = new PhotometricInterpretation(PhotometricInterpretation.PIType.MONOCHROME2);
        image.SetPhotometricInterpretation(pi);

        // FIXME hardcoded:
        PixelFormat pixeltype = new PixelFormat(PixelFormat.ScalarType.UINT8);
        image.SetPixelFormat(pixeltype);

        TransferSyntax ts = new TransferSyntax(TransferSyntax.TSType.JPEGBaselineProcess1);
        image.SetTransferSyntax(ts);

        image.SetDimension(0, (uint)1700);
        image.SetDimension(1, (uint)2200);

        ImageWriter writer = new ImageWriter();
        gdcm.File file = writer.GetFile();


        var ds = file.GetDataSet();
        DataElement patientID = DataElementHelper.PatientID;
        DataElement patientName = DataElementHelper.PatientName;
        DataElement accessionNumber = DataElementHelper.AccessionNumber;
        DataElement studyDate = DataElementHelper.StudyDate;
        DataElement studyTime = DataElementHelper.StudyTime;
        DataElement studyInstanceUID = DataElementHelper.StudyInstanceUID;
        DataElement seriesInstanceUID = DataElementHelper.SeriesInstanceUID;
        DataElement mediaStorage = DataElementHelper.SOPClassUID;

        string studyUID = new gdcm.UIDGenerator().Generate();
        string seriesUID = new gdcm.UIDGenerator().Generate();

        //pixelData.SetArray(b, (uint)b.Length);
        DataElementHelper.SetDataElement(ref patientName, "TEST^MARCUS");
        DataElementHelper.SetDataElement(ref patientID, "0000000801");
        DataElementHelper.SetDataElement(ref accessionNumber, "0000000801-12345");
        DataElementHelper.SetDataElement(ref studyDate, DateTime.Now.ToString("yyyyMMdd"));
        DataElementHelper.SetDataElement(ref studyTime, DateTime.Now.ToString("HHmmss"));
        DataElementHelper.SetDataElement(ref studyInstanceUID, studyUID);
        DataElementHelper.SetDataElement(ref seriesInstanceUID, seriesUID);
        DataElementHelper.SetDataElement(ref mediaStorage, "1.2.840.10008.5.1.4.1.1.7");
        ds.Insert(patientID);
        ds.Insert(patientName);
        ds.Insert(accessionNumber);
        ds.Insert(studyDate);
        ds.Insert(studyTime);
        ds.Insert(studyInstanceUID);
        ds.Insert(seriesInstanceUID);
        ds.Insert(mediaStorage);

        writer.SetImage(image);
        writer.SetFileName("gdcm_test.dcm");
        bool ret = writer.Write();
原来是傀儡 2024-12-14 21:39:11

请查看 mdcm C# DICOM 库,最初由 Colby Dillion 编写。他开发了通往 IJG/LibJPEGOpenJPEG 代码库,因此 mdcm 提供 8/12/16 位有损和无损 JPEG 支持以及 JPEG-2000 支持。

Colby 的原始库具有 WinForms 依赖项。我在此处创建了一个针对 Silverlight 和 WPF 的 mdcm 分支。该库的 WPF 版本可以充分利用 Colby 最初实现的相同 JPEG(-2000) 编解码器。
另一方面,Silverlight 版本目前无法从这些编解码器中受益。我已尝试应用 FJCoreLibJpeg.Net 库,用于在 Silverlight 中支持有损 JPEG,但这些库目前仅支持 8 位图像。

问候,
安德斯@Cureos

please have a look at the mdcm C# DICOM library, originally written by Colby Dillion. He has developed managed C++ "bridges" to the IJG/LibJPEG and OpenJPEG code bases, so mdcm provides both 8/12/16-bit lossy and lossless JPEG support as well as JPEG-2000 support.

Colby's original library has WinForms dependencies. I have created a Silverlight and WPF targeted fork of mdcm here. The WPF version of the library can fully utilize the same JPEG(-2000) codecs that Colby originally implemented.
The Silverlight version on the other hand currently cannot benefit from these codecs. I have made some attempts to apply the FJCore and LibJpeg.Net libraries for lossy JPEG support in Silverlight, but these libraries only support 8-bit images at the moment.

Regards,
Anders @ Cureos

南烟 2024-12-14 21:39:11

.NET 本身没有支持 DICOM 的功能。您将需要使用图书馆。我不知道有什么免费的,但我使用过 LeadTools,它可以做到这一点(需要付费)。但我只会给它 4/10,并且我会重新开始你寻找其他选择。

There is no functionality in .NET itself for DICOM support. You will need to use a library. I do not know of any free ones but I have used LeadTools and it will do it (for a price). But I would only give it a 4/10, and I would recommenced you look for other options too.

脸赞 2024-12-14 21:39:11

您不需要将 JPEG“转换”为 DICOM。 DICOM 只是 JPEG 流的“信封”。以下是我在 GDCM 中封装(=放入 DICOM 信封)现有 MPEG2 文件的方法:

http://gdcm.sourceforge.net/html/MpegVideoInfo_8cs-example.html

只需针对输入 JPEG 文件调整该代码即可。例如,看看:

http://gdcm.sourceforge.net/html/DecompressJPEGFile_8cs- example.html

不需要解压/重新压缩,那样会浪费资源。

You do not need to 'convert' JPEG to DICOM. DICOM is simply an 'envelope' for your JPEG stream. Here is what I did in GDCM to encapsulate (= put into a DICOM envelope) an existing MPEG2 file:

http://gdcm.sourceforge.net/html/MpegVideoInfo_8cs-example.html

Simply adapt that code for an input JPEG file. For instance have a look at:

http://gdcm.sourceforge.net/html/DecompressJPEGFile_8cs-example.html

No need to decompress/recompress, that would be a waste of resource.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文