日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

opencv-python 详解图像梯度、边缘检测

發(fā)布時間:2024/1/8 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 opencv-python 详解图像梯度、边缘检测 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

作者:RayChiu_Labloy
版權聲明:著作權歸作者所有,商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處


目錄

關于圖像梯度

?從卷積的角度看垂直邊緣提取:?

談一下邊緣檢測算法sobel

Scharr算子

?Laplacian()拉普拉斯算子

邊緣檢測算法通常有四個步驟:

(1)濾波:

(2)增強:?

(3)檢測:?

(4)定位:?

canny() 邊緣檢測:

1、灰度化圖像

2、高斯濾波消除噪聲

Guess過程:

3、計算幅值圖像、角度圖像,計算圖像梯度的方向

4、對幅值圖像進行非極大值抑制

5、雙閾值檢測和連接邊緣,滯后閾值

canny()測試,測試圖片:


關于圖像梯度

????????如果還記得高數(shù)中用一階導數(shù)來求極值的話,就很容易理解圖像梯度了:把圖片想象成連續(xù)函數(shù),因為邊緣部分的像素值是與旁邊像素明顯有區(qū)別的,所以對圖片局部求極值,就可以得到整幅圖片的邊緣信息了。 ? ????????不過圖片是二維的離散函數(shù),導數(shù)就變成了差分,這個差分就稱為圖像的梯度。

?從卷積的角度看垂直邊緣提取:?

濾波是應用卷積來實現(xiàn)的,卷積的關鍵就是卷積核,我們來考察下面這個卷積核:

?這個核是用來提取圖片中的垂直邊緣的,怎么做到的呢?看下圖:

????????當前列左右兩側的元素進行差分,由于邊緣的值明顯小于(或大于)周邊像素,所以邊緣的差分結果會明顯不同,這樣就提取出了垂直邊緣。
????????同理,把上面那個矩陣轉置一下,就是提取水平邊緣。這種差分操作就稱為圖像的梯度計算:

談一下邊緣檢測算法sobel

? ? ? ? 關于上圖圖像的邊緣,圖像中像素灰度值變化沒有規(guī)律。一種比較好的描述這種變化的方法是采用導數(shù)。其中梯度劇烈變化的地方代表圖像灰度值變化強烈的地方,也就是邊緣。
????????為了更好的說明,以1維圖像(也就是圖像的1行)為例。邊緣出現(xiàn)在灰度值跳變的地方,如下圖所示:?

?如果對上面的1維圖像求導數(shù),得到下圖,可以很明顯的看到邊緣所在的位置。

????????從上面的解釋,我們可以設置一個閾值,根據(jù)局部像素變化強烈程度獲取圖像邊緣。
????????sobel算子是一個離散微分算子,計算得到的是圖像梯度的近似值。sobel算子結合了高斯平滑和微分
????????假設輸入圖像是I,,核大小為3,通過下面運算分別計算水平方向和垂直方向的微分:
a.水平方向:

?b.垂直方向:

?具體運算為:

結合上面結果可以計算出圖像中一個點的近似梯度: ?

?或者表示為:

Scharr算子

Scharr()?函數(shù)提供了比標準Sobel函數(shù)更精確的計算結果。它使用了下面的核:

?除了卷積核與Sobel不同,在其余方面它與Sobel基本一致。

?Laplacian()拉普拉斯算子

Sobel邊緣檢測原理是利用邊緣區(qū)域像素值的跳變。通過求一階導數(shù),可以使邊緣值最大化。如下圖所示:

那么,如果求二階導數(shù)會得到什么呢? ?

????????可以觀察到邊緣處于二階導數(shù)為0的地方。因此,可以利用該方法獲取圖像中的邊緣。然而,需要注意的是二級導數(shù)為0的不只出現(xiàn)在邊緣地方,還可能是一些無意義的位置,根據(jù)需要通過濾波處理該情況。

????????現(xiàn)在我們來討論二階微分,它是拉普拉斯算子的基礎,與微積分中定義的微分略有不同,數(shù)字圖像中處理的是離散的值,因此對于一維函數(shù)的一階微分的基本定義是差值:

?類似的,二階微分定義為:

?將一維函數(shù)擴展到二維:

二階微分的定義保證了以下幾點:

1、在恒定灰度區(qū)域的微分值為0

2、在灰度臺階或斜坡的起點處微分值非零

可以看出,二階微分可以檢測出圖像的邊緣、增強細節(jié)

由于圖像是二維的,因此需要分別獲取兩個方向的導數(shù),拉普拉斯算子用下面公式定義:

?其中:

?可以用多種方式將其表示為數(shù)字形式。對于一個3*3的區(qū)域,一般情況下被推薦最多的形式是:

?實現(xiàn)上式的濾波器模板為:

?我們發(fā)現(xiàn),拉普拉斯算子不需要像Sobel算子那樣分別對x,y方向進行處理,它可以直接處理 .

較為復雜的圖像拉普拉斯算子的效果也并不是很好,由于二階微分一定的局限性,目前的邊緣檢測還不夠完美,我們需要一種綜合的算法,類似 canny()

邊緣檢測算法通常有四個步驟

(1)濾波

????????邊緣檢測算法主要是基于圖像強度的一階和二階導數(shù),但導數(shù)的計算對噪聲很敏感,因此必須使用濾波器來改善與噪聲有關的邊緣檢測器的性能.需要指出,大多數(shù)濾波器在降低噪聲的同時也導致了邊緣強度的損失,因此,增強邊緣和降低噪聲之間需要折衷.

(2)增強:?

????????增強邊緣的基礎是確定圖像各點鄰域強度的變化值.增強算法可以將鄰域(或局部)強度值有顯著變化的點突顯出來.邊緣增強一般是通過計算梯度幅值來完成的.

(3)檢測:?

在圖像中有許多點的梯度幅值比較大,而這些點在特定的應用領域中并不都是邊緣,所以應該用某種方法來確定哪些點是邊緣點.最簡單的邊緣檢測判據(jù)是梯度幅值閾值判據(jù).

(4)定位:?

如果某一應用場合要求確定邊緣位置,則邊緣的位置可在子像素分辨率上來估計,邊緣的方位也可以被估計出來.
????????在邊緣檢測算法中,前三個步驟用得十分普遍。這是因為大多數(shù)場合下,僅僅需要邊緣檢測器指出邊緣出現(xiàn)在圖像某一像素點的附近,而沒有必要指出邊緣的精確位置或方向.邊緣檢測誤差通常是指邊緣誤分類誤差,即把假邊緣判別成邊緣而保留,而把真邊緣判別成假邊緣而去掉.邊緣估計誤差是用概率統(tǒng)計模型來描述邊緣的位置和方向誤差的.我們將邊緣檢測誤差和邊緣估計誤差區(qū)分開,是因為它們的計算方法完全不同,其誤差模型也完全不同.

canny() 邊緣檢測:

????????JohnCanny于1986年提出Canny算子,它與Marr(LoG)邊緣檢測方法類似,也屬于是先平滑后求導數(shù)的方法,看下原理:

1、灰度化圖像

Canny算法通常處理的圖像為灰度圖,因此如果攝像機獲取的是彩色圖像,那首先就得進行灰度化。對一幅彩色圖進行灰度化,就是根據(jù)圖像各個通道的采樣值進行加權平均。以RGB格式的彩圖為例,通常灰度化采用的方法主要有:

方法1:Gray=(R+G+B)/3

方法2:Gray=0.299R+0.587G+0.114B;(這種參數(shù)考慮到了人眼的生理特點)

注意1:至于其他格式的彩色圖像,可以根據(jù)相應的轉換關系轉為RGB然后再進行灰度化;

注意2:在編程時要注意圖像格式中RGB的順序通常為BGR。

2、高斯濾波消除噪聲

令f(x,y)表示數(shù)據(jù)(輸入源數(shù)據(jù)),G(x,y)表示二維高斯函數(shù)(卷積操作數(shù)),fs(x,y)為卷積平滑后的圖像。

Guess過程

用坐標點(x,y)表示一個3x3的鄰域,設中心點的坐標為(0,0),相鄰的點以此類推。

?計算權重矩陣。設定方差σ2=0.64的值,將對應各個坐標點(x,y)帶入二維高斯公式G(x,y)中,得到一個權重矩陣,歸一化權重矩陣(矩陣中各個點除以權重之和),得到標準的權重矩陣,即高斯模板。

計算高斯模糊。設在一幅圖像中的3×3區(qū)域內,用各像素點的灰度值乘以對應點的權重。

?將得到的9個值求和,就是中心點的高斯模糊值。

簡單來說就是使用Guess模板在原始圖像中進行移位、相乘、相加的過程。

3、計算幅值圖像、角度圖像,計算圖像梯度的方向

求變化率時,對于一元函數(shù),即求導;對于二元函數(shù),求偏導。數(shù)字圖像處理中,用一階有限差分近似求取灰度值的梯度值(變化率)。

例:計算一點x方向和y方向的梯度幅值和方向?

????????上圖中顯示一段直的邊緣線段放大后一部分,每個方塊代表一個像素點,用一個方框強調點處邊緣的幅值和方向。令灰色像素值為0,白色像素值為1。

如圖關于一點為中心的?3×3鄰域,使用Prewittt卷積模板進行計算:

????????根據(jù)x方向和y方向的卷積模板,可知,在3x3的鄰域中從底部一行像素值減去頂部一行的像素,得到x方向的偏導數(shù)(梯度);同樣,從右邊一列像素值減去左邊一列的像素,得到y(tǒng)方向的偏導數(shù)。

x方向的梯度:

?y方向的梯度:

?由此,可以得到該點梯度的幅值和方向:

?如下圖表示了中心點的梯度向量、方位角以及邊緣方向。(任一點的邊緣與梯度向量正交):

?Canny算子的卷積模板為:

4、對幅值圖像進行非極大值抑制

首先將角度劃分成四個方向范圍:水平(0°)、?45°、垂直(90°)、+45°如下圖:

?接著討論對3x3區(qū)域的四個基本邊緣方向進行非極大值抑制。

?做法:若中心點(即:訪問點)在沿其方向上鄰域的梯度幅值最大,則保留;否則,抑制。

5、雙閾值檢測和連接邊緣,滯后閾值

????????經過前面四步,就只剩下0和可能的邊緣梯度值了,為了最終確定下來,需要設定高低閾值:

  • 像素點的值大于最高閾值,那肯定是邊緣(上圖A
  • 同理像素值小于最低閾值,那肯定不是邊緣
  • 像素值介于兩者之間,如果與高于最高閾值的點連接,也算邊緣,所以上圖中C算,B不算

?推薦的高低閾值TH和TL比在2:13:1之間。

????????取出非極大值抑制后的圖像中的最大梯度幅值,定義高低閾值。即:TH×Max,TL×Max (當然可以自己給定)?;

????????將小于低閾值的點拋棄,賦0;將大于高閾值的點立即標記(這些點就是邊緣點),賦1;

????????將小于高閾值,大于低閾值的點使用8連通區(qū)域確定(即:只有與TH像素連接時才會被接受,成為邊緣點,賦??1)。

canny()測試,測試圖片:

測試代碼:

import cv2 import numpy as np img = cv2.imread('handwriting.jpg', 0) edges = cv2.Canny(img, 18, 40) # canny邊緣檢測 cv2.imshow('canny', np.hstack((img, edges))) cv2.waitKey(0)

效果:

?關于邊緣檢測函數(shù) cv2.Canny()

edge = CV2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient ]]])?

參數(shù)23表示最低、高閾值,參數(shù)3用于檢測圖像中明顯的邊緣,但一般情況下檢測的效果不會那么完美,邊緣檢測出來是斷斷續(xù)續(xù)的。所以這時候用較小的第一個閾值用于將這些間斷的邊緣連接起來。

????????可選參數(shù)中apertureSize就是Sobel算子的大小。而L2gradient參數(shù)是一個布爾值,如果為真,則使用更精確的L2范數(shù)進行計算(即兩個方向的倒數(shù)的平方和再開放),否則使用L1范數(shù)(直接將兩個方向導數(shù)的絕對值相加)。?

【如果對您有幫助,交個朋友給個一鍵三連吧,您的肯定是我博客高質量維護的動力!!!】?

總結

以上是生活随笔為你收集整理的opencv-python 详解图像梯度、边缘检测的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。