Dicom Pixeldata для UIImage - PullRequest
       6

Dicom Pixeldata для UIImage

2 голосов
/ 16 мая 2011

Я пытаюсь получить UIImage из моих данных dicom на ipad.

Код выглядит так:

reader->SetFileName(documentsFolderPath/test.dcm);
reader->Update();
ImageType *  imageTest = reader->GetOutput(); // get 2d image data
PixelType * pixelData = imageTest->GetBufferPointer();   

const void* buffer = pixelData;

// Set the dimensions of the current context
size_t width = 157; // set manually, but correct
size_t height = 143;

// 1 byte per component
size_t bitsPerComponent = 8;
unsigned int multiplier;
bitsPerComponent *= 2; // short = 2 byte

size_t bitsPerPixel, bytesPerRow;
CGColorSpaceRef colorSpace;
CGBitmapInfo bitmapInfo;
CGDataProviderRef theDataProvider;
CFDataRef theDataReference;
bool shouldInterpolate = NO;
CGColorRenderingIntent theIntent;


bitsPerPixel = bitsPerComponent * 1; // because of grayscale image
colorSpace = CGColorSpaceCreateDeviceGray();
bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrder32Big;

// cg data provider to build the cg image
const UInt8* rawData = static_cast<const UInt8*>(buffer);

// For some reason initiating a CGImage uses BITS per pixel, so we need to divide by 8 to get BYTES 
// per pixel        
bytesPerRow = (bitsPerPixel/8) * width;

theDataReference = CFDataCreate(NULL,
                                rawData,
                                (bytesPerRow*height));

theDataProvider = CGDataProviderCreateWithCFData(theDataReference);



// Finally create the image reference
CGImageRef theImageRef = CGImageCreate(width,
                                       height,
                                       bitsPerComponent,
                                       bitsPerPixel,
                                       bytesPerRow,
                                       colorSpace,
                                       bitmapInfo,
                                       theDataProvider,
                                       nil,
                                       shouldInterpolate,
                                       theIntent);


// Construct an output image
UIImage *myImage = [UIImage imageWithCGImage:(theImageRef)];

imageView.image = myImage;

Но тогда мое выходное изображение выглядит так:

http://www.ettisberger.ch/images/outputImage.png

(на изображении с масштабом для заполнения, поэтому размер не имеет значения)

Но фон должен быть черным, и большинство пикселей кости более или менее белые ...

Есть ли кто-то, кто может увидеть мою неудачу?

РЕДАКТИРОВАТЬ: Может быть, 16 бит на ipad может быть проблемой?

EDIT2: Я знаю решение знаю. Я прохожу каждый пиксель и вычисляю значение типа unsigned int в диапазоне от 0 до 255. Max и min - это максимальные и минимальные значения всей картинки, потому что нам нужно изменить контраст. Это работает, но моему методу требуется 0,1-0,2 секунды для создания одного uiimage - и со стеком из 400 изображений это так медленно, и пользователю пришлось ждать 1 минуту: / Не знаю, есть ли лучшее решение.

    for(int i = 0; i < (bytesPerRow*height);i++){
    short tmpPixelValue = *pixelData;
    short tmpNewPixelValue;

    if(tmpPixelValue == 0){
        tmpNewPixelValue = 0;
    }else{
        tmpNewPixelValue = (tmpPixelValue - min) * (255.0 / (max - min));
    }

    pixelBuffer[i] = (UInt8)tmpNewPixelValue;  

    pixelData++;
} 

Ответы [ 2 ]

1 голос
/ 01 июня 2011

то, что предложил ваш EDIT2, это то, что вы применяете к своим изображениям уровень окна и ширину окна.Это часто требуется для обработки чего-либо выше, чем 8 бит.Чтобы ускорить работу вашего EDIT2, вы всегда можете создать справочную таблицу для пикселей с аналогичной интенсивностью, которая уже была вычислена ранее.

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

** FYI: max, min должны быть связаны с шириной окна и уровнем окна (одна из самых простых реализаций: max = уровень окна + (ширина окна / 2) и min = уровень окна - (ширина окна / 2). Или, вы можете следовать стандарту DICOM, но я забыл, в какой главе, попробуйте Grasscale Softcopy Presentation State.

0 голосов
/ 27 мая 2011

Я сам не использовал CGColorSpaceCreateDeviceGray, но возможно ли, что он ищет значения RGBA, где R, G, B равны 0-255 и все одинаковые? В этом случае вам необходимо преобразовать входные данные в четырехкомпонентную структуру данных. Переход от 16-битного числа с плавающей запятой к 255 символам можно рассчитать, как я указал на

Как перевести ширину и уровень изображения DICOM в яркость и контрастность JPEG?

...