canny邊緣檢測演算法是一種比較常見且效果較好的邊緣檢測演算法,其優點在於得到的邊緣為單畫素邊緣,但是速度較sobel等邊緣檢測演算法較慢。網上canny演算法的演算法介紹很多,此處不仔細寫了,主要分為五步,分別是:高斯去噪,梯度計算、梯度方向計算、非極大值抑制和雙閾值邊緣抑制。其中,非極大值抑制保證了邊緣檢測結果為單畫素邊緣,雙閾值邊緣抑制的作用為去掉孤立的低閾值邊緣。以下**為canny運算元的簡單實現,其中包含了sobel運算元的實現和高斯去噪的簡單版本。
高斯去噪:
cv::mat gaussblur(__in__ const cv::mat& src)
} for (int i = 1; i < row - 1; ++i)
} return des;
}
sobel運算元:
cv::mat sobeloperator(__in__ const cv::mat& src, __out__ cv::mat& gx, __out__ cv::mat& gy)
} return des;
}
canny運算元:
cv::mat cannyedgedetector(__in__ const cv::mat& src, __in__ const float up, __in__ const float down)
} uint max_pixel_value = 0;
cv::mat non_max = g.clone();
//step 4: non-maximum suppression
for (int i = 1; i < row - 1; ++i)
else if (angle >= 22.5 && angle < 67.5)
else if (angle >= 67.5 && angle < 112.5)
else if (angle >= 112.5 && angle < 157.5)
else *pnew = *pdata;
if (max_pixel_value < *pdata)max_pixel_value = *pdata;
} }cv::mat result(row, col, cv_8uc1, cv::scalar(0));
//step 5: hysteresis thresholding using two thresholds
uint* account = new uint[max_pixel_value + 1]();
for (int i = 1; i < row - 1; ++i)
} //chack the thresholds' legality
if (up < down)
if (up > 1)
if (down < 0)
int all = (row - 2) * (col - 2) - account[0];
const int up_account = all * up;
const int down_account = all * down;
int up_num, down_num;
while (all > up_account)
up_num = ++max_pixel_value;
while (all > down_account)
down_num = ++max_pixel_value;
for (int i = 1; i < row - 1; ++i)
} for (int i = 1; i < row - 1; ++i)
} }return result;
}
使用這段**需要#include , 其中涉及了一段異常丟擲,各位看官可以直接刪除掉那段**,或者直接用c++的exception。
需要注意幾個坑:
第一:sobel運算元的計算結果並非cv_8uc1
第二:注意atan2的計算,不要把gx和gy搞反
第三,非極大值抑制的時候不要在g的原圖上改,否則畫出來的邊緣和素描一樣,並非單邊緣
第四,opencv裡面的雙閾值為畫素具體值,而本程式裡面用的是百分比,測試中使用的值up為0.93, down為0.9,效果還可以。
此外,非極大值抑制部分有另乙個版本的形式,下面為另乙個版本,對比來看,前乙個版本應該更好用一點
//step 4: non-maximum suppression
for (int i = 1; i < row - 1; ++i)
else if (th <= 90.0)
else if (th <= 135.0)
else
if (max_pixel_value < *pdata)max_pixel_value = *pdata;
} }
Canny邊緣檢測
1.canny邊緣檢測基本原理 1 圖象邊緣檢測必須滿足兩個條件 一能有效地抑制雜訊 二必須盡量精確確定邊緣的位置。2 根據對訊雜比與定位乘積進行測度,得到最優化逼近運算元。這就是canny邊緣檢測運算元。3 類似與marr log 邊緣檢測方法,也屬於先平滑後求導數的方法。2.canny邊緣檢測演...
Canny邊緣檢測
canny運算元是邊緣檢測運算元中最常用的一種,是公認效能優良的一種運算元,常被其它邊緣檢測運算元作為標準運算元進行優劣分析。canny演算法基本可以分為3個步驟 平滑 梯度計算 基於梯度值及梯度方向的候選點過濾 1 平滑 影象梯度的計算對雜訊很敏感,因此必須首先對其進行低通濾波。在這裡使用5 5的...
Canny邊緣檢測
canny邊緣檢測是一種非常流行的邊緣檢測演算法,是john canny在1986年提出的。它是乙個多階段的演算法,即由多個步驟構成。1.影象降噪 2.計算影象梯度 3.非極大值抑制 4.閾值篩選 我們就事後諸葛亮,分析下這個步驟的緣由。首先,影象降噪。我們知道梯度運算元可以用於增強影象,本質上是通...