iOS 上的 ITK 库 - 加载 DICOM

发布于 2024-11-07 17:12:59 字数 907 浏览 0 评论 0原文

我已经为 ipad 构建了 ITK 库 - 并且它可以工作。然后我尝试制作一个 ITK 示例 - 类似这样:

// Load DICOM files
typedef itk::ImageSeriesReader< InputImageType > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
typedef itk::GDCMImageIO ImageIOType;
typedef itk::GDCMSeriesFileNames NamesGeneratorType;
ImageIOType::Pointer gdcmIO = ImageIOType::New();
NamesGeneratorType::Pointer namesGenerator = NamesGeneratorType::New();
namesGenerator->SetInputDirectory( "C:/test" );

但我尝试了很多可能性来加载 ipad 文档文件夹上的目录中的 DICOM 堆栈,而不是 c: /test 路径。但这没有用。

所以我的想法是通过互联网加载一个像这样的 DICOM:

NSData *dicomImage = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.someurl.ch/dicom/blabla.dcm"]];   

现在我考虑尝试获取 dicom 数据(患者姓名等)并将其与图像数据分开。那么我想最后一定可以有一个UIImage来显示在IPAD上。

我为此寻找了一个例子,但遗憾的是......我没有找到好的东西。如果有人知道如何通过 ITK 在 ipad 上加载 dcm 或如何从 NSData 对象中获取图像数据?

I have built the ITK library for the ipad - and it works. Then I tried to make an ITK example - something like that:

// Load DICOM files
typedef itk::ImageSeriesReader< InputImageType > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
typedef itk::GDCMImageIO ImageIOType;
typedef itk::GDCMSeriesFileNames NamesGeneratorType;
ImageIOType::Pointer gdcmIO = ImageIOType::New();
NamesGeneratorType::Pointer namesGenerator = NamesGeneratorType::New();
namesGenerator->SetInputDirectory( "C:/test" );

But I tried a lot of possibilites to load a DICOM stack in a directory on the documents folder of the ipad instead of the c:/test path. But that didn't work.

So my idea is to load a DICOM like that over the internet:

NSData *dicomImage = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.someurl.ch/dicom/blabla.dcm"]];   

And now I think about trying to get out the dicom data (patient name etc) and separate it from the image data. Then I think it must be possible to have at the end an UIImage to display on the IPAD.

I searched for an example for that, but sadly...i didnt found something good. If anybody has got an idea how to load a dcm on the ipad through ITK or an idea how to get the image data out of the NSData object?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我不是你的备胎 2024-11-14 17:12:59

ITK实际上使用GDCM来读取DICOM文件,因此直接使用GDCM可能更容易。
http://sourceforge.net/apps/mediawiki/gdcm/index.php

至于在 iPad(或任何移动设备)上加载 DICOM 文件,我会很小心。一些 DICOM 文件非常大(大约 GB),这可能会使您的应用程序崩溃。当然,无论如何,您可能很难将这么大的文件加载到 iPad 上:)


像素数据不一定是您期望在 JPEG 中找到的 RGB 数据。检查光度解释。如果它是 RGB,那么就可以了(解码和解压缩后)。如果它是单色的,您可能需要转换为 RGB 值(请参阅 如何将 DICOM 图像宽度和级别转换为 JPEG 亮度和对比度?),然后将数据传递给 UIImage。

ITK actually uses GDCM to read DICOM files, so it's probably easier to use GDCM directly.
http://sourceforge.net/apps/mediawiki/gdcm/index.php

As for loading DICOM files on the iPad (or any mobile device), I would be careful when doing so. Some DICOM files are very large (on the order of GBs), and that would probably just crash your application. Of course, you'd probably have a difficult time loading files that large onto the iPad anyway :)


The pixel data is not necessarily RGB data as you would expect to find in a JPEG. Check the photometric interpretation. If it's RGB, then you're good to go (after decoding & decompression). If it's monochrome, you may need to convert to RGB values (see How to translate DICOM image width and level to JPEG brightness and contrast?) before passing the data to UIImage.

魂归处 2024-11-14 17:12:59

您可能想研究 DCMTK。在 iPhone 上,您可能需要 DCMTK 中的网络协议功能。

You may want to investigate DCMTK. On an iphone you will likely need the network protocol capabilities that are in DCMTK.

oО清风挽发oО 2024-11-14 17:12:59

自从我上一篇文章以来,我现在对我的问题有了一些解决方案。

namesGenerator->SetInputDirectory( documentFolderPath );
typedef std::vector<std::string> FileNamesContainer; 
FileNamesContainer fileNames = nameGenerator->GetInputFileNames();
reader->SetFileNames( fileNames );
reader->Update();
ImageType *  imageTest = reader->GetOutput(); // get 3d volume
PixelType * pixelData = imageTest->GetBufferPointer(); // get bufferpointer

这样,我就可以加载 DICOM 堆栈并获取整个 dicom 标头信息:) 现在我的问题是将图像像素数据获取到 UIImage 中。我可以使用此代码加载单个像素值:(仅用于测试,getPixel 是一个缓慢的方法)

ImageType::IndexType pixelIndex;
pixelIndex[0] = 100; 
pixelIndex[1] = 100; 
pixelIndex[2] = 0;

ImageType::PixelType pixelValue = imageTest->GetPixel( pixelIndex );

但我的问题是,我不明白如何处理 *pixeldata (缓冲区指针)的数据来创建 UIImage。遗憾的是我没有在 ITK 文档中找到一些示例:(

Since my last post, I have now a little solution for my problem.

namesGenerator->SetInputDirectory( documentFolderPath );
typedef std::vector<std::string> FileNamesContainer; 
FileNamesContainer fileNames = nameGenerator->GetInputFileNames();
reader->SetFileNames( fileNames );
reader->Update();
ImageType *  imageTest = reader->GetOutput(); // get 3d volume
PixelType * pixelData = imageTest->GetBufferPointer(); // get bufferpointer

With that, I can load DICOM stacks and get out the whole dicom header information :) Now my problem is about getting the image pixel data into an UIImage. I can load single pixelvalues with this code:(just for a test, getPixel is a slow method)

ImageType::IndexType pixelIndex;
pixelIndex[0] = 100; 
pixelIndex[1] = 100; 
pixelIndex[2] = 0;

ImageType::PixelType pixelValue = imageTest->GetPixel( pixelIndex );

But my problem is, that I dont understand how I can handle the data of *pixeldata (the bufferpointer) to create a UIImage. Sadly I didnt found some example in the ITK documentation :(

春夜浅 2024-11-14 17:12:59
//assume that the image width is 880 and the image height is 635
int imageWidth = 880;
int imageHeight = 635;
NSString *dicomPath = [[[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/"] stringByAppendingString:@"your dicom file name"];
const char *c_dicomPath = [dicomPath UTF8String];

typedef unsigned char InputPixelType; 
const unsigned int InputDimension = 3;
typedef itk::Image< InputPixelType, InputDimension > InputImageType;

typedef itk::ImageFileReader< InputImageType > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(c_dicomPath);

typedef itk::GDCMImageIO ImageIOType; 
ImageIOType::Pointer gdcmImageIO = ImageIOType::New(); 
reader->SetImageIO(gdcmImageIO);

InputPixelType *imageBuf = (InputPixelType*)malloc(sizeof(InputPixelType)*imageHeight*imageWidth*3);
reader->Update();

//get dicom image
memset(imageBuf, 0, sizeof(InputPixelType)*imageHeight*imageWidth*3);

gdcmImageIO->Read(imageBuf);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGDataProviderRef provider = CGDataProviderCreateWithData(nil, imageBuf, imageWidth*imageHeight*3*sizeof(InputPixelType), nil);  

CGImageRef imageRef = CGImageCreate(imageWidth,//width
                                    imageHeight,//height 
                                    8,//size_t bitsPerComponent, 
                                    24,//size_t bitsPerPixel,
                                    imageWidth*sizeof(InputPixelType)*3,//size_t bytesPerRow, 
                                    colorspace,//CGColorSpaceRef space,
                                    kCGBitmapByteOrderDefault,//CGBitmapInfo bitmapInfo,
                                    provider,//CGDataProviderRef provider,
                                    nil,//const CGFloat *decode,
                                    NO,//bool shouldInterpolate, 
                                    kCGRenderingIntentDefault//CGColorRenderingIntent intent
                                    );
//here is the dicom image decode from dicom file
UIImage *dicomImage = [[UIImage alloc] initWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationUp];
//assume that the image width is 880 and the image height is 635
int imageWidth = 880;
int imageHeight = 635;
NSString *dicomPath = [[[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/"] stringByAppendingString:@"your dicom file name"];
const char *c_dicomPath = [dicomPath UTF8String];

typedef unsigned char InputPixelType; 
const unsigned int InputDimension = 3;
typedef itk::Image< InputPixelType, InputDimension > InputImageType;

typedef itk::ImageFileReader< InputImageType > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(c_dicomPath);

typedef itk::GDCMImageIO ImageIOType; 
ImageIOType::Pointer gdcmImageIO = ImageIOType::New(); 
reader->SetImageIO(gdcmImageIO);

InputPixelType *imageBuf = (InputPixelType*)malloc(sizeof(InputPixelType)*imageHeight*imageWidth*3);
reader->Update();

//get dicom image
memset(imageBuf, 0, sizeof(InputPixelType)*imageHeight*imageWidth*3);

gdcmImageIO->Read(imageBuf);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGDataProviderRef provider = CGDataProviderCreateWithData(nil, imageBuf, imageWidth*imageHeight*3*sizeof(InputPixelType), nil);  

CGImageRef imageRef = CGImageCreate(imageWidth,//width
                                    imageHeight,//height 
                                    8,//size_t bitsPerComponent, 
                                    24,//size_t bitsPerPixel,
                                    imageWidth*sizeof(InputPixelType)*3,//size_t bytesPerRow, 
                                    colorspace,//CGColorSpaceRef space,
                                    kCGBitmapByteOrderDefault,//CGBitmapInfo bitmapInfo,
                                    provider,//CGDataProviderRef provider,
                                    nil,//const CGFloat *decode,
                                    NO,//bool shouldInterpolate, 
                                    kCGRenderingIntentDefault//CGColorRenderingIntent intent
                                    );
//here is the dicom image decode from dicom file
UIImage *dicomImage = [[UIImage alloc] initWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationUp];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文