Экспорт JPG из файла Dicom с помощью mDCM - PullRequest
0 голосов
/ 29 марта 2010

Я использую mDCM с C # для просмотра тэгов dicom, но я пытаюсь преобразовать данные пикселей в растровое изображение и в конечном итоге в файл JPG. Я прочитал все посты в mDCM Google Group по теме, и все примеры кода либо не работают, либо отсутствуют важные строки кода. Изображение, с которым я работаю, является 16-битным монохромным1 (это упомянутый формат, но на самом деле это 16-битная шкала серого). Я пытался использовать LockBits, SetPixel и небезопасный код для преобразования данных пикселей в растровое изображение, но все попытки не удаются. У кого-нибудь есть какой-нибудь код, который мог бы заставить это работать.

Вот моя последняя попытка с использованием SetPixel:

DcmElement pixelData = this.currentFileFormat.Dataset.GetElement(new DcmTag(DcmConstTags.PixelData));
ushort[] pixels = this.currentPixelData.GetFrameDataU16(0);
this.currentImage = new Bitmap(this.currentPixelData.ImageWidth, this.currentPixelData.ImageHeight, PixelFormat.Format16bppRgb555);
int resample = (int)Math.Pow(2, (this.currentPixelData.BitsStored - 8));

int pxCounter = 0;
int min = ushort.MaxValue;
int max = 0;

for (int c = 0; c < this.currentPixelData.ImageHeight; c++)
{
    for (int r = 0; r < this.currentPixelData.ImageWidth; r++)
    {
        ushort pxColor = pixels[pxCounter];
        int temp = 255 - (pxColor / resample);
        if (temp < min) min = temp;
        if (temp > max) max = temp;
        this.currentImage.SetPixel(r, c, Color.FromArgb(temp, temp, temp));
        pxCounter++;
    }
}

UPDATE: Я стал ближе, используя LockBits и Marshal.Copy, но изображение получается в радуге цветов вместо оттенков серого. Поэтому я предполагаю, что мне нужен способ преобразования данных в градациях серого в формат RBG:

byte[] pixels = this.currentPixelData.GetFrameDataU8(frameIndex);
this.currentImage = new Bitmap(this.currentPixelData.ImageWidth, this.currentPixelData.ImageHeight, PixelFormat.Format16bppRgb555);
BitmapData bitmapData = this.currentImage.LockBits(new Rectangle(0, 0, this.currentImage.Width, this.currentImage.Height), ImageLockMode.ReadWrite, this.currentImage.PixelFormat);
System.Runtime.InteropServices.Marshal.Copy(pixels, 0, bitmapData.Scan0, this.currentImage.Width * this.currentImage.Height * 2);
this.currentImage.UnlockBits(bitmapData);

Заранее спасибо

P.S. Прежде чем кто-либо предложит попробовать что-то еще, например ClearCanvas, знайте, что mDCM - единственная библиотека, которая отвечает моим потребностям, и ClearCanvas СЛИШКОМ слишком раздут для того, что мне нужно сделать.

Ответы [ 3 ]

1 голос
/ 07 апреля 2010

Я в конце концов понял это, поэтому, если кто-то еще наткнется на эту проблему, я смог отобразить и сохранить 16-битные изображения в градациях серого, используя код из статьи CodeProject. Вот ссылка на эту статью:

http://www.codeproject.com/KB/graphics/Image16bit.aspx?msg=3210733

0 голосов
/ 07 апреля 2010

Я работаю на Atalasoft , и у нас есть компонент обработки изображений, который сделает это за вас:

DicomDecoder decoder = new DicomDecoder();
using (AtalaImage image = decoder.Read(stream, frameIndex, null)) {
    AtalaImage imageToSave = null;
    if (image.PixelFormat == PixelFormat.Pixel16bppGrayscale) {
        imageToSave = image.GetChangedPixelFormat(PixelFormat.Pixel8bppGrayscale);
    }
    else if (image.PixelFormat == PixelFormat.Pixel48bppBgr) {
        imageToSave = image.GetChangedPixelFormat(PixelFormat.Pixel24bppBgr);
    }
    else {
        imageToSave = image;
    }
    imageToSave.Save(outputStream, new JpegEncoder(), null);
    if (imageToSave != image)
        imageToSave.Dispose();
}

Это немного сложнее, чем нужно - я бы выделил подпрограмму для возврата изображения в формате, подходящем для кодера, который вы хотите использовать. В общем, Jpeg - это довольно ограниченные пиксельные форматы, которые он может обрабатывать, тогда как dicom может инкапсулировать некоторые довольно широкие форматы. TIFF, вероятно, будет лучшим выбором для формата выходного файла.

Я поднял этот вопрос, потому что объект DicomDecoder автоматически обрабатывает более эзотерические пиксельные форматы dicom, позволяет выполнять выравнивание окон (выравнивание, яркость и контрастность) в необработанном пространстве изображения, а также получать метки, и мы даем вы выиграли / веб-формы управления для отображения AtalaImages, что, вероятно, уменьшит размер вашего приложения.

Конечно, существует ряд разумных причин, по которым вы можете быть вынуждены использовать mDCM, но я подумал, что это может помочь вам (или другим) увидеть другой вариант.

0 голосов
/ 06 апреля 2010

Жаль, что вы не используете GDCM с C #. Это будет 5-строчный код:

http://gdcm.sourceforge.net/html/ExtractEncapsulatedFile.cs-example.html

...