3

我正在尝试编写一个读取 FITS 图像的应用程序。FITS代表灵活图像传输格式,它是一种主要用于存储与天体物理学相关的科学数据的格式,其次,它被大多数使用CCD相机拍摄天空的天文爱好者使用。因此 FITS 文件包含图像,但它们也可能包含表格和其他类型的数据。由于我是 Objectiv-C 和 cocoa 编程的新手(我一年前开始这个项目,但由于我很忙,我几乎一年都没有碰它!),我开始尝试创建一个库,让我可以转换文件的图像内容到 NSImageRep。FITS 图像二进制数据可能是 8 位/像素、16 位/像素、32 位/像素无符号整数或 32 位/像素、64 位/像素浮点数,均采用大端序。

我设法在 16 位/像素、32 位/像素无符号整数中获得灰度 FITS 图像的图像表示,但是当我寻找 32 位/像素浮点时,我得到了非常奇怪的行为(并且这个问题对于 RGB 32 位是值得的/pix 浮点数)。到目前为止,我还没有测试 8 位/像素整数数据和基于 16 位/像素和 32 位/像素整数数据的 RGB 图像,因为我还没有在网上找到示例文件。

以下是我创建灰度图像表单适合文件的代码:

-(void) ConstructImgGreyScale
{
CGBitmapInfo     bitmapInfo;
int bytesPerRow;

switch ([self BITPIX])   // BITPIX : Number bits/pixel. Information extracted from the FITS header
{
    case 8:
        bytesPerRow=sizeof(int8_t);
        bitmapInfo = kCGImageAlphaNone ;
        break;
    case 16:
        bytesPerRow=sizeof(int16_t);
        bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrder16Big;
        break;
    case 32:
        bytesPerRow=sizeof(int32_t);
        bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrder32Big;
        break;
    case 64:
        bytesPerRow=sizeof(int64_t);
        bitmapInfo = kCGImageAlphaNone;
        break;
    case -32:
        bytesPerRow=sizeof(Float32);
        bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrder32Big  | kCGBitmapFloatComponents;
    case -64:
        bytesPerRow=sizeof(Float64);
        bitmapInfo = kCGImageAlphaNone  | kCGBitmapFloatComponents;
        break;
    default:
        NSLog(@"Unknown pixel bit size");
        return;
}
[self setBitsPerSample:abs([self BITPIX])];

[self setColorSpaceName:NSCalibratedWhiteColorSpace];

[self setPixelsWide:[self NAXESofAxis:0]]; // <- Size of the X axis. Extracted from FITS header
[self setPixelsHigh:[self NAXESofAxis:1]]; // <- Size of the Y axis. Extracted from FITS header

[self setSize:  NSMakeSize( 2*[self pixelsWide], 2*[self pixelsHigh])];

[self setAlpha: NO];
[self setOpaque:NO];

CGDataProviderRef provider=CGDataProviderCreateWithCFData ((CFDataRef) Img);

CGFloat Scale[2]={0,28};
image = CGImageCreate ([self pixelsWide],
                       [self pixelsHigh],
                       [self bitsPerSample],
                       [self bitsPerSample],
                       [self pixelsWide]*bytesPerRow,
                       [[NSColorSpace deviceGrayColorSpace] CGColorSpace],
                       bitmapInfo,
                       provider,
                       NULL,
                       NO,
                       kCGRenderingIntentDefault
                       );

CGDataProviderRelease(provider);
return;
}  

这是 32/bits/pix 浮点数据的结果快照:NASA HST 图片

图像似乎向左移动,但更烦人的是我在同一帧中得到了同一图像的两个表示(帧的上部和下部)。

而对于其他一些文件,行为更奇怪: Star Field 1,(对于其他链接请参阅评论,作为新用户,我在此文本中不能有两个以上的链接。我也不能直接放图片。)

所有三个星域图像都是相同拟合文件内容的表示。我在帧的底部获得了正确的图像表示(星星太饱和了,但我还没有使用编码)。但是,在上半部分,每次我打开同一个文件时,我都会得到不同的图像表示。看起来每次我打开这个文件时,它都不会使用相同的字节序列来生成图像表示(至少对于上部而言)。

另外,我不知道底部重复的图像是否包含数据的一半,而上面的图像包含另一半数据,或者它是否只是数据的副本。

当我以原始格式(人类可读数字)转换我的数据内容时,该数字与像素中应该在良好位置的内容兼容。这让我认为问题不是来自数据,而是来自 CGImage 解释数据的方式,即我在传递给 CGImageCreate 函数的参数中的某处是错误的。

在 RGB 适合图像数据的情况下,我在最后将 18 个图像获取到我的帧中。R、G 和 B 图像各 6 个副本。全部为灰度。请注意,对于 RGB 图像,我的代码是不同的。

我究竟做错了什么 ?

4

1 回答 1

1

好的,我终于找到了关于图像重复问题的解决方案。这是一个非常愚蠢的错误,我并不为自己没有早点找到它而感到自豪。

在代码中,我忘记breakcase -32. 仍然存在关于画面转变的问题。当我打开 32 位整数图像时,我没有看到移位,但它出现在 32 位浮点数据上。

有没有人知道我的代码中这种转变可能来自哪里?是不是因为我构建图像的方式?或者有可能是由于我绘制图像的方式?

Bellow 是我用来绘制图像的一段代码。由于图像首先是颠倒的,所以我稍微改变了坐标。

- (bool)draw {
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
if (!context || !image) {
    return NO;
}
NSSize size = [self size];

CGContextTranslateCTM(context, 0, size.height);
CGContextScaleCTM(context, 1, -1);

CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), image);
return YES;
}
于 2011-12-07T21:00:57.230 回答