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

如何在OpenCV(C++)中将彩色图像转换为16位灰度图?

OpenCV 4.x将彩色图像转为16位灰度图的正确方法

问题背景

在OpenCV 4.1.2 + C++17环境下,需要将彩色图像转换为16位灰度图以获得更细腻的灰度渐变,同时实现像素访问与保存。现有代码可完成8位灰度转换,但直接尝试16位转换时出现内存异常,保存的JPG文件损坏,且数据未正确映射到16位范围。

现有8位转换代码:

#include <iostream>
#include <string>

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/core/mat.hpp>
#include <opencv2/imgcodecs.hpp>

int main()
{
    cv::Mat image = cv::imread("test.jpg", -1);

    cv::Mat imageGray;
    cv::cvtColor(image, imageGray, cv::COLOR_BGR2GRAY);

    std::cout << "First pixel: " + std::to_string(imageGray.at<uchar>(0, 0)) + "\n";

    cv::imwrite("gray.jpg", imageGray);

    return 0;
}

核心问题分析

  1. 16位类型未正确初始化:直接用at<ushort>访问未指定类型的Mat,会因内存布局不匹配触发异常;
  2. 像素值未缩放:8位图像的0-255范围需映射到16位的0-65535,否则16位数据仅低8位有效,失去细腻度;
  3. 保存格式不兼容:JPEG格式仅支持8位图像,保存16位数据会导致文件损坏。

解决方案

正确转换流程

  1. 将8位彩色图像转换为16位彩色图像,同步完成像素值范围缩放;
  2. 将16位彩色图像转换为16位灰度图像;
  3. 使用ushort类型访问16位灰度像素;
  4. 保存为支持16位的图像格式(如PNG、TIFF)。

完整代码示例

#include <iostream>
#include <string>

#include <opencv2/opencv.hpp>

int main()
{
    // 加载8位彩色图像
    cv::Mat image = cv::imread("test.jpg", cv::IMREAD_COLOR);
    if (image.empty()) {
        std::cerr << "图像加载失败!" << std::endl;
        return -1;
    }

    cv::Mat image16BGR;
    // 将8位BGR转16位BGR,缩放因子257(65535/255),把0-255映射到0-65535
    image.convertTo(image16BGR, CV_16UC3, 257.0);

    cv::Mat imageGray16;
    // 将16位BGR转换为16位灰度图(类型CV_16UC1)
    cv::cvtColor(image16BGR, imageGray16, cv::COLOR_BGR2GRAY);

    // 访问16位灰度像素,使用ushort类型匹配CV_16UC1
    ushort firstPixel = imageGray16.at<ushort>(0, 0);
    std::cout << "第一个像素(16位):" << firstPixel << "\n";

    // 保存为PNG格式(支持16位灰度),禁止用JPG
    if (!cv::imwrite("gray_16bit.png", imageGray16)) {
        std::cerr << "图像保存失败!" << std::endl;
        return -1;
    }

    return 0;
}

关键说明

  • convertTo的作用:完成图像类型转换的同时,通过缩放因子将8位像素值线性映射到16位的全范围,保证灰度渐变的细腻度;
  • cvtColor的输出类型:输入为16位彩色图时,COLOR_BGR2GRAY会自动输出CV_16UC1类型的灰度图,与C++的ushort类型完全匹配,避免内存异常;
  • 保存格式选择:必须使用支持16位图像的格式(如PNG、TIFF),JPEG仅支持8位,无法正确存储16位数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:18:17