2010-03-29 3 views
0

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

Вот моя последняя попытка с помощью 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 слишком раздута для того, что мне нужно делать.

+0

Добавлена ​​часть о оттенках серого. Не заинтересованы в покупке LeadTools. Нужен код. –

+0

Я получил возможность использовать LockBits и Marshal.Copy, используя следующий код, но он появляется в радуге цветов вместо оттенков серого: byte [] pixels = currentPixelData.GetFrameDataU8 (frameIndex); currentImage = new Растровое изображение (ширина, высота, PixelFormat.Format16bppRgb555); BitmapData bitmapData = currentImage.LockBits (новый прямоугольник (0, 0, ширина, высота), ImageLockMode.ReadWrite, currentImage.PixelFormat); System.Runtime.InteropServices.Marshal.Copy (пиксели, 0, битмапData.Scan0, ширина * высота * 2); currentImage.UnlockBits (bitmapData); –

ответ

1

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

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

+0

hi ross, Я застрял в той же проблеме. Я не могу решить, правильно ли вы обрабатываете исходные значения уровня окна. как вы это сделаете. спасибо – prashant

0

Я работаю 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(); 
} 

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

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

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