Opencv--Canny邊緣檢測器
阿新 • • 發佈:2018-12-12
目標
- 使用OpenCV函式cv :: Canny來實現Canny Edge Detector。
理論
該Canny邊緣檢測是由約翰·F·坎尼在1986年也知道很多的開發最佳的檢測,坎尼演算法旨在滿足三個主要標準:
- 低錯誤率:意味著只有現有邊緣的良好檢測。
- 良好的定位:檢測到的邊緣畫素與實際邊緣畫素之間的距離必須最小化。
- 最小響應:每個邊緣只有一個檢測器響應。
步驟
- 濾除任何噪音。高斯濾波器用於此目的。可能使用的的高斯核心的示例如下所示:size=5
- 找到影象的強度梯度。為此,我們遵循類似於Sobel的程式:
應用一對卷積面罩 (在 x 和 y directions:
查詢梯度強度和方向:
方向四捨五入為四個可能的角度之一(即0,45,90或135)
- 應用非最大抑制。這將刪除不被認為是邊緣的一部分的畫素。因此,只有細線(候選邊)將保留。
- 滯後:最後一步。Canny確實使用兩個閾值(上限和下限):
- 如果畫素梯度高於上限閾值,則畫素被接受為邊緣
- 如果畫素梯度值低於較低閾值,則會被拒絕。
- 如果畫素梯度在兩個閾值之間,那麼只有當它連線到高於上限閾值的畫素時才被接受。
Canny推薦上限:2:1和3:1之間的較低比例。
- 有關更多詳細資訊,您可以隨時諮詢您最喜愛的Computer Vision書籍。
Code
- 這個程式是做什麼的?
- 要求使用者輸入數值以設定我們的Canny Edge Detector的下限(通過Trackbar)。
- 應用Canny Detector並生成一個蒙版(亮線表示黑色背景上的邊緣)。
- 應用在原始影象上獲得的蒙版,並將其顯示在視窗中。
- 程式碼如下:
#include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespace cv; Mat src, gray_src, dst; int t1_value = 50; int max_value = 255; const char* OUTPUT_TITLE = "Canny Result"; void Canny_Demo(int, void*); int main(int argc, char** argv) { src = imread("C:/usr/opencv-test/Testpictures/sight.jpg"); if (!src.data) { printf("could not load image...\n"); return -1; } char INPUT_TITLE[] = "input image"; namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE); namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE); imshow(INPUT_TITLE, src); cvtColor(src, gray_src, CV_BGR2GRAY); createTrackbar("Threshold Value:", OUTPUT_TITLE, &t1_value, max_value, Canny_Demo); Canny_Demo(0, 0); waitKey(0); return 0; } void Canny_Demo(int, void*) { Mat edge_output; blur(gray_src, gray_src, Size(3, 3), Point(-1, -1), BORDER_DEFAULT); Canny(gray_src, edge_output, t1_value, t1_value * 3, 3, false);//false表用L1,即G(s) = |G(x)|+|G(y)| dst.create(src.size(), src.type()); src.copyTo(dst, edge_output); // (edge_output, edge_output); imshow(OUTPUT_TITLE, edge_output); }
說明
請注意以下事項:
- 我們建立一個較低的上限閾值3:1(與可變比率)的比率。
- 我們設定核心大小為(Sobel操作由Canny函式內部執行)。3
- 我們為的下限閾值設定最大值。100
- 載入源影象:
- 建立一個相同型別和大小的src(為dst)的矩陣:
cvtColor(src,src_gray,COLOR_BGR2GRAY);
- 建立一個視窗來顯示結果:
- 建立一個跟蹤欄,供使用者輸入Canny檢測器的下限:
createTrackbar("Threshold Value:", OUTPUT_TITLE, &t1_value, max_value, Canny_Demo);
觀察以下內容:
- Trackbar要控制的變數是lowThreshold,最大值為max_lowThreshold(我們先前設定為100)
- 每次Trackbar註冊一個動作時,將呼叫回撥函式CannyThreshold。
- 讓我們檢查CannyThreshold函式,一步一步:
- 首先,我們用核心大小為3的過濾器模糊影象:
-
blur(gray_src, gray_src, Size(3, 3), Point(-1, -1), BORDER_DEFAULT);
- 然後,我們應用OpenCV函式cv :: Canny:
Canny(gray_src, edge_output, t1_value, t1_value * 3, 3, false);
其中的解釋:
-
- detected_edges:源影象,灰度
- detected_edges:檢測器的輸出(可以與輸入相同)
- lowThreshold:使用者移動軌跡欄輸入的值
- highThreshold:在程式中設定為下限閾值的三倍(在Canny的建議之後)
- kernel_size:我們將它定義為3(要在內部使用的Sobel核心的大小)
結果
- 在編譯上面的程式碼之後,我們可以執行它作為引數作為影象的路徑。例如,使用以下影象作為輸入:
- 移動滑塊,嘗試不同的閾值,我們得到以下結果:
- 注意影象如何與邊緣區域上的黑色背景疊加。