Экспорт JPG из файла Dicom с помощью mDCM

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

Вот моя последняя попытка использовать 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++;
    }
}

ОБНОВЛЕНИЕ: я стал ближе, используя 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 СЛИШКОМ слишком раздут для того, что мне нужно делать.


person Ross Peoples    schedule 29.03.2010    source источник
comment
Добавлен раздел о градациях серого. Не заинтересован в покупке LeadTools. Нужен код.   -  person Ross Peoples    schedule 30.03.2010
comment
Я смог продвинуться дальше, используя LockBits и Marshal.Copy, используя следующий код, но он выходит в радуге цветов вместо оттенков серого: byte [] пикселей = currentPixelData.GetFrameDataU8 (frameIndex); currentImage = новое растровое изображение (ширина, высота, PixelFormat.Format16bppRgb555); BitmapData bitmapData = currentImage.LockBits (новый прямоугольник (0, 0, ширина, высота), ImageLockMode.ReadWrite, currentImage.PixelFormat); System.Runtime.InteropServices.Marshal.Copy (пикселей, 0, bitmapData.Scan0, ширина * высота * 2); currentImage.UnlockBits (bitmapData);   -  person Ross Peoples    schedule 30.03.2010


Ответы (3)


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

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

person Ross Peoples    schedule 07.04.2010
comment
привет Росс, я застрял на той же проблеме. Я не могу решить, правильно ли вы работаете с начальными значениями уровня окна. как вы это сделаете. Благодарность - person prashant; 21.04.2010

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

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

person malat    schedule 06.04.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, но я подумал, что это может помочь вам (или другим) увидеть другой вариант.

person plinth    schedule 07.04.2010