1. 程式人生 > >影象邊緣檢測——canny運算元原理與程式碼

影象邊緣檢測——canny運算元原理與程式碼

轉自:http://blog.csdn.net/dcrmg/article/details/5234490

另有:http://blog.csdn.net/likezhaobin/article/details/6892629

            http://blog.csdn.net/ftxv95x5/article/details/55657534

            http://blog.csdn.net/tigerda/article/details/61192943        參考

常見邊緣檢測運算元:Roberts 、Sobel 、Prewitt、Laplacian、Log/Marr、Canny、Kirsch、Nevitia

一階微分運算元:Roberts 、Sobel 、Prewitt

     二階微分運算元:Laplacian、Log/Marr

            非微分邊緣檢測運算元:Canny


Canny邊緣檢測演算法是澳大利亞科學家John F. Canny在1986年提出來的,不得不提一下的是當年John Canny本人才28歲!到今天已經30年過去了,Canny演算法仍然是影象邊緣檢測演算法中最經典、有效的演算法之一。

一起睹一下大家Canny的風采:


John Canny研究了最優邊緣檢測方法所需的特性,給出了評價邊緣檢測效能優劣的3個指標:

  • 1  好的信噪比,即將非邊緣點判定為邊緣點的概率要低,將邊緣點判為非邊緣點的概率要低;
  • 2 高的定位效能,即檢測出的邊緣點要儘可能在實際邊緣的中心;
  • 3 對單一邊緣僅有唯一響應,即單個邊緣產生多個響應的概率要低,並且虛假響應邊緣應該得到最大抑制;
Canny演算法就是基於滿足這3個指標的最優解實現的,在對影象中物體邊緣敏感性的同時,也可以抑制或消除噪聲的影響。

Canny運算元邊緣檢測的具體步驟如下:

  • 一、用高斯濾波器平滑影象
  • 二、用Sobel等梯度運算元計算梯度幅值和方向
  • 三、對梯度幅值進行非極大值抑制
  • 四、用雙閾值演算法檢測和連線邊緣

一、用高斯濾波器平滑影象

高斯濾波是一種線性平滑濾波,適用於消除高斯噪聲,特別是對抑制或消除服從正態分佈的噪聲非常有效。濾波可以消除或降低影象中噪聲的影響,

使用高斯濾波器主要是基於在濾波降噪的同時也可以最大限度保留邊緣資訊的考慮。

高斯濾波實現步驟:

1.1  彩色RGB影象轉換為灰度影象

邊緣檢測是基於對影象灰度差異運算實現的,所以如果輸入的是RGB彩色影象,需要先進行灰度圖的轉換。 RGB轉換成灰度影象的一個常用公式是: Gray = R*0.299 + G*0.587 + B*0.114 C++程式碼實現起來也比較簡單,注意一般情況下影象處理中彩色影象各分量的排列順序是B、G、R [cpp] view plain copy  print?
  1. //******************灰度轉換函式*************************
  2. //第一個引數image輸入的彩色RGB影象;
  3. //第二個引數imageGray是轉換後輸出的灰度影象;
  4. //*************************************************************
  5. void ConvertRGB2GRAY(const Mat &image,Mat &imageGray)  
  6. {  
  7.     if(!image.data||image.channels()!=3)  
  8.     {  
  9.         return ;  
  10.     }  
  11.     imageGray=Mat::zeros(image.size(),CV_8UC1);  
  12.     uchar *pointImage=image.data;  
  13.     uchar *pointImageGray=imageGray.data;  
  14.     int stepImage=image.step;  
  15.     int stepImageGray=imageGray.step;  
  16.     for(int i=0;i<imageGray.rows;i++)  
  17.     {  
  18.         for(int j=0;j<imageGray.cols;j++)  
  19.         {  
  20.             pointImageGray[i*stepImageGray+j]=0.114*pointImage[i*stepImage+3*j]+0.587*pointImage[i*stepImage+3*j+1]+0.299*pointImage[i*stepImage+3*j+2];  
  21.         }  
  22.     }  
  23. }  
RGB原影象:                                                                 轉換後的灰度圖:                                              

1.2 生成高斯濾波卷積核

高斯濾波的過程是將灰度影象跟高斯卷積核卷積,所以第一步是先要求解出給定尺寸和Sigma的高斯卷積核引數,以下程式碼實現對卷積核引數求解: [cpp] view plain copy  print?
  1. //******************高斯卷積核生成函式*************************
  2. //第一個引數gaus是一個指向含有N個double型別陣列的指標;
  3. //第二個引數size是高斯卷積核的尺寸大小;
  4. //第三個引數sigma是卷積核的標準差
  5. //*************************************************************
  6. void GetGaussianKernel(double **gaus, constint size,constdouble sigma)  
  7. {  
  8.     constdouble PI=4.0*atan(1.0); //圓周率π賦值
  9.     int center=size/2;  
  10.     double sum=0;  
  11.     for(int i=0;i<size;i++)  
  12.     {  
  13.         for(int j=0;j<size;j++)  
  14.         {  
  15.             gaus[i][j]=(1/(2*PI*sigma*sigma))*exp(-((i-center)*(i-center)+(j-center)*(j-center))/(2*sigma*sigma));  
  16.             sum+=gaus[i][j];  
  17.         }  
  18.     }  
  19.     for(int i=0;i<size;i++)  
  20.     {  
  21.         for(int j=0;j<size;j++)  
  22.         {  
  23.             gaus[i][j]/=sum;  
  24.             cout<<gaus[i][j]<<"  ";  
  25.         }  
  26.         cout<<endl<<endl;  
  27.     }  
  28.     return ;  
  29. }  
Sigma為1時,求得的3*3大小的高斯卷積核引數為:

Sigma為1,5*5大小的高斯卷積核引數為:
以下運算中Canny運算元使用的是尺寸5*5,Sigma為1的高斯核。

1.3  高斯濾波

用在1.2中生成的高斯卷積核跟灰度影象卷積,得到灰度影象的高斯濾波後的影象,抑制噪聲。 程式碼實現: [cpp] view plain copy  print?
  1. //******************高斯濾波*************************
  2. //第一個引數imageSource是待濾波原始影象;
  3. //第二個引數imageGaussian是濾波後輸出影象;
  4. //第三個引數gaus是一個指向含有N個double型別陣列的指標;
  5. //第四個引數size是濾波核的尺寸
  6. //*************************************************************
  7. void GaussianFilter(const Mat imageSource,Mat &imageGaussian,double **gaus,int size)  
  8. {  
  9.     imageGaussian=Mat::zeros(imageSource.size(),CV_8UC1);  
  10.     if(!imageSource.data||imageSource.channels()!=1)  
  11.     {  
  12.         return ;  
  13.     }  
  14.     double gausArray[100];   
  15.     for(int i=0;i<size*size;i++)  
  16.     {  
  17.         gausArray[i]=0;  //賦初值,空間分配
  18.     }  
  19.     int array=0;  
  20.     for(int i=0;i<size;i++)  
  21.     {  
  22.         for(int j=0;j<size;j++)  
  23.         {  
  24.             gausArray[array]=gaus[i][j];//二維陣列到一維 方便計算
  25.             array++;  
  26.         }  
  27.     }  
  28.     //濾波
  29.     for(int i=0;i<imageSource.rows;i++)  
  30.     {  
  31.         for(int j=0;j<imageSource.cols;j++)  
  32.         {  
  33. 相關推薦

    影象邊緣檢測——canny運算元原理程式碼

    轉自:http://blog.csdn.net/dcrmg/article/details/5234490 另有:http://blog.csdn.net/likezhaobin/article/details/6892629             http:/

    邊緣檢測---Canny運算元

    http://www.cnblogs.com/techyan1990/p/7291771.html 1.Canny邊緣檢測演算法可以分為以下5個步驟: 1)        使用高斯濾波器,以平滑影象,濾除噪聲。 2)&

    5.4.3 邊緣檢測-canny運算元

    Canny運算元是John Canny於20世紀80年代提出的一種多級邊緣檢測演算法。John Canny研究了最優邊緣的特性,即檢測到的邊緣要儘可能跟實際的邊緣接近並儘可能的多,同時,要儘量降低噪聲對邊緣檢測的干擾。其計算步驟如下 1)對源影象進行高斯平滑以消除影象中噪聲 2)採用差分法近似計

    OpenCV3邊緣檢測:Canny運算元/Sobel運算元/Laplace運算元/Scharr濾波器

    邊緣檢測的一般步驟 1)濾波:邊緣檢測的演算法主要是基於影象強度的一階和二階導數,但導數通常對噪聲很敏感,因此必須採用濾波器來改善與噪聲有關的邊緣檢測器的效能。常見的濾波方法主要有高斯濾波,即採用離散化的高斯函式產生一組歸一化的高斯核(具體見“高斯濾波原理及其程式設計離散化實現方法”

    【OpenCV入門教程之十二】OpenCV邊緣檢測 Canny運算元 Sobel運算元 Laplace運算元 Scharr濾波

                    本篇文章中,我們將一起學習OpenCV中邊緣檢測的各種運算元和濾波器——Canny運算元,Sobel運算元,Laplace運算元以及Scharr濾波器。文章中包含了五個淺墨為大家準備的詳細註釋的博文配套原始碼。在介紹四塊知識點的時候分別一個,以及最後的綜合示例中的一個。文章末尾

    影象邊緣檢測—sobel運算元(灰度影象,彩色影象

    void CShowPicView::Ontwodimension() { CShowPicDoc* pDoc = GetDocument(); CDC* pDC=GetDC(); // 字串 CString str; int x,y; int i,n; x=intHeight; y=int

    影象邊緣檢測經典運算元及MATLAB實現

    一、邊緣檢測 邊緣是圖象最基本的特徵. 邊緣檢測在計算機視覺、圖象分析等應用中起著重要的作用,是圖象分析與識別的重要環節,這是因為子圖象的邊緣包含了用於識別的有用資訊. 所以邊緣檢測是影象分析和模式識別的主要特徵提取手段。所謂邊緣是指其周圍畫素灰度後階變化或屋頂狀變化的

    梯度邊緣檢測常用運算元:Roberts、Prewitt、Sobel、LOG,Canny、Lapacian運算元

    原文:https://blog.csdn.net/swj110119/article/details/51777422 原文:https://blog.csdn.net/gdut2015go/article/details/46779251 幾種邊緣檢測運算元的比較Robert

    Canny邊緣檢測算法原理及其VC實現詳解(一)

    常用 差分 實現圖 還需要 鏈接 傳感器 出了 關系 位置 轉自:http://blog.csdn.net/likezhaobin/article/details/6892176 圖象的邊緣是指圖象局部區域亮度變化顯著的部分,該區域的灰度剖面一般可以看作是一個階躍,既從

    0032-使用OpenCV對影象邊緣檢測(Canny、Sobel、Laplace)

    邊緣檢測是影象處理和計算機視覺中的基本問題,邊緣檢測的目的是標識數字影象中亮度變化明顯的點。影象屬性中的顯著變化通常反映了屬性的重要事件和變化。 這些包括(i)深度上的不連續、(ii)表面方向不連續、(iii)物質屬性變化和(iv)場景照明變化。 邊緣檢測是影象處理和計算機視覺中,尤其是特徵提取中的

    影象邊緣檢測——幾種影象邊緣檢測運算元的學習及python 實現

      本文學習利用python學習邊緣檢測的濾波器,首先讀入的圖片程式碼如下: import cv2 from pylab import * saber = cv2.imread("construction.jpg") saber = cv2.cvtColor(saber,cv2.COLOR_BGR2RG

    梯度邊緣檢測常用運算元:Roberts、Prewitt、Sobel、Lapacian運算元

    原文;https://blog.csdn.net/swj110119/article/details/51777422 一、學習心得: 學習影象處理的過程中,剛開始遇到影象梯度和一些運算元的概念,這兩者到底是什麼關係,又有什麼不同,一直困擾著我。後來在看到影象分

    影象邊緣檢測-運算元比較總結

    一階導數運算元   1, Roberts運算元:對具有陡峭的低噪聲的影象處理效果較好。形式如下: [100−1] [

    影象邊緣檢測邊緣增強處理——(Roberts、prewitt、sobel)

    堅持寫下去,雖然簡單,但希望可以幫助到別人,有不足之處還望指教目的:對影象採用3種邊緣檢測運算元進行處理,比較處理後的結果,並用邊緣增強演算法對影象增強。一、基本原理1.1影象邊緣   影象邊緣是影象最基本的特徵之一,往往攜帶著一幅影象的大部分資訊。而邊緣存在於影象的不規則結

    我的CUDA學習之旅4——Sobel運算元影象邊緣檢測CUDA實現

    引言 關於影象邊緣檢測,記得剛開始接觸影象處理時,第一個自己實現的程式是通過筆記本攝像頭採集影象,利用OpenCV自帶的演算法庫進行Canny運算元邊緣檢測,那時候當看到程式執行後,視訊視窗實時顯示經Canny運算元邊緣分割後的影象,覺得十分有科技感,後來慢慢

    【OpenCV影象處理入門學習教程四】基於LoG運算元影象邊緣檢測

    一、基於LoG運算元的影象邊緣檢測原圖:1.LoG運算元與自定義濾波運算元進行比較的結果:2.LoG運算元的結果:3.自定義3*31 1 1 1 -8 1 1 1 1 濾波結果:二、程式碼解析下面是一段基於LoG運算元的影象邊緣檢測的程式碼,同時會生成兩個結果,一個是LoG運算元的結果,第二個是自

    OpenCV使用Canny邊緣檢測器實現影象邊緣檢測

    效果圖 原始碼 Canny邊緣檢測器是一種被廣泛使用的演算法,並被認為是邊緣檢測最優的演算法,該方法使用了比高斯差分演算法更復雜的技巧,如多向灰度梯度和滯後閾值化。 Canny

    5.4.4 邊緣檢測-拉普拉斯運算元

    拉普拉斯運算元是一個二階邊緣運算元,即梯度的散度。拉普拉斯運算元的實現也是通過模板實現。常用的拉普拉斯模板定義如下:                         &nb

    5.4.2 邊緣檢測-sobel運算元

    Sobel運算元也是一種常用的梯度運算元。Sobel運算元計算稍微複雜,它採用3x3的模板。計算時模板在影象上移動,並在每個位置上計算對應中心畫素的梯度值。 VTK中vtkSobel2D計算影象的sobel運算元,使用程式碼如下: /*-----------------------

    5.4.1 邊緣檢測—梯度運算元

    影象中不連續的灰度值會產生邊緣,影象的邊緣檢測是基於邊界的影象分割方法,如分水嶺演算法,通常是分割原圖的梯度影象,梯度實際上也是反應的影象邊緣資訊。影象邊緣一般常用影象一階導數和二階導數來檢測。 梯度運算元對應於影象一階導數。影象一階導數計算一般是通過差分運算來近似的。VTK中可以使用vtkIm