OpenCV濾波算法詳解
目錄
- 線性濾波算法
- 非線性濾波算法
- 邊緣檢測和梯度算子
- 形態學操作
- 實際應用示例
- 選擇指南
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),建議值為975: 顏色空間標準差 (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-8eps: 正則化參數 (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_16S1: X方向導數階數 (int dx),必須是10: 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_32F3: 濾波核大小 (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_OPEN、MORPH_CLOSE、MORPH_GRADIENT、MORPH_TOPHAT、MORPH_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),默認為0borderType: 邊界類型 (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.0beta: 偏移值 (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_CROSSksize: 結構元素大小 (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|)
三個操作步驟:
- 縮放:
src * alpha - 偏移:
+ beta - 取絕對值:
|...| - 類型轉換: 轉為8位無符號整數 (0-255)
這個函數在處理Sobel、Laplacian等算子結果時特別有用,因為這些算子輸出的是有符號的16位整數,包含正值和負值,需要轉換為0-255範圍才能正常顯示。
這些濾波器各有特點,選擇時需要考慮噪聲類型、處理目標、計算效率等因素。