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

8位索引格式Gdiplus::Bitmap转cv::Mat图像褪色问题求助

问题分析

你遇到的褪色问题核心原因是:8位索引位图(PixelFormat8bppIndexed)的像素值并非直接的灰度值,而是调色板的索引。你的代码直接将这些索引值当作灰度值存入cv::Mat,相当于使用了错误的颜色映射,导致图像颜色失真、褪色。

解决方案

要正确转换8位索引位图到cv::Mat,必须先获取位图的调色板,再将每个像素的索引值映射为调色板中对应的灰度值。以下是修正后的代码:

// Converting 8bpp indexed bitmap to cv::Mat correctly
Gdiplus::PixelFormat format = m_Bitmap->GetPixelFormat();
if (format == PixelFormat8bppIndexed)
{
    Gdiplus::BitmapData bitmapData;
    Gdiplus::Rect rect(0, 0, width, height);
    m_Bitmap->LockBits(&rect, Gdiplus::ImageLockModeRead, format, &bitmapData);
    
    // 获取位图的调色板
    Gdiplus::ColorPalette* palette = m_Bitmap->GetPalette();
    if (!palette)
    {
        m_Bitmap->UnlockBits(&bitmapData);
        // 处理调色板获取失败的情况
        return;
    }

    // 创建灰度查找表:将索引映射为对应的灰度值(取RGB的平均值或直接取R通道,因为是灰度图)
    uchar lut[256];
    for (int i = 0; i < 256; ++i)
    {
        // 灰度图的调色板RGB分量相同,直接取R通道即可
        lut[i] = palette->Entries[i].R;
    }

    // 先创建包含索引值的Mat
    cv::Mat indexMat(height, width, CV_8UC1, static_cast<unsigned char*>(bitmapData.Scan0), bitmapData.Stride);
    // 使用查找表转换为实际灰度图
    cv::Mat nmat;
    cv::LUT(indexMat, cv::Mat(1, 256, CV_8UC1, lut), nmat);

    m_Bitmap->UnlockBits(&bitmapData);
    // 后续使用nmat即可
}
补充说明
  • 你之前处理32bppARGB位图时正常,是因为该格式的每个像素直接存储了ARGB四个通道的实际颜色值,无需依赖调色板,直接转换为灰度图即可得到正确结果。
  • 若你的8位索引位图确实是灰度图,调色板的RGB分量应该是相同的(比如索引255对应RGB(255,255,255),索引0对应RGB(0,0,0)),此时取R/G/B任意通道的数值作为灰度值都可以。如果是彩色索引图,需要根据需求转换为灰度(比如取RGB的加权平均值)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 01:26:13