DICOM文件解析

单帧dcm文件

public static void ConvertDicomToBmp(string dicomFilePath, string bmpOutputPath)
{
    DicomFile dcmFile = DicomFile.Open(dicomFilePath);
    var name = dcmFile.Dataset.GetString(DicomTag.PatientName);
    ushort bitStored = dcmFile.Dataset.GetSingleValue<ushort>(DicomTag.BitsStored);
    ushort bitAllocated = dcmFile.Dataset.GetSingleValue<ushort>(DicomTag.BitsAllocated);
    ushort samplesPerPixel = dcmFile.Dataset.GetSingleValue<ushort>(DicomTag.SamplesPerPixel);
    ushort width = dcmFile.Dataset.GetSingleValue<ushort>(DicomTag.Columns);
    ushort height = dcmFile.Dataset.GetSingleValue<ushort>(DicomTag.Rows);

    int windowCenter;  //窗口中心
    if (!dcmFile.Dataset.TryGetSingleValue(DicomTag.WindowCenter, out windowCenter))
    {
        windowCenter = 0; // 默认值
    }

    int windowWidth;    //窗口宽度
    if (!dcmFile.Dataset.TryGetSingleValue(DicomTag.WindowWidth, out windowWidth))
    {
        windowWidth = 0; // 默认值
    }

    string modality;        //模态信息
    if (!dcmFile.Dataset.TryGetString(DicomTag.Modality, out modality))
    {
        modality = "Unknown"; // 默认值或处理方式
    }

    Bitmap gdiImg = new Bitmap(width, height);

    if (bitStored > 8)          //处理高位深度图像,数据用两个字节ushort表示
    {
        ushort[] pixelData = dcmFile.Dataset.GetValues<ushort>(DicomTag.PixelData);
        ushort maxVal = pixelData.Max();
        ushort minVal = pixelData.Min();
        double compressFactor = byte.MaxValue / (double)(maxVal - minVal) - 0.00000000001;

        if (samplesPerPixel == 1) // Gray
        {
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    double gray = pixelData[i * width + j];
                    int grayGDI = (int)(gray * compressFactor);
                    grayGDI = grayGDI < 0 ? 0 : (grayGDI > 255 ? 255 : grayGDI);

                    Color color = Color.FromArgb(grayGDI, grayGDI, grayGDI);
                    gdiImg.SetPixel(j, i, color);
                }
            }
            gdiImg.Save(bmpOutputPath, ImageFormat.Bmp);
        }
        else if (samplesPerPixel == 3) // RGB
        {
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    int index = (i * width + j) * 3;
                    ushort r = pixelData[index];
                    ushort g = pixelData[index + 1];
                    ushort b = pixelData[index + 2];

                    // 压缩 RGB 值到 0-255 范围
                    int rGDI = (int)(r * compressFactor);
                    int gGDI = (int)(g * compressFactor);
                    int bGDI = (int)(b * compressFactor);

                    rGDI = rGDI < 0 ? 0 : (rGDI > 255 ? 255 : rGDI);
                    gGDI = gGDI < 0 ? 0 : (gGDI > 255 ? 255 : gGDI);
                    bGDI = bGDI < 0 ? 0 : (bGDI > 255 ? 255 : bGDI);

                    Color color = Color.FromArgb(rGDI, gGDI, bGDI);
                    gdiImg.SetPixel(j, i, color);
                }
            }
            gdiImg.Save(bmpOutputPath, ImageFormat.Bmp);
        }
    }
    else                         //处理低位深度图像,数据用一个字节byte表示
    {
        byte[] pixelData = dcmFile.Dataset.GetValues<byte>(DicomTag.PixelData);

        if (samplesPerPixel == 1) // Gray
        {
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    byte gray = pixelData[i * width + j];
                    Color color = Color.FromArgb(gray, gray, gray);
                    gdiImg.SetPixel(j, i, color);
                }
            }
            gdiImg.Save(bmpOutputPath, ImageFormat.Bmp);
        }
        else if (samplesPerPixel == 3) // RGB
        {
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    int index = (i * width + j) * 3;
                    byte r = pixelData[index];
                    byte g = pixelData[index + 1];
                    byte b = pixelData[index + 2];
                    Color color = Color.FromArgb(r, g, b);
                    gdiImg.SetPixel(j, i, color);
                }
            }
            gdiImg.Save(bmpOutputPath, ImageFormat.Bmp);
        }
    }

    Console.WriteLine("BMP 文件已保存到 " + bmpOutputPath);
}  

  多帧dcm文件转化

public static void ConvertDicomToBmps(string dicomFilePath, string bmpOutputFolder)
{
    DicomFile dcmFile = DicomFile.Open(dicomFilePath);
    var dataset = dcmFile.Dataset;

    string name = dataset.GetString(DicomTag.PatientName);
    ushort bitStored = dataset.GetSingleValue<ushort>(DicomTag.BitsStored);
    ushort samplesPerPixel = dataset.GetSingleValue<ushort>(DicomTag.SamplesPerPixel);
    ushort width = dataset.GetSingleValue<ushort>(DicomTag.Columns);
    ushort height = dataset.GetSingleValue<ushort>(DicomTag.Rows);

    DicomPixelData pixelData = DicomPixelData.Create(dataset);

    for (int frame = 0; frame < pixelData.NumberOfFrames; frame++)
    {
        Bitmap gdiImg = new Bitmap(width, height);
        IByteBuffer frameDataBuffer = pixelData.GetFrame(frame);

        if (bitStored > 8)
        {
            ushort[] frameData = new ushort[width * height];
            Buffer.BlockCopy(frameDataBuffer.Data, 0, frameData, 0, frameDataBuffer.Data.Length);

            ushort maxVal = frameData.Max();
            ushort minVal = frameData.Min();
            double compressFactor = byte.MaxValue / (double)(maxVal - minVal) - 0.00000000001;

            if (samplesPerPixel == 1) // Gray
            {
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        double gray = frameData[i * width + j];
                        int grayGDI = (int)(gray * compressFactor);
                        grayGDI = grayGDI < 0 ? 0 : (grayGDI > 255 ? 255 : grayGDI);

                        Color color = Color.FromArgb(grayGDI, grayGDI, grayGDI);
                        gdiImg.SetPixel(j, i, color);
                    }
                }
            }
            else if (samplesPerPixel == 3) // RGB
            {
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        int index = (i * width + j) * 3;
                        ushort r = frameData[index];
                        ushort g = frameData[index + 1];
                        ushort b = frameData[index + 2];

                        int rGDI = (int)(r * compressFactor);
                        int gGDI = (int)(g * compressFactor);
                        int bGDI = (int)(b * compressFactor);

                        rGDI = rGDI < 0 ? 0 : (rGDI > 255 ? 255 : rGDI);
                        gGDI = gGDI < 0 ? 0 : (gGDI > 255 ? 255 : gGDI);
                        bGDI = bGDI < 0 ? 0 : (bGDI > 255 ? 255 : bGDI);

                        Color color = Color.FromArgb(rGDI, gGDI, bGDI);
                        gdiImg.SetPixel(j, i, color);
                    }
                }
            }
        }
        else
        {
            byte[] frameData = frameDataBuffer.Data;

            if (samplesPerPixel == 1) // Gray
            {
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        byte gray = frameData[i * width + j];
                        Color color = Color.FromArgb(gray, gray, gray);
                        gdiImg.SetPixel(j, i, color);
                    }
                }
            }
            else if (samplesPerPixel == 3) // RGB
            {
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        int index = (i * width + j) * 3;
                        byte r = frameData[index];
                        byte g = frameData[index + 1];
                        byte b = frameData[index + 2];
                        Color color = Color.FromArgb(r, g, b);
                        gdiImg.SetPixel(j, i, color);
                    }
                }
            }
        }

        string bmpOutputPath = Path.Combine(bmpOutputFolder, $"{frame + 1}.bmp");
        gdiImg.Save(bmpOutputPath, ImageFormat.Bmp);
        gdiImg.Dispose();
    }

    Console.WriteLine("所有帧图像已保存到 " + bmpOutputFolder);
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值