一、什麼是邊緣檢測?
邊緣檢測的基本思想是通過檢測每個像素和其鄰域的狀態,以決定該像素是否位於一個物體的邊界上。如果一個像素位於一個物體的邊界上,則其鄰域像素的灰度值的變化就比較大。假如可以應用某種算法檢測出這種變化並進行量化表示,那麼就可以確定物體的邊界。
經典的邊緣檢測方法是對原始圖像中像素的某小鄰域來構造邊緣檢測算子。常用的邊緣檢測方法有Roberts算子、Sobe l算子、Prew itt算子、K irsch算子、Laplacian算子、LOG 算子、Canny算子等。其中canny算子最爲常用,本文將重點介紹canny算子的運用。
二、邊緣檢測算法有如下四個步驟:
(1)濾波:邊緣檢測算法主要是基於圖像強度的一階和二階導數,但導數的計算對噪聲很敏感,因此必須使用濾波器來改善與噪聲有關的邊緣檢測器的性能.需要指出,大多數濾波器在降低噪聲的同時也導致了邊緣強度的損失,因此,增強邊緣和降低噪聲之間需要折衷.(2)增強:增強邊緣的基礎是確定圖像各點鄰域強度的變化值.增強算法可以將鄰域(或局部)強度值有顯著變化的點突顯出來.邊緣增強一般是通過計算梯度幅值來完成的.
(3)檢測:在圖像中有許多點的梯度幅值比較大,而這些點在特定的應用領域中並不都是邊緣,所以應該用某種方法來確定哪些點是邊緣點.最簡單的邊緣檢測判據是梯度幅值閾值判據.
(4)定位:如果某一應用場合要求確定邊緣位置,則邊緣的位置可在子像素分辨率上來估計,邊緣的方位也可以被估計出來.
在邊緣檢測算法中,前三個步驟用得十分普遍。這是因爲大多數場合下,僅僅需要邊緣檢測器指出邊緣出現在圖像某一像素點的附近,而沒有必要指出邊緣的精確位置或方向.邊緣檢測誤差通常是指邊緣誤分類誤差,即把假邊緣判別成邊緣而保留,而把真邊緣判別成假邊緣而去掉.邊緣估計誤差是用概率統計模型來描述邊緣的位置和方向誤差的.我們將邊緣檢測誤差和邊緣估計誤差區分開,是因爲它們的計算方法完全不同,其誤差模型也完全不同.
三、canny算子的數學算法原理
可參見:canny算子,canny算子相關文獻
四、Canny()原型
canny算子在OpenCV中已經被編寫爲函數Canny(),可直接調用,其原型如下:
void cv::Canny | ( | InputArray | image, //輸入圖像,要求爲灰度圖 |
OutputArray | edges, //canny檢測後的輸出圖像 | ||
double | threshold1, //閾值1,低閾值 | ||
double | threshold2, //閾值2,高閾值,低/高=比值1:2~1:3尤佳 | ||
int |
apertureSize = 3 ,
//Sobel算子的孔徑大小 |
||
bool |
L2gradient = false //計算梯度幅度值的標識,默認爲false |
||
) |
五、代碼示例
//Canny邊緣檢測練習
//2016.07.21
//頭文件和命名空間
#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
int main()
{
Mat srcImage = imread("grape.jpg");
Mat img = srcImage.clone();//原圖備份至img,用於後續的處理
imshow("【1】原圖", img);
Mat grayImage, addingImage, blurImage,canny_detection;
addingImage.create(img.size(), img.type());//創建於原圖大小和類型相同的矩陣
cvtColor(img, grayImage, COLOR_BGR2GRAY);//將待處理圖像轉換爲灰度圖
imshow("【2】灰度圖", grayImage);
blur(grayImage, blurImage, Size(7, 7));//均值濾波,降噪處理
imshow("【3】灰度圖+均值濾波", blurImage);
Canny(blurImage, canny_detection, 3, 9, 3);//邊緣檢測
imshow("【4】灰度圖+均值濾波+邊緣檢測", canny_detection);
addingImage = Scalar::all(0);//創建黑色畫布
img.copyTo(addingImage, canny_detection);//將備份圖和canny輸出的邊緣檢測圖疊加
imshow("【5】原圖和邊緣檢測疊加", addingImage);
waitKey(0);//按ESC可退出
return 0;
}
六、運行結果
============不同的參數取值,如濾波採用的內核,及canny的閾值對最終檢測效果影響較大============
***均值模糊採用3x3的內核,高低閾值分別爲3,9,其邊緣檢測效果:
***均值模糊採用7X7的內核,高低閾值分別爲3、9,其邊緣檢測效果:
***均值模糊採用7X7的內核,高低閾值分別爲40、90,其邊緣檢測效果:
邊緣檢測圖與原圖疊加後的效果圖: