Canny邊緣檢測的c OpenCV實現

2021-09-04 12:18:17 字數 2419 閱讀 9162

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.閾值篩選 我們就事後諸葛亮,分析下這個步驟的緣由。首先,影象降噪。我們知道梯度運算元可以用於增強影象,本質上是通...