最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python Canny邊緣檢測算法的實現(xiàn)

 更新時間:2020年04月24日 09:01:34   作者:kuweicai  
這篇文章主要介紹了python Canny邊緣檢測算法的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

圖像邊緣信息主要集中在高頻段,通常說圖像銳化或檢測邊緣,實質(zhì)就是高頻濾波。我們知道微分運算是求信號的變化率,具有加強(qiáng)高頻分量的作用。在空域運算中來說,對圖像的銳化就是計算微分。對于數(shù)字圖像的離散信號,微分運算就變成計算差分或梯度。圖像處理中有多種邊緣檢測(梯度)算子,常用的包括普通一階差分,Robert算子(交叉差分),Sobel算子等等,是基于尋找梯度強(qiáng)度。拉普拉斯算子(二階差分)是基于過零點檢測。通過計算梯度,設(shè)置閥值,得到邊緣圖像。

Canny邊緣檢測算子是一種多級檢測算法。1986年由John F. Canny提出,同時提出了邊緣檢測的三大準(zhǔn)則:

  • 低錯誤率的邊緣檢測:檢測算法應(yīng)該精確地找到圖像中的盡可能多的邊緣,盡可能的減少漏檢和誤檢。
  • 最優(yōu)定位:檢測的邊緣點應(yīng)該精確地定位于邊緣的中心。
  • 圖像中的任意邊緣應(yīng)該只被標(biāo)記一次,同時圖像噪聲不應(yīng)產(chǎn)生偽邊緣。

Canny算法出現(xiàn)以后一直是作為一種標(biāo)準(zhǔn)的邊緣檢測算法,此后也出現(xiàn)了各種基于Canny算法的改進(jìn)算法。時至今日,Canny算法及其各種變種依舊是一種優(yōu)秀的邊緣檢測算法。而且除非前提條件很適合,你很難找到一種邊緣檢測算子能顯著地比Canny算子做的更好。

關(guān)于各種差分算子,還有Canny算子的簡單介紹,這里就不羅嗦了,網(wǎng)上都可以找得到。直接進(jìn)入Canny算法的實現(xiàn)。Canny算法分為以下幾步。

1. 高斯模糊。

這一步很簡單,類似于LoG算子(Laplacian of Gaussian)作高斯模糊一樣,主要作用就是去除噪聲。因為噪聲也集中于高頻信號,很容易被識別為偽邊緣。應(yīng)用高斯模糊去除噪聲,降低偽邊緣的識別。但是由于圖像邊緣信息也是高頻信號,高斯模糊的半徑選擇很重要,過大的半徑很容易讓一些弱邊緣檢測不到。

2. 計算梯度幅值和方向。

圖像的邊緣可以指向不同方向,因此經(jīng)典Canny算法用了四個梯度算子來分別計算水平,垂直和對角線方向的梯度。但是通常都不用四個梯度算子來分別計算四個方向。常用的邊緣差分算子(如Rober,Prewitt,Sobel)計算水平和垂直方向的差分Gx和Gy。這樣就可以如下計算梯度模和方向:

梯度角度 θ 范圍從弧度 -π 到 π,然后把它近似到四個方向,分別代表水平,垂直和兩個對角線方向(0°,45°,90°,135°)??梢砸浴纈π/8(i=1,3,5,7)分割,落在每個區(qū)域的梯度角給一個特定值,代表四個方向之一。

這里我選擇Sobel算子計算梯度。Sobel算法很簡單,到處都可以找到,就不列出代碼來了。相對于其他邊緣算子,Sobel算子得出來的邊緣粗大明亮。

下圖是對上面半徑2的高斯模糊圖像L通道(HSL)應(yīng)用Sobel算子的梯度模圖,沒有施加任何閥值。

Sobel算子,無閥值

3. 非最大值抑制。

非最大值抑制是一種邊緣細(xì)化方法。通常得出來的梯度邊緣不止一個像素寬,而是多個像素寬。就像我們所說Sobel算子得出來的邊緣粗大而明亮,從上面Lena圖的Sobel結(jié)果可以看得出來。因此這樣的梯度圖還是很“模糊”。而準(zhǔn)則3要求,邊緣只有一個精確的點寬度。非最大值抑制能幫助保留局部最大梯度而抑制所有其他梯度值。這意味著只保留了梯度變化中最銳利的位置。算法如下:

  • 比較當(dāng)前點的梯度強(qiáng)度和正負(fù)梯度方向點的梯度強(qiáng)度。
  • 如果當(dāng)前點的梯度強(qiáng)度和同方向的其他點的梯度強(qiáng)度相比較是最大,保留其值,否則抑制,即設(shè)為0。比如當(dāng)前點的方向指向正上方90°方向,那它需要和垂直方向,它的正上方和正下方的像素比較。

注意,方向的正負(fù)是不起作用的,比如東南方向和西北方向是一樣的,都認(rèn)為是對角線的一個方向。前面我們把梯度方向近似到水平,垂直和兩個對角線四個方向,所以每個像素根據(jù)自身方向在這四個方向之一進(jìn)行比較,決定是否保留。這一部分的代碼也很簡單,列出如下。pModule,pDirection分別記錄了上一步梯度模值和梯度方向。

pmoddrow = pModule + Width + 1; 
pdirdrow = pDirection + Width + 1;
pstrongdrow = pStrong + Width + 1;
for (i = 1; i < Hend - 1; i++)
{
  pstrongd = pstrongdrow;
  pmodd = pmoddrow;
  pdird = pdirdrow;
  for (j = 1; j < Wend - 1; j++)
    {
       switch (*pdird)
      {
      case 0:    // x direction
      case 4:
        if (*pmodd > *(pmodd - 1) && *pmodd > *(pmodd + 1))
          *pstrongd = 255;
        break;
      case 1:    // northeast-southwest direction. Notice the data order on y direction of bmp data
      case 5:
        if (*pmodd > *(pmodd + Width + 1) && *pmodd > *(pmodd - Width - 1))
          *pstrongd = 255;
        break;
      case 2:    // y direction
      case 6:
        if (*pmodd > *(pmodd - Width) && *pmodd > *(pmodd + Width))
          *pstrongd = 255;
        break;
      case 3:    // northwest-southeast direction. Notice the data order on y direction of bmp data
      case 7:
        if (*pmodd > *(pmodd + Width - 1) && *pmodd > *(pmodd - Width + 1))
          *pstrongd = 255;
        break;
      default:
        ASSERT(0);
        break;
      }
      pstrongd++;
      pmodd++;
      pdird++;
  }
  pstrongdrow += Width;
  pmoddrow += Width;
  pdirdrow += Width;
}

下圖是非最大值抑制的結(jié)果??梢娺吘墝挾纫呀?jīng)大大減小。但是這個圖像中因為沒有應(yīng)用任何閥值,還含有大量小梯度模值的點,也就是圖中很暗的地方。下面,閥值要上場了。

非最大值抑制結(jié)果

4. 雙閥值。

一般的邊緣檢測算法用一個閥值來濾除噪聲或顏色變化引起的小的梯度值,而保留大的梯度值。Canny算法應(yīng)用雙閥值,即一個高閥值和一個低閥值來區(qū)分邊緣像素。如果邊緣像素點梯度值大于高閥值,則被認(rèn)為是強(qiáng)邊緣點。如果邊緣梯度值小于高閥值,大于低閥值,則標(biāo)記為弱邊緣點。小于低閥值的點則被抑制掉。這一步算法很簡單。

5. 滯后邊界跟蹤。

至此,強(qiáng)邊緣點可以認(rèn)為是真的邊緣。弱邊緣點則可能是真的邊緣,也可能是噪聲或顏色變化引起的。為得到精確的結(jié)果,后者引起的弱邊緣點應(yīng)該去掉。通常認(rèn)為真實邊緣引起的弱邊緣點和強(qiáng)邊緣點是連通的,而由噪聲引起的弱邊緣點則不會。所謂的滯后邊界跟蹤算法檢查一個弱邊緣點的8連通領(lǐng)域像素,只要有強(qiáng)邊緣點存在,那么這個弱邊緣點被認(rèn)為是真的邊緣保留下來。

這個算法搜索所有連通的弱邊緣,如果一條連通的弱邊緣的任何一個點和強(qiáng)邊緣點連通,則保留這條弱邊緣,否則抑制這條弱邊緣。搜索時可以用廣度優(yōu)先或者深度優(yōu)先算法,我在這里實現(xiàn)了應(yīng)該是最容易的深度優(yōu)先算法。一次連通一條邊緣的深度優(yōu)先算法如下:

  • 準(zhǔn)備一個棧s,一個隊列q,設(shè)連通指示變量connected為假。從圖像的第一個點開始,進(jìn)入2。
  • 如果這個點是弱邊界點并且沒有被標(biāo)記,把它標(biāo)記,并把它作為第一個元素放入棧s中,同時把它放入記錄連通曲線的隊列q,進(jìn)入3。如果這個點不是弱邊界或者已經(jīng)被標(biāo)記過,到圖像的下一個點,重復(fù)2。
  • 從棧s中取出一個元素,查找它的8像素領(lǐng)域。如果一個領(lǐng)域像素是弱邊界并且沒有被標(biāo)記過,把這個領(lǐng)域像素標(biāo)記,并加入棧s中,同時加入隊列q。同時查找領(lǐng)域?qū)?yīng)的強(qiáng)邊界圖,如果有一個像素是強(qiáng)邊界,表示這條弱邊界曲線和強(qiáng)邊界聯(lián)通,設(shè)置connected為真。重復(fù)3直到棧中沒有元素了。如果connected為假,則依次從隊列q中取出每個元素,清空標(biāo)記。如果connected為真,保留標(biāo)記。
  • 清空隊列q,設(shè)置connected為假,移動到圖像的下一個點,回到2。
pmoddrow = pModule + Width + 1; 
pdirdrow = pDirection + Width + 1;
pstrongdrow = pStrong + Width + 1;
for (i = 1; i < Hend - 1; i++)
{
  pstrongd = pstrongdrow;
  pmodd = pmoddrow;
  pdird = pdirdrow;
  for (j = 1; j < Wend - 1; j++)
    {
       switch (*pdird)
      {
      case 0:    // x direction
      case 4:
        if (*pmodd > *(pmodd - 1) && *pmodd > *(pmodd + 1))
          *pstrongd = 255;
        break;
      case 1:    // northeast-southwest direction. Notice the data order on y direction of bmp data
      case 5:
        if (*pmodd > *(pmodd + Width + 1) && *pmodd > *(pmodd - Width - 1))
          *pstrongd = 255;
        break;
      case 2:    // y direction
      case 6:
        if (*pmodd > *(pmodd - Width) && *pmodd > *(pmodd + Width))
          *pstrongd = 255;
        break;
      case 3:    // northwest-southeast direction. Notice the data order on y direction of bmp data
      case 7:
        if (*pmodd > *(pmodd + Width - 1) && *pmodd > *(pmodd - Width + 1))
          *pstrongd = 255;
        break;
      default:
        ASSERT(0);
        break;
      }
      pstrongd++;
      pmodd++;
      pdird++;
  }
  pstrongdrow += Width;
  pmoddrow += Width;
  pdirdrow += Width;
}

下面是對Lena圖計算Canny邊緣檢測的梯度模圖和二值化圖,高斯半徑2,高閥值100,低閥值50。

   

Canny檢測梯度模圖                        Canny檢測梯度二值圖

作為對比,下面是用一階差分和Sobel算子對原圖計算的結(jié)果,閥值100。由于一階差分的梯度值相對較小,我對一階差分的梯度值放大了一定倍數(shù),使得它和Sobel的梯度值保持同樣的水平。

   

 一階差分梯度模圖                        一階差分梯度二值圖

   

Sobel梯度模圖                          Sobel梯度二值圖

很明顯,Canny邊緣檢測的效果是很顯著的。相比普通的梯度算法大大抑制了噪聲引起的偽邊緣,而且是細(xì)化過的邊緣,易于后續(xù)處理。對于對比度較低的圖像,通過調(diào)節(jié)參數(shù),Canny算法也能有很好的效果。

到此這篇關(guān)于python Canny邊緣檢測算法的實現(xiàn)的文章就介紹到這了,更多相關(guān)Canny邊緣檢測算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 設(shè)置jupyter中DataFrame的顯示限制方式

    設(shè)置jupyter中DataFrame的顯示限制方式

    這篇文章主要介紹了設(shè)置jupyter中DataFrame的顯示限制方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來
    2020-04-04
  • python函數(shù)存儲在模塊的優(yōu)點及用法總結(jié)

    python函數(shù)存儲在模塊的優(yōu)點及用法總結(jié)

    在本篇文章里小編給大家整理了一篇關(guān)于python函數(shù)存儲在模塊的優(yōu)點及用法相關(guān)內(nèi)容,有興趣的朋友們可以跟著學(xué)習(xí)下。
    2021-10-10
  • PyCharm GUI界面開發(fā)和exe文件生成的實現(xiàn)

    PyCharm GUI界面開發(fā)和exe文件生成的實現(xiàn)

    這篇文章主要介紹了PyCharm GUI界面開發(fā)和exe文件生成,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Python使用5行代碼批量做小姐姐的素描圖

    Python使用5行代碼批量做小姐姐的素描圖

    本文主要介紹了Python使用5行代碼批量做小姐姐的素描圖,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • python環(huán)境路徑配置以及命令行運行腳本

    python環(huán)境路徑配置以及命令行運行腳本

    這篇文章主要為大家詳細(xì)介紹了python環(huán)境路徑配置以及命令行運行腳本,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • pytorch中構(gòu)建模型的3種方法詳解

    pytorch中構(gòu)建模型的3種方法詳解

    這篇文章主要介紹了pytorch中構(gòu)建模型的3種方法,分別是使用繼承nn.Module基類構(gòu)建自定義模型,使用nn.Sequential按層順序構(gòu)建模型或者,繼承nn.Module基類構(gòu)建模型并輔助應(yīng)用模型容器進(jìn)行封裝(nn.Sequential,nn.ModuleList,nn.ModuleDict),需要的朋友可以參考下
    2023-09-09
  • Python包管理工具之PDM的使用教程

    Python包管理工具之PDM的使用教程

    今天主要是給大家推薦一個叫PDM的工具,全稱:Python?Development?Master,它也是非常好用。本文將為大家詳細(xì)講講它的使用,感興趣的可以了解一下
    2022-08-08
  • 使用Python和Pillow實現(xiàn)圖片馬賽克功能

    使用Python和Pillow實現(xiàn)圖片馬賽克功能

    在這篇博客中,我們將探討如何使用Python創(chuàng)建一個簡單而有趣的桌面應(yīng)用程序,我們的目標(biāo)是構(gòu)建一個應(yīng)用,允許用戶選擇一張照片,然后在照片的右下角添加馬賽克效果,感興趣的小伙伴跟著小編一起來看看吧
    2024-08-08
  • python讀取hdfs上的parquet文件方式

    python讀取hdfs上的parquet文件方式

    這篇文章主要介紹了python讀取hdfs上的parquet文件方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • Python創(chuàng)建系統(tǒng)目錄的方法

    Python創(chuàng)建系統(tǒng)目錄的方法

    這篇文章主要介紹了Python創(chuàng)建系統(tǒng)目錄的方法,實例分析了Python操作目錄的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03

最新評論

习水县| 舒城县| 房产| 天峨县| 铜山县| 忻城县| 广水市| 论坛| 高雄县| 泰来县| 南靖县| 广丰县| 灌云县| 乌苏市| 彭州市| 溧水县| 安阳县| 神农架林区| 资兴市| 肇州县| 莎车县| 安图县| 紫云| 大方县| 芦溪县| 和田县| 彰化市| 奉新县| 彰武县| 互助| 炎陵县| 华阴市| 蓬安县| 旬阳县| 靖州| 大厂| 绥芬河市| 运城市| 出国| 凤城市| 德江县|