OpenCV(十七)边缘检测3 -- Canny算子(最优边缘检测)
目錄
一、基礎理論
1、作用及介紹
1、原理
2、過程
3、Canny函數
二、回調函數及總代碼
效果
參考資料
???????
一、基礎理論
1、作用及介紹
Canny邊緣檢測是非常流行的邊緣檢測算法,被認為是最優的邊緣檢測算法。
1、原理
首先在x和y方向求一階導數,然后組合為4個方向的導數,這些方向導數達到局部最大值的點就是組成邊緣的候選點。
優點:分別用兩種不同的閾值檢測強邊緣和弱邊緣。(當且僅當強邊緣與弱邊緣相連時,才將若邊緣輸出到圖像中)
2、過程
四步法:
第一步,圖像降噪。高斯濾波。
第二步,計算圖像梯度,sobel算子,計算梯度大小和方向。
梯度方向總是與邊緣垂直,梯度方向有四類:垂直、水平、兩個對角線方向。
第三步,非極大值抑制(保留極大值)。利用梯度方向像素判斷是否為邊界點,去除非邊界點。(邊緣變“瘦”)
第四步,雙閾值篩選(保留極大值)。設置兩個閾值,確定最終邊界。
現在要確定真正的邊界。我們設置兩個閾值: minVal和 maxVal。當圖像的灰度梯度高于maxVal時被認為是真的邊界,低于minVal的邊界會被拋棄。如果介于兩者之間的話,就要看這個點是否與某個被確定為真正的邊界點相連,如果是就認為它也是邊界點,如果不是就拋棄。(和極大值相連則保留)如下圖:A和C視為邊界,B不視為邊界。
3、Canny函數
void Canny(InputArray image,OutputArray edges, double threshold1, double threshold2, int apertureSize=3,bool L2gradient=false )InputArray類型的image,輸入圖像,即源圖像,填Mat類的對象即可,且需為單通道8位圖像。
OutputArray類型的edges,輸出的邊緣圖,需要和源圖片有一樣的尺寸和類型。
double類型的threshold1,第一個滯后性閾值【低閾值】。值越大,找到的邊緣越少
double類型的threshold2,第二個滯后性閾值【高閾值】。
int類型的apertureSize,表示應用Sobel算子的孔徑大小,其有默認值3。
bool類型的L2gradient,一個計算圖像梯度幅值的標識,有默認值false。C++:
Canny(src, dst, 100, 255, 3); //Canny函數// 低閾值 高閾值 sobel算子孔徑大小?python:
dst = cv.Canny(img, 100, 255)# 低閾值 高閾值
Canny算子處理:?
C++:
//Canny邊緣檢測
void Canny()
{Canny(src, dst, 100, 255, 3); //Canny函數// 低閾值 高閾值 sobel算子孔徑大小imshow(window, dst);
}
?python:
# Canny最優微分算子
def Canny():dst = cv.Canny(img, 100, 255)# 低閾值 高閾值cv.imshow("dst", dst)
?
二、回調函數及總代碼
C++:
//Canny算子回調函數(參數可調)
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp> using namespace cv;
using namespace std;Mat src, dst, gray;
string window = "Canny";
int Min = 50, Max = 200; //初始參數void Callback_Canny_Min(int, void*); //Canny算子回調函數
void Callback_Canny_Max(int, void*);//圖片初始化
void Image_Init()
{src = imread("Resource/test17.jpg");imshow("原圖", src);
}//Canny邊緣檢測
void Canny()
{Canny(src, dst, 100, 255, 3); //Canny函數// 低閾值 高閾值 sobel算子孔徑大小imshow(window, dst);
}int main()
{Image_Init(); //圖片初始化//先第一次顯示(Canny)Canny();//回調函數createTrackbar("min:", window, &Min, 255, Callback_Canny_Min);createTrackbar("max:", window, &Max, 255, Callback_Canny_Max);waitKey(0);return 0;
}//Canny回調函數
void Callback_Canny_Min(int, void*)
{Canny();
}//Canny回調函數
void Callback_Canny_Max(int, void*)
{Canny();
}
python:
# 邊緣檢測(Sobel、Laplace、Canny)
import cv2 as cv# Canny最優微分算子
def Canny():dst = cv.Canny(img, 100, 255)# 低閾值 高閾值cv.imshow("dst", dst)if __name__ == '__main__':# 讀取圖片img = cv.imread("Resource/test5.jpg")cv.imshow("img", img)# Sobel() #Sobel一階微分算子# Laplace() #Laplace二階微分算子Canny() #Canny最優微分算子cv.waitKey(0)
效果
參考資料
https://www.bilibili.com/video/BV1Fo4y1d7JL?p=34&spm_id_from=pageDriver
總結
以上是生活随笔為你收集整理的OpenCV(十七)边缘检测3 -- Canny算子(最优边缘检测)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV(十八)霍夫变换(直线、线段
- 下一篇: OpenCV(十九)直方图(直方图计算、