OpenCV濾波算法詳解

目錄

  1. 線性濾波算法
  2. 非線性濾波算法
  3. 邊緣檢測和梯度算子
  4. 形態學操作
  5. 實際應用示例
  6. 選擇指南

1. 線性濾波算法

1.1 均值濾波 (Blur/Average Filter)

cv::blur(image, result, cv::Size(3, 3));

參數説明:

  • image: 輸入圖像 (InputArray)
  • result: 輸出圖像 (OutputArray)
  • cv::Size(3, 3): 濾波核大小 (Size),必須是奇數

作用: 用鄰域像素的平均值替換中心像素

特點:

  • 簡單快速
  • 能有效去除高斯噪聲
  • 會模糊邊緣
  • 所有權重相等

卷積核:

1/9 * [1 1 1]
      [1 1 1]
      [1 1 1]

1.2 高斯濾波 (Gaussian Filter)

cv::GaussianBlur(image, result, cv::Size(5, 5), 1.5);

參數説明:

  • image: 輸入圖像 (InputArray)
  • result: 輸出圖像 (OutputArray)
  • cv::Size(5, 5): 濾波核大小 (Size),寬度和高度必須是奇數
  • 1.5: 高斯核的標準差 (double sigmaX),設為0時自動計算
  • 可選參數: sigmaY (Y方向標準差,默認等於sigmaX)
  • 可選參數: borderType (邊界類型,默認為BORDER_DEFAULT)

作用: 使用高斯分佈進行加權平均

特點:

  • 中心像素權重最大,距離越遠權重越小
  • 去噪效果好,邊緣保持較好
  • 符合人眼視覺特性
  • 可分離濾波器,計算效率高

5×5高斯核:

1/273 * [ 1  4  7  4  1]
        [ 4 16 26 16  4]
        [ 7 26 41 26  7]
        [ 4 16 26 16  4]
        [ 1  4  7  4  1]

1.3 方框濾波 (Box Filter)

cv::boxFilter(image, result, -1, cv::Size(3, 3));

參數説明:

  • image: 輸入圖像 (InputArray)
  • result: 輸出圖像 (OutputArray)
  • -1: 輸出圖像深度 (int ddepth),-1表示與輸入相同
  • cv::Size(3, 3): 濾波核大小 (Size)
  • 可選參數: anchor (錨點位置,默認為Point(-1,-1)表示中心)
  • 可選參數: normalize (是否歸一化,默認為true)
  • 可選參數: borderType (邊界類型)

作用: 類似均值濾波,但不進行歸一化

特點:

  • 可以選擇是否歸一化
  • 適合積分圖計算

2. 非線性濾波算法

2.1 中值濾波 (Median Filter)

cv::medianBlur(image, result, 3);

參數説明:

  • image: 輸入圖像 (InputArray),可以是1、3或4通道圖像
  • result: 輸出圖像 (OutputArray),與輸入圖像大小和類型相同
  • 3: 濾波核大小 (int ksize),必須是大於1的奇數,如3、5、7等

作用: 用鄰域像素的中值替換中心像素

特點:

  • 對椒鹽噪聲非常有效
  • 能保持邊緣清晰
  • 不會產生新像素值
  • 計算量較大

2.2 雙邊濾波 (Bilateral Filter)

cv::bilateralFilter(image, result, 9, 75, 75);

參數説明:

  • image: 輸入圖像 (InputArray),必須是8位整數或浮點數
  • result: 輸出圖像 (OutputArray),與輸入圖像大小和類型相同
  • 9: 像素鄰域直徑 (int d),建議值為9
  • 75: 顏色空間標準差 (double sigmaColor),值越大混合越多顏色
  • 75: 座標空間標準差 (double sigmaSpace),值越大影響越遠的像素

作用: 保邊去噪濾波器

特點:

  • 同時考慮空間距離和像素值相似性
  • 能保持邊緣鋭利
  • 計算複雜度高
  • 美顏濾鏡的基礎

2.3 導向濾波 (Guided Filter)

cv::ximgproc::guidedFilter(guide, src, dst, radius, eps);

參數説明:

  • guide: 引導圖像 (InputArray),用於指導濾波過程
  • src: 待濾波圖像 (InputArray)
  • dst: 輸出圖像 (OutputArray)
  • radius: 濾波半徑 (int),通常取值為2-8
  • eps: 正則化參數 (double),控制濾波強度,值越大平滑效果越強
  • 可選參數: dDepth (輸出圖像深度,默認為-1表示與輸入相同)

作用: 使用引導圖進行濾波

特點:

  • 比雙邊濾波速度快
  • 邊緣保持效果好
  • 可用於HDR、去霧等

3. 邊緣檢測和梯度算子

3.1 Sobel算子

cv::Sobel(image, sobel_x, CV_16S, 1, 0, 3); // 水平方向
cv::Sobel(image, sobel_y, CV_16S, 0, 1, 3); // 垂直方向

參數説明:

  • image: 輸入圖像 (InputArray)
  • sobel_x/sobel_y: 輸出圖像 (OutputArray)
  • CV_16S: 輸出圖像深度 (int ddepth),常用CV_16S避免梯度溢出
  • 1/0: X方向導數階數 (int dx),1表示計算X方向梯度,0表示不計算
  • 0/1: Y方向導數階數 (int dy),1表示計算Y方向梯度,0表示不計算
  • 3: 濾波核大小 (int ksize),必須是1、3、5或7,推薦3
  • 可選參數: scale (縮放因子,默認為1)
  • 可選參數: delta (偏移值,默認為0)
  • 可選參數: borderType (邊界類型)

作用: 計算圖像梯度

特點:

  • 一階導數算子
  • 對噪聲敏感
  • 可檢測水平和垂直邊緣

3×3 Sobel核:

水平: [-1 0 1]  垂直: [-1 -2 -1]
       [-2 0 2]        [ 0  0  0]
       [-1 0 1]        [ 1  2  1]

3.2 Scharr算子

cv::Scharr(image, scharr_x, CV_16S, 1, 0);

參數説明:

  • image: 輸入圖像 (InputArray)
  • scharr_x: 輸出圖像 (OutputArray)
  • CV_16S: 輸出圖像深度 (int ddepth),常用CV_16S
  • 1: X方向導數階數 (int dx),必須是1
  • 0: Y方向導數階數 (int dy),必須是0
  • 可選參數: scale (縮放因子,默認為1)
  • 可選參數: delta (偏移值,默認為0)
  • 可選參數: borderType (邊界類型)

注意: Scharr算子只能計算單個方向的梯度,需要分別調用計算X和Y方向

作用: Sobel算子的改進版本

特點:

  • 梯度檢測更準確
  • 旋轉不變性更好
  • 適合小核

3.3 Laplacian算子

cv::Laplacian(image, laplacian, CV_16S, 3);

參數説明:

  • image: 輸入圖像 (InputArray)
  • laplacian: 輸出圖像 (OutputArray)
  • CV_16S: 輸出圖像深度 (int ddepth),推薦CV_16S或CV_32F
  • 3: 濾波核大小 (int ksize),必須是1、3、5或7
  • 可選參數: scale (縮放因子,默認為1)
  • 可選參數: delta (偏移值,默認為0)
  • 可選參數: borderType (邊界類型)

作用: 二階導數算子

特點:

  • 對邊緣更敏感
  • 對噪聲更敏感
  • 各向同性

Laplacian核:

[ 0  1  0]  或  [ 1  1  1]
[ 1 -4  1]      [ 1 -8  1]
[ 0  1  0]      [ 1  1  1]

3.4 Canny邊緣檢測

cv::Canny(image, edges, 50, 150);

參數説明:

  • image: 輸入圖像 (InputArray),必須是單通道8位圖像
  • edges: 輸出邊緣圖像 (OutputArray),單通道二值圖像
  • 50: 低閾值 (double threshold1),用於邊緣連接
  • 150: 高閾值 (double threshold2),用於強邊緣檢測
  • 可選參數: apertureSize (Sobel算子核大小,默認為3)
  • 可選參數: L2gradient (是否使用L2梯度,默認為false使用L1梯度)

閾值説明:

  • 像素梯度 > 高閾值 → 強邊緣點
  • 低閾值 < 像素梯度 ≤ 高閾值 → 弱邊緣點
  • 像素梯度 ≤ 低閾值 → 被抑制

作用: 多步驟邊緣檢測算法

特點:

  • 使用高斯濾波去噪
  • 雙閾值檢測
  • 滯後閾值處理
  • 邊緣連接優化

4. 形態學操作

4.1 腐蝕 (Erosion)

cv::erode(image, result, kernel);

參數説明:

  • image: 輸入圖像 (InputArray),可以是任意通道數
  • result: 輸出圖像 (OutputArray),與輸入圖像大小和類型相同
  • kernel: 結構元素 (InputArray),定義腐蝕的形狀和大小
  • 可選參數: anchor (錨點位置,默認為Point(-1,-1)表示中心)
  • 可選參數: iterations (迭代次數,默認為1)
  • 可選參數: borderType (邊界類型)
  • 可選參數: borderValue (邊界值)

作用: 消除小的白色區域

特點:

  • 使物體邊界收縮
  • 去除孤立點
  • 斷開連接區域

4.2 膨脹 (Dilation)

cv::dilate(image, result, kernel);

參數説明:

  • image: 輸入圖像 (InputArray)
  • result: 輸出圖像 (OutputArray)
  • kernel: 結構元素 (InputArray)
  • 可選參數: anchor (錨點位置,默認為Point(-1,-1))
  • 可選參數: iterations (迭代次數,默認為1)
  • 可選參數: borderType (邊界類型)
  • 可選參數: borderValue (邊界值)

作用: 擴大白色區域

特點:

  • 使物體邊界擴張
  • 填充小空洞
  • 連接斷裂區域

4.3 開運算 (Opening)

cv::morphologyEx(image, result, cv::MORPH_OPEN, kernel);

參數説明:

  • image: 輸入圖像 (InputArray)
  • result: 輸出圖像 (OutputArray)
  • cv::MORPH_OPEN: 形態學操作類型 (int op)
  • kernel: 結構元素 (InputArray)
  • 可選參數: anchor (錨點位置)
  • 可選參數: iterations (迭代次數,默認為1)
  • 可選參數: borderType (邊界類型)

操作類型: MORPH_OPENMORPH_CLOSEMORPH_GRADIENTMORPH_TOPHATMORPH_BLACKHAT

公式: Result = Erode(Dilate(image))

作用: 去除噪聲,保持形狀

4.4 閉運算 (Closing)

cv::morphologyEx(image, result, cv::MORPH_CLOSE, kernel);

參數説明: 同開運算,只是操作類型為MORPH_CLOSE

公式: Result = Dilate(Erode(image))

作用: 填充小洞,連接鄰近物體

4.5 梯度 (Gradient)

cv::morphologyEx(image, result, cv::MORPH_GRADIENT, kernel);

參數説明: 同開運算,操作類型為MORPH_GRADIENT

公式: Result = Dilate(image) - Erode(image)

作用: 提取物體輪廓

4.6 頂帽 (Top Hat)

cv::morphologyEx(image, result, cv::MORPH_TOPHAT, kernel);

參數説明: 同開運算,操作類型為MORPH_TOPHAT

公式: Result = image - Opening(image)

作用: 提取比結構元素小的亮區域

4.7 黑帽 (Black Hat)

cv::morphologyEx(image, result, cv::MORPH_BLACKHAT, kernel);

參數説明: 同開運算,操作類型為MORPH_BLACKHAT

公式: Result = Closing(image) - image

作用: 提取比結構元素小的暗區域


5. 實際應用示例

5.1 去噪應用

// 高斯噪聲 - 使用高斯濾波
cv::GaussianBlur(noisy_image, denoised, cv::Size(5, 5), 1.5);

// 椒鹽噪聲 - 使用中值濾波
cv::medianBlur(noisy_image, denoised, 3);

// 保邊去噪 - 使用雙邊濾波
cv::bilateralFilter(noisy_image, denoised, 9, 75, 75);

5.2 邊緣檢測流程

// 完整的邊緣檢測流程
cv::Mat gray, blurred, edges;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
cv::GaussianBlur(gray, blurred, cv::Size(5, 5), 1.5);
cv::Canny(blurred, edges, 50, 150);

5.3 形態學應用

// 文字增強
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
cv::morphologyEx(binary_image, result, cv::MORPH_CLOSE, kernel);

// 噪聲去除
cv::morphologyEx(binary_image, result, cv::MORPH_OPEN, kernel);

5.4 自定義卷積核

// 鋭化濾波器
cv::Mat sharpen_kernel = (cv::Mat_<float>(3, 3) <<
    -1, -1, -1,
    -1,  9, -1,
    -1, -1, -1);
cv::filter2D(image, result, -1, sharpen_kernel);

//浮雕效果
cv::Mat emboss_kernel = (cv::Mat_<float>(3, 3) <<
    -2, -1,  0,
    -1,  1,  1,
     0,  1,  2);
cv::filter2D(image, result, -1, emboss_kernel);

// 水平邊緣檢測
cv::Mat horizontal_kernel = (cv::Mat_<float>(1, 3) << -1, 0, 1);
cv::filter2D(image, result, CV_32F, horizontal_kernel);

filter2D參數説明:

cv::filter2D(src, dst, ddepth, kernel, anchor, delta, borderType);
  • src: 輸入圖像 (InputArray)
  • dst: 輸出圖像 (OutputArray)
  • ddepth: 輸出圖像深度 (int),-1表示與輸入相同
  • kernel: 卷積核 (InputArray),單通道浮點矩陣
  • anchor: 錨點位置 (Point),默認為Point(-1,-1)表示核中心
  • delta: 偏移值 (double),默認為0
  • borderType: 邊界類型 (int),默認為BORDER_DEFAULT

5.5 convertScaleAbs的使用

// Sobel算子結果處理
cv::Mat sobel_x, sobel_x_abs;
cv::Sobel(image, sobel_x, CV_16S, 1, 0);           // 16位有符號
cv::convertScaleAbs(sobel_x, sobel_x_abs);          // 轉為8位無符號用於顯示

// 對比度和亮度調整
cv::Mat enhanced;
cv::convertScaleAbs(image, enhanced, 1.5, 50);      // alpha=1.5(對比度), beta=50(亮度)

// 等價於以下三步操作:
// cv::Mat temp = image * 1.5 + 50;
// temp = cv::abs(temp);
// temp.convertTo(enhanced, CV_8U);

convertScaleAbs參數説明:

cv::convertScaleAbs(src, dst, alpha, beta);
  • src: 輸入數組 (InputArray)
  • dst: 輸出數組 (OutputArray),8位無符號整數
  • alpha: 縮放因子 (double),默認為1.0
  • beta: 偏移值 (double),默認為0

5.6 結構元素創建

// 矩形結構元素
cv::Mat rect_kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

// 橢圓結構元素
cv::Mat ellipse_kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5));

// 十字形結構元素
cv::Mat cross_kernel = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3));

getStructuringElement參數説明:

cv::getStructuringElement(shape, ksize, anchor);
  • shape: 結構元素形狀 (int) - MORPH_RECT, MORPH_ELLIPSE, MORPH_CROSS
  • ksize: 結構元素大小 (Size)
  • anchor: 錨點位置 (Point),默認為Point(-1,-1)表示中心

6. 選擇指南

應用場景

推薦算法

原因

高斯噪聲

GaussianBlur

效果好,速度快

椒鹽噪聲

medianBlur

保持邊緣,去除斑點

保邊去噪

bilateralFilter

保持邊緣鋭利

邊緣檢測

Canny

完整的邊緣檢測流程

文字處理

形態學操作

連接斷筆,去除噪聲

圖像增強

filter2D+自定義核

靈活性高

梯度計算

Sobel/Scharr

一階導數,方向敏感

輪廓提取

morphological gradient

提取物體邊緣


核心概念理解

卷積的本質

通過卷積核在圖像上滑動,對局部區域進行加權求和,實現不同的圖像處理效果。

關鍵參數

  • 核大小: 影響處理強度和計算量
  • 核權重: 決定處理效果
  • 邊界處理: 常用補零或鏡像

性能考慮

  • 可分離核(如高斯)可優化計算
  • 大核計算量成指數增長
  • GPU可加速卷積運算

convertScaleAbs函數

void convertScaleAbs(InputArray src, OutputArray dst, double alpha = 1, double beta = 0)

功能: 對輸入數組進行縮放、絕對值、轉換為8位無符號整數的組合操作

數學公式: dst = saturate_cast<uchar>(|src * alpha + beta|)

三個操作步驟:

  1. 縮放: src * alpha
  2. 偏移: + beta
  3. 取絕對值: |...|
  4. 類型轉換: 轉為8位無符號整數 (0-255)

這個函數在處理Sobel、Laplacian等算子結果時特別有用,因為這些算子輸出的是有符號的16位整數,包含正值和負值,需要轉換為0-255範圍才能正常顯示。

這些濾波器各有特點,選擇時需要考慮噪聲類型、處理目標、計算效率等因素。