Ⅰ 如何利用opencv實現彩色圖像邊緣檢測演算法
在opencv中顯示邊緣檢測很簡單,只需調用一個cvCanny函數,其使用的是Canny演算法來實現對圖像的邊緣檢測.
函數原型為:
void cvCanny( const CvArr* image,CvArr* edges,double threshold1,double threshold2, int aperture_size=3 );
第一個參數為待檢測的圖像,注意一點,其必須是灰度圖.
第二個參數為輸出的邊緣圖,其也是一個灰度圖.
後三個參數與Canny演算法直接相關,threshold1和threshold2 當中的小閾值用來控制邊緣連接,大的閾值用來控制強邊緣的初始分割,aperture_size運算元內核大小,可以去看看Canny演算法.
從彩色圖到灰度圖需要使用到cvCvtColor函數,其接受三個參數,第一為輸入,第二為輸出,第三個為轉換的標識,我們這邊是RGB到GRAY,使用的是CV_RGB2GRAY.
參考demo代碼如下:
#include <iostream>
#include <string>
#include <sstream>
#include <opencv/cv.h>
#include <opencv/highgui.h>
using namespace std;
int String2int(const string& str_)
{
int _nre = 0;
stringstream _ss;
_ss << str_;
_ss >> _nre;
return _nre;
}
void DoCanny(const string& strFileName_)
{
//原彩色圖片
IplImage* _pIplImageIn = cvLoadImage(strFileName_.data());
if (_pIplImageIn == NULL)
{
return;
}
//彩色圖片轉換成灰度圖放置的圖片
IplImage* _pIplImageCanny = cvCreateImage(cvGetSize(_pIplImageIn), _pIplImageIn->depth, 1);
cvCvtColor(_pIplImageIn, _pIplImageCanny, CV_RGB2GRAY);//CV_RGB2GRAY將rgb圖轉成灰度圖
//只有邊緣路徑的圖片
IplImage* _pIplImageOut = cvCreateImage(cvGetSize(_pIplImageIn), IPL_DEPTH_8U, 1);
//邊緣檢測只能作用於灰度圖
if (_pIplImageCanny->nChannels != 1)
{
return;
}
//邊緣檢測操作
cvCanny(_pIplImageCanny, _pIplImageOut, 1, 110, 3);
cvNamedWindow("Src");
cvShowImage("Src", _pIplImageIn);
cvNamedWindow("Canny");
cvShowImage("Canny", _pIplImageOut);
cvWaitKey(0);
cvReleaseImage(&_pIplImageIn);
cvReleaseImage(&_pIplImageCanny);
cvReleaseImage(&_pIplImageOut);
cvDestroyWindow("Src");
cvDestroyWindow("Canny");
}
int main(int argc, char* argv[])
{
if (argc < 2)
{
cout << "You should give the filename of picture!" << endl;
return -1;
}
DoCanny(argv[1]);
return 0;
}
Ⅱ 邊緣檢測的檢測邊緣
如果將邊緣認為是一定數量點亮度發生變化的地方,那麼邊緣檢測大體上就是計算這個亮度變化的導數。為簡化起見,我們可以先在一維空間分析邊緣檢測。在這個例子中,我們的數據是一行不同點亮度的數據。例如,在下面的1維數據中我們可以直觀地說在第4與第5個點之間有一個邊界:
除非場景中的物體非常簡單並且照明條件得到了很好的控制,否則確定一個用來判斷兩個相鄰點之間有多大的亮度變化才算是有邊界的閾值,並不是一件容易的事。實際上,這也是為什麼邊緣檢測不是一個微不足道問題的原因之一。
檢測方法
有許多用於邊緣檢測的方法, 他們大致可分為兩類:基於搜索和基於零交叉。
基於搜索的邊緣檢測方法首先計算邊緣強度, 通常用一階導數表示, 例如梯度模,然後,用計算估計邊緣的局部方向, 通常採用梯度的方向,並利用此方向找到局部梯度模的最大值。
基於零交叉的方法找到由圖像得到的二階導數的零交叉點來定位邊緣。 通常用拉普拉斯運算元或非線性微分方程的零交叉點。
濾波做為邊緣檢測的預處理通常是必要的,通常採用高斯濾波。
已發表的邊緣檢測方法應用計算邊界強度的度量,這與平滑濾波有本質的不同。 正如許多邊緣檢測方法依賴於圖像梯度的計算,他們用不同種類的濾波器來估計x-方向和y-方向的梯度。
計算一階導數
許多邊緣檢測操作都是基於亮度的一階導數——這樣就得到了原始數據亮度的梯度。使用這個信息我們能夠在圖像的亮度梯度中搜尋峰值。如果 I(x) 表示點 x 的亮度,I′(x) 表示點 x 的一階導數(亮度梯度),這樣我們就會發現:
對於更高性能的圖像處理來說,一階導數能夠通過帶有掩碼的原始數據(1維)卷積計算得到。
計算二階導數
其它一些邊緣檢測操作是基於亮度的二階導數。這實質上是亮度梯度的變化率。在理想的連續變化情況下,在二階導數中檢測過零點將得到梯度中的局部最大值。另一方面,二階導數中的峰值檢測是邊線檢測,只要圖像操作使用一個合適的尺度表示。如上所述,邊線是雙重邊緣,這樣我們就可以在邊線的一邊看到一個亮度梯度,而在另一邊看到相反的梯度。這樣如果圖像中有邊線出現的話我們就能在亮度梯度上看到非常大的變化。為了找到這些邊線,我們可以在圖像亮度的二階導數中尋找過零點。如果 I(x) 表示點 x 的亮度,I′′(x) 表示點 x 亮度的二階導數,那麼:
同樣許多演算法也使用卷積掩碼快速處理圖像數據:
步驟:
①濾波:邊緣檢測演算法主要是基於圖像強度的一階和二階導數,但導數的計算對雜訊很敏感,因此必須使用濾波器來改善與雜訊有關的邊緣檢測器的性能。需要指出,大多數濾波器在降低雜訊的同時也導致了邊緣強度的損失,因此,增強邊緣和降低雜訊之間需要折中。
②增強:增強邊緣的基礎是確定圖像各點鄰域強度的變化值。增強演算法可以將鄰域(或局部)強度值有顯著變化的點突顯出來。邊緣增強一般是通過計算梯度幅值來完成的。
③檢測:在圖像中有許多點的梯度幅值比較大,而這些點在特定的應用領域中並不都是邊緣,所以應該用某種方法來確定哪些點是邊緣點。最簡單的邊緣檢測判據是梯度幅值閾值判據。
④定位:如果某一應用場合要求確定邊緣位置,則邊緣的位置可在子像素解析度上來估計,邊緣的方位也可以被估計出來。在邊緣檢測演算法中,前三個步驟用得十分普遍。這是因為大多數場合下,僅僅需要邊緣檢測器指出邊緣出現在圖像某一像素點的附近,而沒有必要指出邊緣的精確位置或方向。
邊緣檢測的實質是採用某種演算法來提取出圖像中對象與背景間的交界線。我們將邊緣定義為圖像中灰度發生急劇變化的區域邊界。圖像灰度的變化情況可以用圖像灰度分布的梯度來反映,因此我們可以用局部圖像微分技術來獲得邊緣檢測運算元。經典的邊緣檢測方法,是通過對原始圖像中像素的某小鄰域構造邊緣檢測運算元來達到檢測邊緣這一目的的。
Ⅲ canny邊緣檢測演算法 濾波用什麼方法好
Canny 的目標是找到一個最優的邊緣檢測演算法,最優邊緣檢測的含義是:
(1)最優檢測:演算法能夠盡可能多地標識出圖像中的實際邊緣,漏檢真實邊緣的概率和誤檢非邊緣的概率都盡可能小;
(2)最優定位準則:檢測到的邊緣點的位置距離實際邊緣點的位置最近,或者是由於雜訊影響引起檢測出的邊緣偏離物體的真實邊緣的程度最小;
(3)檢測點與邊緣點一一對應:運算元檢測的邊緣點與實際邊緣點應該是一一對應。
為了滿足這些要求 Canny 使用了變分法,這是一種尋找滿足特定功能的函數的方法。最優檢測使用四個指數函數項表示,但是它非常近似於高斯函數的一階導數。
Ⅳ 圖像的邊緣檢測原理是什麼啊
邊緣通常都是一邊亮,一邊暗
邊緣檢測就是利用亮 與 暗 之間的梯度變化
Ⅳ 邊緣檢測的理論依據是什麼有哪些方法各有什麼特點
就是通過一些臨近像素相關演算法突出灰度變化比較大的部分。變化平緩的取值低,變化越劇烈取值越高。比如有卷積演算法,具體計算方法,有拉普拉斯運算元、高斯運算元等的應用。
Ⅵ 邊緣檢測演算法中為什麼閾值影響檢測效果
canny邊緣檢測的實現大致有4步:1.高斯濾波對圖像去噪。2.由原始灰度圖求出縱橫2個梯度圖,以及綜合梯度圖(求梯度的運算元很多)。3.結合3個 梯度圖來進行非極大抑制(此步一過,檢測的圖像邊緣已經很細了)4.進行邊緣連接(個人感覺這一步雖叫連接,演算法也確實體現了連接的行為,但那是強邊緣到 弱邊緣的連接,所有可能連接的點都出不了非極大抑制後的范圍,所以這一步更准確的目的應該是在非極大抑制的結果中去除假邊緣保留真邊緣,同時又能讓保留的 邊緣盡量連貫真實)5.對邊緣進行細化(這步在matlab的canny演算法中有,但是考慮到通過以上4步尤其是第3步得到的邊緣已經很細,一般沒有再對 邊緣進行細化的必要,因此,此步可以省略)
上述4步中,前兩步比較簡單,實現的關鍵在於後兩步。這里對第二步也概括的說一下,求縱橫梯度的運算元是很多的,像3×3的sobel運算元,其卷積核是 [1,0,-1;1,0,-1;1,0,-1]和[1,1,1;0,0,0;-1,-1,-1];2×2的robert運算元,其卷積核是 [1,-1;1,-1]和[1,1;-1,-1]。而我們學習matlab中canny檢測的演算法,在第一步濾波和第二步求縱橫梯度時用的都是高斯模版。 注意,濾波的模版系數之和為1,求梯度的模版系數之和為0,這是卷積模版的一個規律。我們濾波和求梯度的模版都是二維的高斯模版,但是用縱橫2次兩個一維 的高斯卷積模版進行卷積可以達到和一個二維模版一樣的效果,同時減小了總計算量,所以,在第一步濾波的時候我們用兩個一維高斯模版代替一個二維高斯模版, 但是第二步的高斯模版牽扯到梯度方向,所以還是用一個二維的高斯模版來直接卷積。
Ⅶ 圖像邊緣檢測演算法有哪些
早期的有邊緣運算元法、曲線擬合法、模板匹配法、門限化法。近年來又有許多新的邊緣檢測的演算法:小波變換、小波包的邊緣檢測等,基於數學形態學、模糊理論和神經網路的邊緣檢測演算法等。