天天看點

【OpenCV + Python】Canny 邊緣檢測

對平滑後的圖像使用Sobel 算子計算水準方向和豎直方向的一階導數(圖像梯度)(Gx 和Gy)。根據得到的這兩幅梯度圖(Gx 和Gy)找到邊界的梯度和方向,梯度的方向一般總是與邊界垂直。梯度方向被歸為四類:垂直,水準,和兩個對角線。

【OpenCV + Python】Canny 邊緣檢測

在獲得梯度的方向和大小之後,應該對整幅圖像做一個掃描,去除那些非邊界上的點。對每一個像素進行檢查,看這個點的梯度是不是周圍具有相同梯度方向的點中最大的。

現在要确定那些邊界才是真正的邊界。這時我們需要設定兩個門檻值:minVal 和maxVal。當圖像的灰階梯度高于maxVal 時被認為是真的邊界,那些低于minVal 的邊界會被抛棄。如果介于兩者之間的話,就要看這個點是否與某個被确定為真正的邊界點相連,如果是就認為它也是邊界點,如果不是就抛棄。

【OpenCV + Python】Canny 邊緣檢測

A 高于門檻值maxVal 是以是真正的邊界點,C 雖然低于maxVal 但高于minVal 并且與A 相連,是以也被認為是真正的邊界點。而B 就會被抛棄,因為他不僅低于maxVal 而且不與真正的邊界點相連。是以選擇合适的maxVal和minVal 對于能否得到好的結果非常重要。在這一步一些小的噪聲點也會被除去,因為我們假設邊界都是一些長的線段。

在OpenCV 中隻需要一個函數:cv2.Canny(),就可以完成以上幾步。讓我們看如何使用這個函數。這個函數的第一個參數是輸入圖像。第二和第三個分别是minVal 和maxVal。第三個參數設定用來計算圖像梯度的Sobel卷積核的大小,預設值為3。 最後一個參數是L2gradient,它可以用來設定求梯度大小的方程。如果設為True(L2gradient參數表示L2gradient參數表示一個布爾值,如果為真,則使用更精确的L2範數進行計算(即兩個方向的倒數的平方和再開方),否則使用L1範數(直接将兩個方向導數的絕對值相加),就會使用我們上面提到過的方程,否則使用方程:

【OpenCV + Python】Canny 邊緣檢測

代替,預設值為False。

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('1.png',0)
edges = cv2.Canny(img,100,200,3)
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()
           
【OpenCV + Python】Canny 邊緣檢測
#Canny邊緣提取
import cv2 as cv
def edge_demo(image):
    blurred = cv.GaussianBlur(image, (3, 3), 0)
    gray = cv.cvtColor(blurred, cv.COLOR_RGB2GRAY)
    # xgrad = cv.Sobel(gray, cv.CV_16SC1, 1, 0) #x方向梯度
    # ygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1) #y方向梯度
    # edge_output = cv.Canny(xgrad, ygrad, 50, 150)
    edge_output = cv.Canny(gray, 50, 150)
    cv.imshow("Canny Edge", edge_output)
    dst = cv.bitwise_and(image, image, mask= edge_output)
    cv.imshow("Color Edge", dst)
src = cv.imread('E:/imageload/liu.jpg')
cv.namedWindow('input_image', cv.WINDOW_NORMAL) #設定為WINDOW_NORMAL可以任意縮放
cv.imshow('input_image', src)
edge_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
           
【OpenCV + Python】Canny 邊緣檢測

應用場景,使用步驟:

①高斯模糊 - GaussianBlur

②灰階轉換 - cvtColor

③計算梯度 – Sobel/Scharr

④非最大信号抑制

⑤高低門檻值輸出二值圖像