Back
PQCHub

灰階化與色彩操作

探索色彩背後的數學,用程式實作灰階、亮度、對比度演算法,掌握影像處理核心。


1 灰階化

影像處理的基礎操作中,灰階化是非常重要的一環。它可以把彩色影像轉換為只包含亮度資訊的單色影像,方便後續分析、處理或特效應用。

灰階化的核心概念是 將每個像素的紅、綠、藍三個通道 (R、G、B) 轉換為單一亮度值。但是人眼對不同顏色敏感度不同,因此直接平均 RGB 值並不總能呈現自然灰階效果。


1.1 灰階化原理

彩色影像的每個像素都由三個通道組成:

  • R (Red):紅色通道
  • G (Green):綠色通道
  • B (Blue):藍色通道

人眼對這三種顏色的敏感度不同,綠色最敏感、紅色次之、藍色最不敏感。為了模擬自然亮度,通常使用 加權平均法 計算灰階值:

\begin{align} Gray = 0.299 \times R + 0.587 \times G + 0.114 \times B \end{align}

這種方法在攝影、電腦視覺中廣泛使用,能保留亮暗對比,讓灰階影像看起來更自然。

補充觀念:

  • 如果不使用加權法,直接平均 (R+G+B)/3 會導致偏暗或偏淡,尤其在綠色占主導的場景。
  • 灰階化可以作為邊緣檢測、影像二值化、特徵提取的前置步驟。 Uploading file..._pehyzzg0b

1.2 程式實作

以下使用我們自製的 BmpImage 類別操作 BMP 影像,每個像素的灰階值都會依加權法計算並更新:

import BmpImage from "./BmpImage.js";

function rgbToGray(img) {
    for (let y = 0; y < img.height; y++) {
        for (let x = 0; x < img.width; x++) {
            const { r, g, b } = img.getPixel(x, y);
            const gray = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
            img.setPixel(x, y, gray, gray, gray);
        }
    }
}

// 載入 BMP 影像
const img = BmpImage.load("test.bmp");

// 進行灰階化
rgbToGray(img);

// 儲存結果
img.save("test_gray.bmp");
console.log("已生成灰階影像 test_gray.bmp");

說明:

  1. getPixel(x, y) 取得每個像素的 RGB 值。BMP 格式的像素資料從左下角開始排列,BmpImage 已經內部處理 Y 軸反轉。
  2. setPixel(x, y, gray, gray, gray) 將灰階值寫回影像,R、G、B 三個通道都設成同一值,完成灰階化。
  3. 使用 Math.round 將浮點數轉整數,確保像素值在 0–255 範圍內。

1.3 觀察結果

灰階化後的影像可以觀察到:

  • 亮區與暗區對比明顯
  • 細節紋理保留良好
  • 對後續影像處理(如邊緣檢測、二值化)非常有幫助
  • 左:原彩色 BMP
  • 右:灰階化後 BMP

小技巧:對於彩色影像,也可以先灰階化再進行亮度或對比度調整,效果通常比直接操作彩色影像更穩定。


2 亮度調整

灰階化之後,我們可以對影像進行 亮度調整,控制整張影像的明暗程度。亮度調整常用於:

  • 修正拍攝過暗或過亮的影像
  • 增強影像細節
  • 影像特效應用

2.1 亮度調整原理

亮度調整的核心概念是對每個像素的 RGB 值加上或乘上某個係數:

\begin{align} R' = clamp(R + \Delta L), \quad G' = clamp(G + \Delta L), \quad B' = clamp(B + \Delta L) \end{align}

  • $\Delta L$ 為亮度增減值,可以是正數(變亮)或負數(變暗)
  • clamp() 函數確保結果在 0–255 之間,避免像素溢位

補充觀念:

  • 直接加減亮度會保持色彩比例不變
  • 也可以使用乘法 $R' = R \times factor$ 來增強對比,但需要注意溢位

2.2 程式實作

以下範例使用我們的 BmpImage 類別,對 BMP 影像進行亮度調整:

import BmpImage from "./BmpImage.js";

function clamp(value) {
    return Math.max(0, Math.min(255, value));
}

function adjustBrightness(img, delta) {
    for (let y = 0; y < img.height; y++) {
        for (let x = 0; x < img.width; x++) {
            const { r, g, b } = img.getPixel(x, y);
            img.setPixel(
                x,
                y,
                clamp(r + delta),
                clamp(g + delta),
                clamp(b + delta)
            );
        }
    }
}

// 載入 BMP 影像
const img = BmpImage.load("test_gray.bmp");

// 調整亮度 (+50 增亮,-50 變暗)
adjustBrightness(img, 50);

// 儲存結果
img.save("test_bright.bmp");
console.log("已生成亮度調整影像 test_bright.bmp");

說明:

  1. clamp 函數避免 RGB 值超出 0–255 範圍
  2. 對每個像素同時操作 R、G、B 通道
  3. 可將灰階影像或彩色影像都進行亮度調整

2.3 觀察效果

  • 正數增亮後,整張影像變得更明亮,暗部細節更明顯
  • 負數變暗後,整張影像更沉穩,亮部細節不易曝光

小技巧:

  • 先灰階化再亮度調整,可以避免彩色通道比例失衡
  • 若同時要調整亮度與對比度,可以先亮度後對比度,效果更自然

3 對比度

對比度調整用來控制影像明暗差異,使亮部更亮、暗部更暗,增強影像層次感。對比度調整常用於:

  • 增強影像視覺衝擊力
  • 改善平淡的照片或掃描影像
  • 預處理影像以利後續分析

3.1 對比度調整原理

對比度調整可以使用以下公式:

\begin{align} R' = clamp((R - 128) \times factor + 128) \end{align}

\begin{align} G' = clamp((G - 128) \times factor + 128) \end{align}

\begin{align} B' = clamp((B - 128) \times factor + 128) \end{align}

  • factor:對比度係數

    • factor > 1 增強對比度
    • factor < 1 降低對比度
  • clamp() 確保像素值在 0–255 之間

  • 將 128 作為中心值,亮度值偏離中心越多,對比度越明顯

補充觀念:

  • 對比度調整前可先灰階化,方便分析亮度分布
  • 調整彩色影像時,RGB 通道同時調整可避免色偏

3.2 程式實作

使用 BmpImage 類別進行對比度調整:

import BmpImage from "./BmpImage.js";

function clamp(value) {
    return Math.max(0, Math.min(255, value));
}

function adjustContrast(img, factor) {
    for (let y = 0; y < img.height; y++) {
        for (let x = 0; x < img.width; x++) {
            const { r, g, b } = img.getPixel(x, y);
            img.setPixel(
                x,
                y,
                clamp((r - 128) * factor + 128),
                clamp((g - 128) * factor + 128),
                clamp((b - 128) * factor + 128)
            );
        }
    }
}

// 載入 BMP 影像
const img = BmpImage.load("test_gray.bmp");

// 增加對比度 (factor > 1)
adjustContrast(img, 1.5);

// 儲存結果
img.save("test_contrast.bmp");
console.log("已生成對比度調整影像 test_contrast.bmp");

說明:

  1. factor 控制對比度強弱
  2. 對每個像素同時操作 R、G、B 通道
  3. 可配合灰階化影像,觀察效果更明顯

3.3 觀察效果

  • factor > 1:亮部更亮,暗部更暗,影像層次感加強
  • factor < 1:整張影像平淡,對比度降低
  • 在部落格上展示前後對比圖,可直觀呈現對比度調整效果

小技巧:

  • 調整對比度前先觀察原圖亮暗分布
  • 若亮度與對比度都要調整,建議先亮度後對比度,避免亮度被過度壓縮

SNPQ © 2025