国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

python實(shí)現(xiàn)Canny算子邊緣檢測(cè)算法

這篇具有很好參考價(jià)值的文章主要介紹了python實(shí)現(xiàn)Canny算子邊緣檢測(cè)算法。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

? ? 邊緣檢測(cè)是一種將圖片中關(guān)鍵信息表現(xiàn)出來(lái)的一種圖片技術(shù),它的結(jié)果并不是字面意思上的獲取圖片邊緣,而是將圖片有用的信息勾勒出來(lái),類似素描的結(jié)果,但是已經(jīng)去掉了很多信息。如下所示,一張?jiān)嫉膱D片是這樣的:

? ??python實(shí)現(xiàn)Canny算子邊緣檢測(cè)算法

? ? 通過(guò)邊緣檢測(cè)算法,我們最終得到的圖片可能是這樣的:

python實(shí)現(xiàn)Canny算子邊緣檢測(cè)算法

? ? 雖然丟掉了顏色和很多細(xì)節(jié),但是這張圖片從輪廓山仍然可以看出是模特lenna。

? ? 邊緣檢測(cè)算法有很多實(shí)現(xiàn)方式,結(jié)果也不盡相同,其中最常見的就是Canny算子的邊緣檢測(cè)算法,Canny邊緣檢測(cè)算法大致描述如下:? ?.

  1. ? ? ?灰度化
  2. ? ? ?應(yīng)用高斯濾波去除噪聲
  3. ? ? ?計(jì)算圖像強(qiáng)度梯度和方向
  4. ? ? ?非極大值抑制 non-max-suppresion
  5. ? ? ?雙閾值跟蹤邊界

? ? opencv庫(kù)提供了Canny算法,可以很方便的進(jìn)行邊緣檢測(cè),代碼如下:

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('lenna.png', 0)
# 灰度
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 高斯濾波 卷積 3 * 3
img_blur = cv2.GaussianBlur(img_gray, (3, 3), 0)
# x梯度
xgrad = cv2.Sobel(img_blur, cv2.CV_16SC1, 1, 0)
# y梯度
ygrad = cv2.Sobel(img_blur, cv2.CV_16SC1, 0, 1)
# 使用梯度參數(shù)進(jìn)行邊緣檢測(cè) 閾值 50 ~ 150
edge1 = cv2.Canny(xgrad, ygrad, 50, 150)
# 直接用高斯濾波結(jié)果進(jìn)行邊緣檢測(cè) 閾值 50 ~ 150
edge2 = cv2.Canny(img_blur, 50, 150)
cv2.imshow('origin image', img)
cv2.imshow('edge image', edge1)
cv2.imshow('edge image2', edge2)
cv2.waitKey()

? ? 這段代碼大致意思是先加載lenna.png,然后轉(zhuǎn)灰度,高斯濾波平滑圖片,計(jì)算梯度,使用Canny算法邊緣檢測(cè)。

? ? 算法運(yùn)行結(jié)果:

python實(shí)現(xiàn)Canny算子邊緣檢測(cè)算法

? ?根據(jù)上面提到的算法步驟,以及一些理論公式,其實(shí)這個(gè)有很多直接使用python代碼實(shí)現(xiàn)的Canny算子邊緣檢測(cè)算法,如下所示,這些函數(shù)分別都是根據(jù)上面的算法步驟進(jìn)行整理的:

import numpy as np
import math
import cv2


# 灰度化
def gray(img_path):
    """
    計(jì)算公式:
    Gray(i,j) = 0.299 * R(i,j) + 0.587 * G(i,j) + 0.114 * B(i,j)
    """

    # 讀取圖片
    img = cv2.imread(img_path, 0)
    # BGR 轉(zhuǎn)換成 RGB 格式
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    # 灰度化
    img_gray = np.dot(img_rgb[..., :3], [0.299, 0.587, 0.114])
    return img_gray


# 去除噪音 - 使用 5x5 的高斯濾波器
def smooth(img_gray):
    # 生成高斯濾波器
    """
    要生成一個(gè) (2k+1)x(2k+1) 的高斯濾波器,濾波器的各個(gè)元素計(jì)算公式如下:
    H[i, j] = (1/(2*pi*sigma**2))*exp(-1/2*sigma**2((i-k-1)**2 + (j-k-1)**2))
    """
    sigma1 = sigma2 = 1.4
    gau_sum = 0
    gaussian = np.zeros([5, 5])
    for i in range(5):
        for j in range(5):
            gaussian[i, j] = math.exp((-1 / (2 * sigma1 * sigma2)) * (np.square(i - 3) + np.square(j - 3))) / (
                    2 * math.pi * sigma1 * sigma2)
            gau_sum = gau_sum + gaussian[i, j]

    # 歸一化處理
    gaussian = gaussian / gau_sum

    # 高斯濾波
    W, H = img_gray.shape
    new_gray = np.zeros([W - 5, H - 5])

    for i in range(W - 5):
        for j in range(H - 5):
            new_gray[i, j] = np.sum(img_gray[i:i + 5, j:j + 5] * gaussian)

    return new_gray


# 計(jì)算梯度幅值
def gradients(new_gray):
    """
    :type: image which after smooth
    :rtype:
        dx: gradient in the x direction
        dy: gradient in the y direction
        M: gradient magnitude
        theta: gradient direction
    """
    W, H = new_gray.shape
    dx = np.zeros([W - 1, H - 1])
    dy = np.zeros([W - 1, H - 1])
    M = np.zeros([W - 1, H - 1])

    for i in range(W - 1):
        for j in range(H - 1):
            dx[i, j] = new_gray[i + 1, j] - new_gray[i, j]
            dy[i, j] = new_gray[i, j + 1] - new_gray[i, j]
            # 圖像梯度幅值作為圖像強(qiáng)度值
            M[i, j] = np.sqrt(np.square(dx[i, j]) + np.square(dy[i, j]))
    return dx, dy, M


def NMS(M, dx, dy):
    d = np.copy(M)
    W, H = M.shape
    NMS = np.copy(d)
    NMS[0, :] = NMS[W - 1, :] = NMS[:, 0] = NMS[:, H - 1] = 0
    for i in range(1, W - 1):
        for j in range(1, H - 1):
            # 如果當(dāng)前梯度為0,該點(diǎn)就不是邊緣點(diǎn)
            if M[i, j] == 0:
                NMS[i, j] = 0
            else:
                gradX = dx[i, j]  # 當(dāng)前點(diǎn) x 方向?qū)?shù)
                gradY = dy[i, j]  # 當(dāng)前點(diǎn) y 方向?qū)?shù)
                gradTemp = d[i, j]  # 當(dāng)前梯度點(diǎn)

                # 如果 y 方向梯度值比較大,說(shuō)明導(dǎo)數(shù)方向趨向于 y 分量
                if np.abs(gradY) > np.abs(gradX):
                    weight = np.abs(gradX) / np.abs(gradY)  # 權(quán)重
                    grad2 = d[i - 1, j]
                    grad4 = d[i + 1, j]

                    # 如果 x, y 方向?qū)?shù)符號(hào)一致
                    # 像素點(diǎn)位置關(guān)系
                    # g1  g2
                    #     c
                    #     g4  g3

                    if gradX * gradY > 0:
                        grad1 = d[i - 1, j - 1]
                        grad3 = d[i + 1, j + 1]

                    # 如果 x,y 方向?qū)?shù)符號(hào)相反
                    # 像素點(diǎn)位置關(guān)系
                    #     g2  g1
                    #     c
                    # g3  g4

                    else:
                        grad1 = d[i - 1, j + 1]
                        grad3 = d[i + 1, j - 1]

                # 如果 x 方向梯度值比較大
                else:
                    weight = np.abs(gradY) / np.abs(gradX)
                    grad2 = d[i, j - 1]
                    grad4 = d[i, j + 1]

                    # 如果 x, y 方向?qū)?shù)符號(hào)一致
                    # 像素點(diǎn)位置關(guān)系
                    #      g3
                    # g2 c g4
                    # g1
                    if gradX * gradY > 0:
                        grad1 = d[i + 1, j - 1]
                        grad3 = d[i - 1, j + 1]

                    # 如果 x,y 方向?qū)?shù)符號(hào)相反
                    # 像素點(diǎn)位置關(guān)系
                    # g1
                    # g2 c g4
                    #      g3
                    else:
                        grad1 = d[i - 1, j - 1]
                        grad3 = d[i + 1, j + 1]

                # 利用 grad1-grad4 對(duì)梯度進(jìn)行插值
                gradTemp1 = weight * grad1 + (1 - weight) * grad2
                gradTemp2 = weight * grad3 + (1 - weight) * grad4

                # 當(dāng)前像素的梯度是局部的最大值,可能是邊緣點(diǎn)
                if gradTemp >= gradTemp1 and gradTemp >= gradTemp2:
                    NMS[i, j] = gradTemp
                else:
                    # 不可能是邊緣點(diǎn)
                    NMS[i, j] = 0

    return NMS


def double_threshold(NMS):
    W, H = NMS.shape
    DT = np.zeros([W, H])

    # 定義高低閾值
    TL = 0.1 * np.max(NMS)
    TH = 0.3 * np.max(NMS)

    for i in range(1, W - 1):
        for j in range(1, H - 1):
            # 雙閾值選取
            if (NMS[i, j] < TL):
                DT[i, j] = 0
            elif (NMS[i, j] > TH):
                DT[i, j] = 1
            # 連接
            elif (NMS[i - 1, j - 1:j + 1] < TH).any() or (
                    NMS[i + 1, j - 1:j + 1].any() or (NMS[i, [j - 1, j + 1]] < TH).any()):
                DT[i, j] = 1
    return DT


def canny(img):
    img_gray = gray(img)
    new_gray = smooth(img_gray)
    dx, dy, M = gradients(new_gray)
    nms = NMS(M, dx, dy)
    return double_threshold(nms)


if __name__ == '__main__':
    img_url = 'lenna.png'
    img = cv2.imread(img_url)
    edgedetect = canny(img_url)
    img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    img_blur = cv2.GaussianBlur(img_gray, (3, 3), 0)
    cv2.imshow('origin img', img)
    opencvedge = cv2.Canny(img_blur, 50, 150)
    cv2.imshow('opencv edge', opencvedge)
    cv2.imshow('python edge', edgedetect)
    cv2.waitKey()

? ? 算法運(yùn)行結(jié)果;

python實(shí)現(xiàn)Canny算子邊緣檢測(cè)算法

? ? 我們通過(guò)python算法實(shí)現(xiàn)的邊緣檢測(cè),線條好像不是很光滑,雖然輪廓是出來(lái)了,但是線條很糙。這其實(shí)是代碼里面一個(gè)計(jì)算梯度的地方正好寫反了。

python實(shí)現(xiàn)Canny算子邊緣檢測(cè)算法

? ? 我們調(diào)整代碼如下:

dx[i, j] = new_gray[i, j + 1] - new_gray[i, j]
dy[i, j] = new_gray[i + 1, j] - new_gray[i, j]

執(zhí)行結(jié)果如下;

python實(shí)現(xiàn)Canny算子邊緣檢測(cè)算法

雖然結(jié)果與opencv Canny算法結(jié)果有些差別,但是線條明顯光滑了很多,比之前的結(jié)果要好。?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-473639.html

到了這里,關(guān)于python實(shí)現(xiàn)Canny算子邊緣檢測(cè)算法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • OpenCV(7):邊緣檢測(cè)之Sobel算子,Scharr算子,Laplacian算子和Canny算子邊緣檢測(cè)

    OpenCV(7):邊緣檢測(cè)之Sobel算子,Scharr算子,Laplacian算子和Canny算子邊緣檢測(cè)

    Sobel算子、Scharr算子、Laplacian算子和Canny算子都是常用的圖像邊緣檢測(cè)算法。它們可以用來(lái)識(shí)別圖像中物體之間的邊界,從而對(duì)物體進(jìn)行定位、跟蹤、分割、識(shí)別等處理。 Sobel算子和Scharr算子都是基于卷積運(yùn)算實(shí)現(xiàn)的邊緣檢測(cè)算法。Sobel算子使用兩個(gè)3×3的矩陣對(duì)原始圖像進(jìn)行卷

    2024年02月05日
    瀏覽(28)
  • opencv(23) Canny邊緣檢測(cè)流程(Canny算子)

    opencv(23) Canny邊緣檢測(cè)流程(Canny算子)

    Canny 邊緣檢測(cè)算法 是 John F. Canny 于 1986年開發(fā)出來(lái)的一個(gè)多級(jí)邊緣檢測(cè)算法,也被很多人認(rèn)為是邊緣檢測(cè)的 最優(yōu)算法 , 最優(yōu)邊緣檢測(cè)的三個(gè)主要評(píng)價(jià)標(biāo)準(zhǔn)是: 低錯(cuò)誤率: 標(biāo)識(shí)出盡可能多的實(shí)際邊緣,同時(shí)盡可能的減少噪聲產(chǎn)生的誤報(bào)。 高定位性: 標(biāo)識(shí)出的邊緣要與圖像中的實(shí)

    2024年04月11日
    瀏覽(30)
  • OpenCV 筆記(12):常用的邊緣檢測(cè)算子—— Canny

    OpenCV 筆記(12):常用的邊緣檢測(cè)算子—— Canny

    一階導(dǎo)數(shù)、二階導(dǎo)數(shù)的邊緣算子雖然簡(jiǎn)單易用,但存在一些缺點(diǎn)。例如容易受噪聲影響,容易產(chǎn)生虛假邊緣。 John F. Canny 在 1986 年提出了 Canny 邊緣檢測(cè)算法。它是結(jié)合了梯度計(jì)算方法和非極大值抑制技術(shù)的一種邊緣檢測(cè)算法。該算法克服了之前的邊緣檢測(cè)算法在抑制噪聲和保

    2024年02月03日
    瀏覽(20)
  • 我在Vscode學(xué)OpenCV 圖像處理三(圖像梯度--邊緣檢測(cè)【圖像梯度、Sobel 算子、 Scharr 算子、 Laplacian 算子、Canny 邊緣檢測(cè)】)

    我在Vscode學(xué)OpenCV 圖像處理三(圖像梯度--邊緣檢測(cè)【圖像梯度、Sobel 算子、 Scharr 算子、 Laplacian 算子、Canny 邊緣檢測(cè)】)

    這里需要區(qū)分開邊緣檢測(cè)和輪廓檢測(cè) 邊緣檢測(cè)并非萬(wàn)能,邊緣檢測(cè)雖然能夠檢測(cè)出邊緣,但邊緣是不連續(xù)的,檢測(cè)到的邊緣并不是一個(gè)整體。圖像輪廓是指將邊緣連接起來(lái)形成的一個(gè)整體,用于后續(xù)的計(jì)算。 OpenCV 提供了查找圖像輪廓的函數(shù) cv2.findContours(),該函數(shù)能夠查找圖

    2024年02月04日
    瀏覽(27)
  • Halcon邊緣檢測(cè)Sobel、Laplace和Canny算子

    Halcon邊緣檢測(cè)Sobel、Laplace和Canny算子

    提示:文章參考了網(wǎng)絡(luò)上其他作者的文章,以及相關(guān)書籍,如有侵權(quán),請(qǐng)聯(lián)系作者。 ???????除了閾值分割外,也可以通過(guò)檢測(cè)區(qū)域的邊緣得到目標(biāo)區(qū)域。區(qū)域的邊緣像素的灰度值往往會(huì)發(fā)生灰度上的突變,針對(duì)這些跳躍性的突變進(jìn)行檢測(cè)和計(jì)算,可以得到區(qū)域的邊緣輪廓

    2023年04月08日
    瀏覽(21)
  • Halcon經(jīng)典的邊緣檢測(cè)算子Sobel/Laplace/Canny

    關(guān)于邊緣檢測(cè),有許多經(jīng)典的算子,各大圖形處理庫(kù)都有各自的邊緣檢測(cè)算子,這里簡(jiǎn)要介紹幾種。 Sobel算子結(jié)合了高斯平滑和微分求導(dǎo)。它是一階導(dǎo)數(shù)的邊緣檢測(cè)算子,使用卷積核對(duì)圖像中的每個(gè)像素點(diǎn)做卷積和運(yùn)算,然后采用合適的閾值提取邊緣。Soble算子有兩個(gè)卷積核

    2024年01月22日
    瀏覽(21)
  • OpenCV 入門教程:Laplacian算子和Canny邊緣檢測(cè)

    邊緣檢測(cè)在圖像處理和計(jì)算機(jī)視覺領(lǐng)域中起著重要的作用。 Laplacian 算子和 Canny 邊緣檢測(cè)是兩種常用的邊緣檢測(cè)方法,它們能夠幫助我們準(zhǔn)確地檢測(cè)圖像中的邊緣信息。 OpenCV 提供了這

    2024年02月13日
    瀏覽(21)
  • openCV實(shí)戰(zhàn)-系列教程5:邊緣檢測(cè)(Canny邊緣檢測(cè)/高斯濾波器/Sobel算子/非極大值抑制/線性插值法/梯度方向/雙閾值檢測(cè) )、原理解析、源碼解讀
?????OpenCV實(shí)戰(zhàn)系列總目錄

    openCV實(shí)戰(zhàn)-系列教程5:邊緣檢測(cè)(Canny邊緣檢測(cè)/高斯濾波器/Sobel算子/非極大值抑制/線性插值法/梯度方向/雙閾值檢測(cè) )、原理解析、源碼解讀 ?????OpenCV實(shí)戰(zhàn)系列總目錄

    打印一個(gè)圖片可以做出一個(gè)函數(shù): Canny是一個(gè)科學(xué)家在1986年寫了一篇論文,所以用自己的名字來(lái)命名這個(gè)檢測(cè)算法,Canny邊緣檢測(cè)算法這里寫了5步流程,會(huì)用到之前《openCV實(shí)戰(zhàn)-系列教程》的內(nèi)容。? 使用高斯濾波器,以平滑圖像,濾除噪聲。 計(jì)算圖像中每個(gè)像素點(diǎn)的梯度強(qiáng)

    2024年02月11日
    瀏覽(23)
  • Canny邊緣檢測(cè)算法

    Canny邊緣檢測(cè)算法

    Canny是目前最優(yōu)秀的邊緣檢測(cè)算法之一,在傳統(tǒng)機(jī)器學(xué)習(xí)算法當(dāng)中,Canny是最優(yōu)秀的算法,但是有深度學(xué)習(xí)的方法要比Canny好。Canny算法的目標(biāo)是找到一個(gè)最優(yōu)的邊緣,其最優(yōu)邊緣的定義為: 好的檢測(cè):算法能夠盡可能的標(biāo)出圖像中的實(shí)際邊緣 好的定位:標(biāo)識(shí)出的邊緣要與實(shí)際

    2024年02月09日
    瀏覽(13)
  • OpenCV——Canny邊緣檢測(cè)算法

    OpenCV——Canny邊緣檢測(cè)算法

    圖像分割是將數(shù)字圖像細(xì)分為多個(gè)子區(qū)域的過(guò)程,在計(jì)算機(jī)視覺/機(jī)器視覺領(lǐng)域被廣泛應(yīng)用。它的目的是簡(jiǎn)化或改變圖像的表示形式,以便更容易理解和分析。常見的圖像分割方法包括閾值處理、聚類法、邊緣檢測(cè)和區(qū)域生長(zhǎng)等。解決圖像分割問題通常需要結(jié)合領(lǐng)域知識(shí),以提

    2024年04月17日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包