You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中将cv::Mat保存为FITS格式图像?(OpenCV)

解决OpenCV cv::Mat保存为FITS格式的问题

问题原因

OpenCV的imwrite函数不内置支持FITS格式的写入器,直接指定.fits扩展名会触发could not find a writer for the specified extension错误。要保存FITS文件,需要使用专门的天文数据处理库,最常用的是CFITSIO(NASA官方维护的FITS格式标准库)。

解决方案:使用CFITSIO库实现写入

步骤1:准备CFITSIO

  • 先在开发环境中安装CFITSIO库:可通过包管理器(如Ubuntu的libcfitsio-dev)或从官方源码编译安装。
  • 在C++项目中链接CFITSIO库,编译时添加-lcfitsio参数。

步骤2:编写转换与写入代码

以下是针对单通道cv::Mat的示例代码(支持常见的浮点型、整型像素格式):

#include <opencv2/opencv.hpp>
#include <fitsio.h>

bool saveMatToFITS(const cv::Mat& mat, const std::string& filePath) {
    // 仅支持单通道图像,多通道需拆分为多个HDU或转为单通道处理
    if (mat.channels() != 1) {
        std::cerr << "仅支持单通道图像写入FITS" << std::endl;
        return false;
    }

    fitsfile* fptr;
    int status = 0;
    long naxes[2] = {mat.cols, mat.rows}; // FITS维度顺序为(宽度, 高度)
    int bitpix = 0;

    // 匹配cv::Mat类型与FITS的bitpix参数,确保数据格式兼容
    switch (mat.type()) {
        case CV_8U: bitpix = BYTE_IMG; break;
        case CV_16U: bitpix = SHORT_IMG; break;
        case CV_16S: bitpix = SHORT_IMG; break;
        case CV_32F: bitpix = FLOAT_IMG; break;
        case CV_64F: bitpix = DOUBLE_IMG; break;
        default:
            std::cerr << "不支持的图像像素类型" << std::endl;
            return false;
    }

    // 创建新FITS文件,覆盖已存在的文件
    fits_create_file(&fptr, filePath.c_str(), &status);
    if (status != 0) {
        fits_report_error(stderr, status);
        return false;
    }

    // 创建包含图像数据的Primary HDU
    fits_create_img(fptr, bitpix, 2, naxes, &status);
    if (status != 0) {
        fits_report_error(stderr, status);
        fits_close_file(fptr, &status);
        return false;
    }

    // 写入图像数据:cv::Mat与FITS均为行优先存储,直接复制即可
    fits_write_img(fptr, bitpix, 1, mat.total(), mat.data, &status);
    if (status != 0) {
        fits_report_error(stderr, status);
        fits_close_file(fptr, &status);
        return false;
    }

    // 关闭文件并检查错误
    fits_close_file(fptr, &status);
    if (status != 0) {
        fits_report_error(stderr, status);
        return false;
    }

    return true;
}

// 使用示例
int main() {
    cv::Mat img = cv::imread("test.png", cv::IMREAD_GRAYSCALE);
    if (img.empty()) {
        std::cerr << "读取图像失败" << std::endl;
        return -1;
    }

    if (saveMatToFITS(img, "output.fits")) {
        std::cout << "FITS文件保存成功" << std::endl;
    } else {
        std::cerr << "FITS文件保存失败" << std::endl;
        return -1;
    }

    return 0;
}

代码说明

  • 单通道限制:FITS标准中基础图像HDU通常为单通道,多通道图像需拆分为多个HDU,或转换为伪彩色单通道格式自行处理。
  • 类型匹配:严格对应cv::Mat与FITS的数据类型,避免精度损失或格式错误。
  • 错误处理:CFITSIO通过status返回错误码,每次调用后需检查并输出错误信息。

注意事项

  • 多通道图像处理:若需保存多通道cv::Mat,需将每个通道作为独立HDU写入,或转换为FITS支持的彩色扩展格式。
  • 编译命令示例:GCC编译时需同时链接OpenCV与CFITSIO,如g++ your_code.cpp -o your_program pkg-config --cflags --libs opencv4 -lcfitsio

内容的提问来源于stack exchange,提问作者Runsva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:45:17