圖像預處理是計算機視覺任務(如目標檢測、圖像分割、人臉識別)的基礎步驟,核心目的是消除圖像中的噪聲、提升對比度、修正幾何畸變等,為后續高階處理提供高質量輸入。以下先系統梳理經典算法,再通過Python實現2個高頻應用算法(直方圖均衡化、中值濾波)。
一、圖像預處理經典算法梳理
根據處理目標,可將經典算法分為5大類,每類包含核心算法、原理、目的及應用場景:
1. 幾何變換類(修正空間畸變)
針對圖像的空間位置或形狀偏差,調整像素坐標以滿足后續對齊、裁剪等需求。
算法 | 原理 | 核心目的 | 應用場景 |
---|---|---|---|
平移 | 對所有像素按指定偏移量(dx, dy)移動,公式:(x’, y’) = (x+dx, y+dy) | 調整圖像位置 | 圖像拼接、目標定位校準 |
旋轉 | 以某點(如中心)為原點,按角度θ旋轉,需處理像素插值避免模糊 | 修正圖像傾斜 | 文檔掃描(矯正傾斜文字) |
縮放 | 按比例(fx, fy)放大/縮小像素,常用雙線性插值提升畫質 | 統一圖像尺寸 | 神經網絡輸入標準化(如224x224) |
翻轉 | 水平翻轉(左右鏡像)或垂直翻轉(上下鏡像) | 數據增強、修正視角 | 人臉識別(增加樣本多樣性) |
2. 圖像增強類(提升視覺質量)
通過調整像素灰度/顏色分布,增強圖像的細節對比度,解決低光照、模糊等問題。
算法 | 原理 | 核心目的 | 應用場景 |
---|---|---|---|
全局直方圖均衡化 | 拉伸像素灰度分布,使直方圖趨于均勻(映射灰度累積概率) | 提升整體對比度 | 醫學圖像(如X光片)、低光照片 |
CLAHE(自適應直方圖均衡化) | 將圖像分塊,對每塊單獨均衡化,限制對比度避免過增強 | 增強局部細節(如暗區) | 逆光照片、監控圖像 |
伽馬校正 | 通過冪函數(O = I^γ)調整灰度:γ<1提亮,γ>1壓暗 | 修正光照不均 | 顯示器校準、水下圖像增強 |
對比度拉伸(線性變換) | 線性映射灰度范圍:O = a*I + b(a>1增強對比度,a<1降低) | 擴展有效灰度區間 | 灰度范圍狹窄的圖像(如霧天圖) |
3. 圖像去噪類(消除干擾像素)
針對圖像采集過程中的噪聲(如椒鹽噪聲、高斯噪聲),通過鄰域像素平滑實現去噪。
算法 | 原理 | 核心目的 | 應用場景 |
---|---|---|---|
均值濾波 | 用鄰域內所有像素的平均值替換中心像素 | 消除高斯噪聲 | 輕微模糊的自然圖像 |
中值濾波 | 用鄰域內像素的中值替換中心像素 | 消除椒鹽噪聲(脈沖噪聲) | 老照片、傳感器噪聲圖像 |
高斯濾波 | 用高斯核(權重隨距離遞減)加權平均鄰域像素 | 平滑圖像、保留細節 | 預處理(如邊緣檢測前去噪) |
雙邊濾波 | 結合空間距離(鄰域權重)和灰度相似度(避免模糊邊緣)加權平均 | 去噪+保留邊緣 | 人像美顏、紋理保留 |
4. 顏色空間轉換(適配任務需求)
將圖像從默認的RGB空間轉換為其他空間,簡化后續處理(如分離亮度與色彩)。
轉換方向 | 原理 | 核心目的 | 應用場景 |
---|---|---|---|
RGB → 灰度 | 加權平均RGB通道:Gray = 0.299R + 0.587G + 0.114B(符合人眼感知) | 減少維度(3→1) | 灰度圖像任務(如文字識別) |
RGB → HSV | 分離色調(H)、飽和度(S)、亮度(V)通道 | 單獨調整亮度/色彩 | 圖像增強、色彩分割 |
RGB → YCrCb | 分離亮度(Y)與色差(Cr/Cb)通道 | 視頻壓縮、膚色檢測 | 人臉識別(膚色區域提取) |
5. 閾值處理(二值化分割)
將灰度圖轉換為二值圖(僅黑白兩色),突出目標區域。
算法 | 原理 | 核心目的 | 應用場景 |
---|---|---|---|
全局閾值 | 用固定閾值T分割:I>T設為255(白),否則設為0(黑)(如Otsu自動選T) | 簡單目標分割 | 文字提取、硬幣檢測 |
自適應閾值 | 按局部區域動態計算閾值(如鄰域均值) | 處理光照不均圖像 | 文檔掃描(文字與背景分離) |
二、Python實現經典算法(2個高頻案例)
以下基于 OpenCV(圖像處理庫) 和 Matplotlib(圖像顯示庫) 實現,需先安裝依賴:
pip install opencv-python numpy matplotlib
案例1:直方圖均衡化(全局+CLAHE)
需求:提升低對比度圖像的細節(如逆光照片),對比全局均衡化與CLAHE的效果差異。
實現步驟:
- 加載圖像并轉換為灰度圖(均衡化通常在單通道上進行);
- 實現全局直方圖均衡化;
- 實現CLAHE(自適應均衡化);
- 顯示原圖、全局均衡化圖、CLAHE圖及對應直方圖。
代碼:
import cv2
import numpy as np
import matplotlib.pyplot as plt# 1. 加載圖像(以灰度模式讀取,0表示灰度)
img = cv2.imread("low_contrast_image.jpg", 0) # 替換為你的圖像路徑
if img is None:raise ValueError("圖像加載失敗,請檢查路徑是否正確!")# 2. 全局直方圖均衡化
global_eq = cv2.equalizeHist(img)# 3. CLAHE(自適應直方圖均衡化)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) # clipLimit限制對比度,tileGridSize分塊大小
clahe_eq = clahe.apply(img)# 4. 計算各圖像的直方圖(用于對比)
def calculate_histogram(image):hist = cv2.calcHist([image], [0], None, [256], [0, 256])return hist / hist.sum() # 歸一化,便于顯示hist_original = calculate_histogram(img)
hist_global = calculate_histogram(global_eq)
hist_clahe = calculate_histogram(clahe_eq)# 5. 顯示結果(Matplotlib默認RGB,灰度圖直接顯示)
plt.figure(figsize=(15, 10))# 圖像顯示
plt.subplot(2, 3, 1)
plt.imshow(img, cmap="gray")
plt.title("原圖")
plt.axis("off")plt.subplot(2, 3, 2)
plt.imshow(global_eq, cmap="gray")
plt.title("全局直方圖均衡化")
plt.axis("off")plt.subplot(2, 3, 3)
plt.imshow(clahe_eq, cmap="gray")
plt.title("CLAHE(自適應均衡化)")
plt.axis("off")# 直方圖顯示
plt.subplot(2, 3, 4)
plt.plot(hist_original, color="black")
plt.title("原圖直方圖")
plt.xlabel("灰度值")
plt.ylabel("概率密度")plt.subplot(2, 3, 5)
plt.plot(hist_global, color="black")
plt.title("全局均衡化直方圖")
plt.xlabel("灰度值")plt.subplot(2, 3, 6)
plt.plot(hist_clahe, color="black")
plt.title("CLAHE直方圖")
plt.xlabel("灰度值")plt.tight_layout()
plt.show()
結果分析:
- 全局均衡化:整體對比度提升,但可能導致局部過亮(如天空區域泛白);
- CLAHE:通過分塊均衡化,在提升暗區細節(如建筑陰影)的同時,避免過增強,效果更自然。
案例2:中值濾波(消除椒鹽噪聲)
需求:去除圖像中的椒鹽噪聲(隨機黑白斑點),對比原圖與去噪后的效果。
實現步驟:
- 加載灰度圖并手動添加椒鹽噪聲(模擬真實噪聲場景);
- 用中值濾波處理噪聲圖像;
- 對比原圖、噪聲圖、去噪圖。
代碼:
import cv2
import numpy as np
import matplotlib.pyplot as plt# 1. 加載灰度圖像
img = cv2.imread("lena.jpg", 0) # 替換為你的圖像路徑(如經典Lena圖)
if img is None:raise ValueError("圖像加載失敗,請檢查路徑是否正確!")# 2. 手動添加椒鹽噪聲(噪聲比例:10%)
def add_salt_pepper_noise(image, noise_ratio=0.1):h, w = image.shapenoise_img = image.copy()# 計算噪聲像素數量noise_pixels = int(h * w * noise_ratio)# 添加鹽噪聲(白色斑點,灰度255)for _ in range(noise_pixels // 2):x = np.random.randint(0, w)y = np.random.randint(0, h)noise_img[y, x] = 255# 添加椒噪聲(黑色斑點,灰度0)for _ in range(noise_pixels // 2):x = np.random.randint(0, w)y = np.random.randint(0, h)noise_img[y, x] = 0return noise_imgnoise_img = add_salt_pepper_noise(img, noise_ratio=0.1)# 3. 中值濾波處理(核大小為3x3,需為奇數)
median_filtered = cv2.medianBlur(noise_img, ksize=3) # ksize可調整為5、7(核越大去噪越強,但細節越模糊)# 4. 顯示結果
plt.figure(figsize=(12, 4))plt.subplot(1, 3, 1)
plt.imshow(img, cmap="gray")
plt.title("原圖")
plt.axis("off")plt.subplot(1, 3, 2)
plt.imshow(noise_img, cmap="gray")
plt.title("添加椒鹽噪聲(10%)")
plt.axis("off")plt.subplot(1, 3, 3)
plt.imshow(median_filtered, cmap="gray")
plt.title("中值濾波(3x3核)")
plt.axis("off")plt.tight_layout()
plt.show()
結果分析:
- 噪聲圖:出現明顯的黑白斑點(椒鹽噪聲),細節被掩蓋;
- 中值濾波后:大部分噪聲被消除,圖像細節(如面部輪廓、眼睛)保留較好,這是因為中值對脈沖噪聲的抑制效果優于均值濾波。
三、總結
圖像預處理算法的選擇需結合具體任務和圖像問題:
- 若圖像對比度低:優先用CLAHE(優于全局均衡化);
- 若圖像有椒鹽噪聲:優先用中值濾波(核大小根據噪聲強度調整);
- 若需統一圖像尺寸:用縮放(雙線性插值);
- 若需分離亮度與色彩:將RGB轉為HSV或YCrCb。
上述實現的2個算法是工業界最常用的預處理步驟,可直接集成到目標檢測、圖像分割等 pipeline 中,提升后續模型的精度。