2

我试图从 ipad 上的 dicom 数据中获取 UIImage。

代码如下所示:

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

(在带有要填充的比例的图像视图上,所以大小无关紧要)

但是背景应该是黑色的,骨骼的大部分像素或多或少是白色的......

有人能看出我的失败吗?

编辑:也许 ipad 上的 16 位有问题?

EDIT2:我知道了一个解决方案。我遍历每个像素,计算一个介于 0 到 255 之间的无符号 int 值。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++;
} 
4

2 回答 2

1

您的 EDIT2 建议您正在对图像应用窗口级别和窗口宽度。这通常需要处理任何高于 8 位的内容。为了加快 EDIT2 现在的速度,您始终可以为以前已经计算过的具有相似强度的像素建立一个查找表。

假设您的原始像素值为 1255,根据您的窗口级别和窗口宽度计算,您的最终输出可能为 123(只是一个示例,取决于您的级别和宽度)。然后无论原始值为 1255 的后续像素,它将自动被识别为 123(这应该会为您节省一些时间,因为我们知道,计算将花费更多时间而不是查找数组)。

** 仅供参考:max、min 应该与窗口宽度和窗口级别相关联(最直接的实现之一是:max = 窗口级别 +(窗口宽度 / 2),min = 窗口级别 -(窗口宽度 / 2)。或者,您可以遵循 DICOM 标准,但我忘记了哪一章,尝试灰度软拷贝演示状态。

于 2011-06-01T02:40:38.103 回答
0

我自己没有使用过 CGColorSpaceCreateDeviceGray,但它是否有可能正在寻找 RGBA 值,其中 R、G、B 是 0-255 并且都相同?如果是这种情况,您需要将输入转换为 4 组件数据结构。从 16 位浮点数到 255 字符可以按照我在

如何将 DICOM 图像宽度和级别转换为 JPEG 亮度和对比度?

于 2011-05-27T01:08:12.063 回答