用cfitsio读取fits文件是最直接方案,因其原生支持多扩展、wcs头信息等核心特性,而opencv等通用库无法解析;需正确处理bscale/bzero缩放、多hdu切换及wcs关键字提取。

用 CFITSIO 读取 FITS 文件是最直接的方案
CFITSIO 是 NASA 官方维护的 C 语言库,C++ 项目中调用它既稳定又高效。别试图用通用图像库(如 OpenCV、stb_image)硬解 FITS——它们不支持 FITS 的多扩展、表结构、世界坐标系(WCS)头信息等核心特性,强行读取只会得到乱码或崩溃。
实操建议:
- Linux/macOS 下用
brew install cfitsio或apt install libcfitsio-dev;Windows 推荐用 vcpkg:vcpkg install cfitsio:x64-windows - C++ 中只需
#include "fitsio.h",链接时加-lcfitsio(Linux/macOS)或对应 .lib(Windows) - 不要自己解析 FITS 二进制格式——头块(2880 字节/块)、数据对齐、BSCALE/BZERO 缩放等细节全由 CFITSIO 封装,手动处理极易出错
读取主图像数据:注意数据类型与缩放参数
FITS 图像数据常以 short、int、float 存储,但实际物理值往往需经 BSCALE 和 BZERO 变换。直接 memcpy 原始字节会得到错误数值。
正确做法:
- 用
fits_get_img_type先查原始类型(SHORT_IMG、LONG_IMG、FLOAT_IMG等) - 用
fits_get_img_equivtype获取“等效类型”(即应用 BSCALE/BZERO 后应转成的目标类型,通常是TFLOAT) - 调用
fits_read_img或更安全的fits_read_pix,传入目标类型指针,CFITSIO 自动完成缩放和类型转换 - 示例片段:
float *data = new float[nx * ny];<br>fits_read_img(fptr, TFLOAT, fpixel, nelements, &nullval, data, &anynul, &status);
读取 WCS 信息:别只盯着像素数据
天文图像的价值很大程度上取决于坐标系。FITS 头中包含 CRVAL、CRPIX、CD1_1 等 WCS 关键字,但 CFITSIO 不解析它们——它只负责读头字符串。你需要额外库(如 astropy.wcs Python 端,或 C++ 的 WCSTools / astrometry.net C API)做后续解算。
关键提醒:
- 用
fits_read_key逐个读 WCS 相关关键字,例如:fits_read_key(fptr, TDOUBLE, "CRVAL1", &crval1, comment, &status) - 别假设所有 FITS 都用
CDi_j;老文件可能用PCi_j+CDELT,新标准倾向PCi_j;必须检查CTYPE1是否为"RA---TAN"类型再决定如何构造投影矩阵 - 若只需简单线性近似,可手工组合
CRVAL/CRPIX/CDELT,但遇到大视场或非切平面投影时必然偏差显著
处理多扩展 FITS(MEF):忽略扩展名会漏掉关键数据
一个 FITS 文件常含多个 HDU(Header Data Unit):主图像(PRIMARY)、误差图(ERR)、质量图(DQ)、甚至二进制表(BINTABLE)存星表。只读第 0 个 HDU 是常见错误。
操作要点:
- 用
fits_get_num_hdus查总 HDU 数,用fits_get_hdu_num和fits_movabs_hdu切换当前 HDU - 用
fits_get_hdu_type区分IMAGE_HDU、ASCII_TBL、BINARY_TBL;表结构需用fits_read_col系列函数,不能套用图像读取逻辑 - 扩展名(EXTNAME)比序号更可靠,例如科学数据常在
EXTNAME = "SCI"的 HDU 中,而非固定第 1 个;用fits_get_extnum或fits_movnam_hdu定位 - 某些巡天数据(如 DECaLS)把不同曝光的图像放在不同 EXTNAME 下,跳过就等于丢掉半张图
真正麻烦的不是读出像素值,而是确认你读的是哪个物理量(counts?electrons?Jy?)、用了哪套 WCS、是否已扣除偏置/增益/暗流、以及该 HDU 是否被标记为 QUALITY=BAD。这些信息全藏在头里,且各巡天项目约定不一——盯紧头关键字,比调通代码花的时间更多。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











