日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

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

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

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

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

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

梯度計算;

非最大抑制;

雙閾值;

滯后邊緣跟蹤。

應(yīng)用這些步驟后,您將能夠獲得以下結(jié)果:

左側(cè)的原始圖像 - 右側(cè)的已處理圖像

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

降噪

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

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

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

高斯濾波器核方程

用于生成Gaussian 5x5內(nèi)核的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

應(yīng)用高斯模糊后,我們得到以下結(jié)果:

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

梯度計算

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

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

當(dāng)平滑圖像時,計算導(dǎo)數(shù)Ix和Iy。它可以通過分別用Sobel kernelsKx和Ky分別卷積I來實現(xiàn):

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

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

梯度強(qiáng)度和邊緣方向

下面是Sobel濾鏡應(yīng)用于圖像的方法,以及如何獲得強(qiáng)度和邊緣方向矩陣,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)

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

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

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

非最大抑制

理想情況下,最終的圖像應(yīng)該有細(xì)邊。因此,我們必須執(zhí)行非最大抑制以使邊緣變細(xì)。

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

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

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

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

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

現(xiàn)在讓我們關(guān)注另一個例子:

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

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

根據(jù)角度矩陣的角度值識別邊緣方向;

檢查相同方向的像素是否具有比當(dāng)前處理的像素更高的強(qiáng)度;

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

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

結(jié)果是相同的圖像,但邊緣更薄。然而,我們?nèi)匀豢梢宰⒁獾竭吘壛炼鹊囊恍┳兓?一些像素似乎比其他像素更亮,我們將嘗試在最后兩個步驟中彌補(bǔ)這一缺陷。

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

雙閾值

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

弱像素是具有不足以被視為強(qiáng)的強(qiáng)度值的像素,但是還不足以被認(rèn)為與邊緣檢測不相關(guān)。

其他像素被認(rèn)為與邊緣無關(guān)。

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

低閾值用于識別不相關(guān)的像素(強(qiáng)度低于低閾值)

具有兩個閾值之間的強(qiáng)度的所有像素被標(biāo)記為弱,滯后機(jī)制(下一步驟)將幫助我們識別可被視為強(qiáng)的那些和被認(rèn)為是不相關(guān)的那些。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)

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

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

滯后邊緣跟蹤

根據(jù)閾值結(jié)果,當(dāng)且僅當(dāng)被處理像素周圍至少有一個像素為強(qiáng)像素時,滯后由弱像素轉(zhuǎn)換為強(qiáng)像素構(gòu)成,如下所述:

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

總結(jié)

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

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