首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 影像處理實戰:灰度與偽彩色圖像互轉核心算法詳解

     編輯:VC 教學

前言:為什麼需要灰度/彩色轉換?

工業檢測、醫學影像、電腦視覺等領域常面臨:彩色影像資料量大、處理慢,需轉灰度加速運算;灰度影像動態範圍窄,人眼難辨識細微差異,需偽彩色增強視覺效果。本文詳解兩種轉換的數學模型與 VC++ 實現代碼。

一、彩色轉灰度:亮度加權平均法

標準公式 (ITU-R BT.601)

Gray = 0.299 × R + 0.587 × G + 0.114 × B

綠色通道權重最高,因人眼對綠光最敏感。工程上常簡化為 Gray = G 或整數運算 Gray = (R*30 + G*59 + B*11) / 100 避免浮點運算。

二、灰度轉偽彩色:分段線性映射

將 0~255 灰度值映射為 RGB 三通道,產生豐富色彩層次。本文採用四段線性變換曲線(見下圖),對應代碼邏輯:

R 通道映射曲線
G 通道映射曲線
B 通道映射曲線

映射規則表

灰度區間RGB視覺效果
0 ~ 6404×Gray255深藍 → 青
64 ~ 12802554×(128-Gray)青 → 黃
128 ~ 1924×(Gray-128)2550黃 → 紅
192 ~ 2552554×(255-Gray)0紅 → 白

三、VC++ 核心實現代碼 (MFC DIB 操作)

void CDibView::OnMenuChange() {
    // 1. 取得來源灰度 DIB
    HDIB hDib = GetDocument()->GetHDIB();
    LPBITMAPINFOHEADER lpBi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
    BYTE* pSrc = (BYTE*)FindDIBBits(lpBi);
    int w = lpBi->biWidth, h = lpBi->biHeight;
    int srcStride = WIDTHBYTES(w * 8); // 8-bit 灰度行跨度

    // 2. 建立目標 24-bit 彩色 DIB
    BITMAPINFO* pBmi = new BITMAPINFO;
    pBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    pBmi->bmiHeader.biWidth = w;
    pBmi->bmiHeader.biHeight = h;
    pBmi->bmiHeader.biPlanes = 1;
    pBmi->bmiHeader.biBitCount = 24;
    pBmi->bmiHeader.biCompression = BI_RGB;
    int dstStride = WIDTHBYTES(w * 24);
    pBmi->bmiHeader.biSizeImage = dstStride * h;

    HGLOBAL hDst = GlobalAlloc(GMEM_FIXED, pBmi->bmiHeader.biSizeImage);
    BYTE* pDst = (BYTE*)GlobalLock(hDst);

    // 3. 逐像素轉換 (注意 BGR 順序)
    for (int y = 0; y < h; ++y) {
        BYTE* sRow = pSrc + y * srcStride;
        BYTE* dRow = pDst + y * dstStride;
        for (int x = 0; x < w; ++x) {
            BYTE gray = sRow[x];
            int R, G, B;

            if (gray <= 64) { R = 0; G = gray * 4; B = 255; }
            else if (gray <= 128) { R = 0; G = 255; B = (128 - gray) * 4; }
            else if (gray <= 192) { R = (gray - 128) * 4; G = 255; B = 0; }
            else { R = 255; G = (255 - gray) * 4; B = 0; }

            // 寫入 BGR 順序 (Windows DIB 標準)
            dRow[x*3]   = (BYTE)B;
            dRow[x*3+1] = (BYTE)G;
            dRow[x*3+2] = (BYTE)R;
        }
    }

    // 4. 繪製到視窗
    CClientDC dc(this);
    StretchDIBits(dc.m_hDC, 0, 0, w, h, 0, 0, w, h,
                  pDst, pBmi, DIB_RGB_COLORS, SRCCOPY);

    // 5. 清理
    GlobalUnlock(hDib); GlobalUnlock(hDst);
    GlobalFree(hDst); delete pBmi;
}

四、效果展示

原始灰度影像
圖一 原始灰度影像

偽彩色處理結果
圖二 偽彩色增強結果

五、優化與擴展建議

  • 查表法 (LUT): 預計算 256 灰度對應的 RGB 值,轉換時直接查表,消除分支判斷,速度提升 3~5 倍。
  • SIMD 向量化: 使用 SSE/AVX 並行處理 16/32 像素,配合 `_mm_shuffle_epi8` 重排 BGR 通道。
  • 其他色圖: Jet、Hot、Parula、Viridis 等科學視覺化常用色圖,適用不同領域。
  • OpenCV 替代: `cv::applyColorMap(gray, color, cv::COLORMAP_JET)` 一行解決,生產環境首選。

結語

灰度與偽彩色互轉是影像處理基礎環節。理解其數學本質(亮度加權與分段映射)並掌握 DIB 底層操作,有助於在無第三方庫環境下實現高效視覺化。現代專案建議直接使用 OpenCV 等成熟庫,專注於上層業務邏輯創新。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved