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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

candy算子python_Python-计算机视觉中的Canny边缘检测方法

發布時間:2025/6/15 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 candy算子python_Python-计算机视觉中的Canny边缘检测方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天的想法是用Canny邊緣檢測算法,建立一種可以勾畫出圖像上任何物體的邊緣的算法。

首先,我們來描述一下Canny邊緣檢測器:Canny邊緣檢測算子是一種邊緣檢測算子,它采用多級算法檢測圖像中廣泛的邊緣。它是由John F. Canny在1986年開發的。Canny還提出了邊緣檢測的計算理論,解釋了該技術的工作原理。

Canny邊緣檢測算法由5個步驟組成:降噪;

梯度計算;

非最大抑制;

雙閾值;

滯后邊緣跟蹤。

應用這些步驟后,您將能夠獲得以下結果:

左側的原始圖像 - 右側的已處理圖像

最后值得一提的是,該算法是基于灰度圖像的。因此,在進行上述步驟之前,首先要將圖像轉換為灰度。

降噪

由于場景背后涉及的數學主要基于導數(參見步驟2:梯度計算),邊緣檢測結果對圖像噪聲高度敏感。

消除圖像噪聲的一種方法是使用高斯模糊平滑圖像。為此,圖像卷積技術應用高斯核(3x3, 5x5, 7x7等)。核大小取決于預期的模糊效果。基本上,核越小,模糊就越不明顯。在我們的例子中,我們將使用一個5×5的高斯核函數。

大小為(2k+1)×(2k+1)的高斯濾波核的方程為:

高斯濾波器核方程

用于生成Gaussian 5x5內核的Python代碼:

import numpy as npdef gaussian_kernel(size, sigma=1): size = int(size) // 2 x, y = np.mgrid[-size:size+1, -size:size+1] normal = 1 / (2.0 * np.pi * sigma**2) g = np.exp(-((x**2 + y**2) / (2.0*sigma**2))) * normal return g

應用高斯模糊后,我們得到以下結果:

原始圖像(左) - 帶有高斯濾波器的模糊圖像(sigma = 1.4,核大小為5x5)

梯度計算

梯度計算步驟通過使用邊緣檢測算子計算圖像的梯度來檢測邊緣強度和方向。

邊緣對應于像素強度的變化。要檢測它,最簡單的方法是應用filters,在兩個方向上突出這種強度變化:水平(x)和垂直(y)

當平滑圖像時,計算導數Ix和Iy。它可以通過分別用Sobel kernelsKx和Ky分別卷積I來實現:

Sobel filters用于兩個方向(水平和垂直)

然后,梯度的幅度G和斜率θ計算如下:

梯度強度和邊緣方向

下面是Sobel濾鏡應用于圖像的方法,以及如何獲得強度和邊緣方向矩陣,Python代碼如下:from scipy import ndimagedef sobel_filters(img): Kx = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], np.float32) Ky = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]], np.float32) Ix = ndimage.filters.convolve(img, Kx) Iy = ndimage.filters.convolve(img, Ky) G = np.hypot(Ix, Iy) G = G / G.max() * 255 theta = np.arctan2(Iy, Ix) return (G, theta)

模糊圖像(左) - 梯度強度(右)

結果幾乎是預期的,我們可以看到,一些邊緣是厚的,另一些是薄的。非最大抑制步驟將有助于我們減輕厚的。

此外,梯度強度水平在0到255之間,這是不均勻的。最終結果的邊緣應具有相同的強度(即白色像素= 255)。

非最大抑制

理想情況下,最終的圖像應該有細邊。因此,我們必須執行非最大抑制以使邊緣變細。

原理很簡單:算法遍歷梯度強度矩陣上的所有點,并找到邊緣方向上具有最大值的像素。

讓我們舉一個簡單的例子:

上圖左上角的紅色框表示被處理的梯度強度矩陣的一個強度像素。對應的邊緣方向由橙色箭頭表示,其角度為-pi弧度(+/- 180度)。

聚焦左上角的紅色方塊像素

邊緣方向是橙色虛線(從左到右水平)。該算法的目的是檢查在相同方向上的像素是否比被處理的像素強度高或低。在上面的例子中,正在處理像素(i,j),相同方向上的像素用藍色(i, j-1)和(i, j+1)高亮顯示。如果這兩個像素中的一個比正在處理的那個更強,那么只保留更強的那個。像素(i, j-1)似乎更強,因為它是白色的(值255)。因此,當前像素(i, j)的強度值設置為0。如果邊緣方向上沒有具有更強值的像素,則保留當前像素的值。

現在讓我們關注另一個例子:

在這種情況下,方向是橙色虛線對角線。因此,該方向上最強的像素是像素(i-1,j + 1)。

讓我們總結一下。每個像素有2個主要標準(弧度的邊緣方向和像素強度(0-255之間))。基于這些輸入,非最大抑制步驟是:創建一個初始化為0的矩陣,該矩陣與原始梯度強度矩陣的大小相同;

根據角度矩陣的角度值識別邊緣方向;

檢查相同方向的像素是否具有比當前處理的像素更高的強度;

返回使用非最大抑制算法處理的圖像。

Python代碼如下:

def non_max_suppression(img, D): M, N = img.shape Z = np.zeros((M,N), dtype=np.int32) angle = D * 180. / np.pi angle[angle < 0] += 180 for i in range(1,M-1): for j in range(1,N-1): try: q = 255 r = 255 #angle 0 if (0 <= angle[i,j] < 22.5) or (157.5 <= angle[i,j] <= 180): q = img[i, j+1] r = img[i, j-1] #angle 45 elif (22.5 <= angle[i,j] < 67.5): q = img[i+1, j-1] r = img[i-1, j+1] #angle 90 elif (67.5 <= angle[i,j] < 112.5): q = img[i+1, j] r = img[i-1, j] #angle 135 elif (112.5 <= angle[i,j] < 157.5): q = img[i-1, j-1] r = img[i+1, j+1] if (img[i,j] >= q) and (img[i,j] >= r): Z[i,j] = img[i,j] else: Z[i,j] = 0 except IndexError as e: pass return Z

結果是相同的圖像,但邊緣更薄。然而,我們仍然可以注意到邊緣亮度的一些變化:一些像素似乎比其他像素更亮,我們將嘗試在最后兩個步驟中彌補這一缺陷。

非最大抑制的結果

雙閾值

雙閾值步驟旨在識別3種像素:強,弱和不相關:強像素是指像素的強度如此之高,以至于我們確信它們有助于最終的邊緣。

弱像素是具有不足以被視為強的強度值的像素,但是還不足以被認為與邊緣檢測不相關。

其他像素被認為與邊緣無關。

現在你可以看到這兩個閾值代表什么:高閾值用于識別強像素(強度高于高閾值)

低閾值用于識別不相關的像素(強度低于低閾值)

具有兩個閾值之間的強度的所有像素被標記為弱,滯后機制(下一步驟)將幫助我們識別可被視為強的那些和被認為是不相關的那些。def threshold(img, lowThresholdRatio=0.05, highThresholdRatio=0.09): highThreshold = img.max() * highThresholdRatio; lowThreshold = highThreshold * lowThresholdRatio; M, N = img.shape res = np.zeros((M,N), dtype=np.int32) weak = np.int32(25) strong = np.int32(255) strong_i, strong_j = np.where(img >= highThreshold) zeros_i, zeros_j = np.where(img < lowThreshold) weak_i, weak_j = np.where((img <= highThreshold) & (img >= lowThreshold)) res[strong_i, strong_j] = strong res[weak_i, weak_j] = weak return (res, weak, strong)

此步驟的結果是只有2個像素強度值(強弱)的圖像:

非最大抑制圖像(左) - 閾值結果(右)

滯后邊緣跟蹤

根據閾值結果,當且僅當被處理像素周圍至少有一個像素為強像素時,滯后由弱像素轉換為強像素構成,如下所述:

def hysteresis(img, weak, strong=255): M, N = img.shape for i in range(1, M-1): for j in range(1, N-1): if (img[i,j] == weak): try: if ((img[i+1, j-1] == strong) or (img[i+1, j] == strong) or (img[i+1, j+1] == strong) or (img[i, j-1] == strong) or (img[i, j+1] == strong) or (img[i-1, j-1] == strong) or (img[i-1, j] == strong) or (img[i-1, j+1] == strong)): img[i, j] = strong else: img[i, j] = 0 except IndexError as e: pass return img

總結

以上是生活随笔為你收集整理的candy算子python_Python-计算机视觉中的Canny边缘检测方法的全部內容,希望文章能夠幫你解決所遇到的問題。

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