首頁 > 軟體

Python如何使用cv2.canny進行影象邊緣檢測

2023-01-31 06:01:46

使用cv2.canny進行影象邊緣檢測

CV2提供了提取影象邊緣的函數canny。

其演演算法思想如下:

  • 1.使用高斯模糊,去除噪音點(cv2.GaussianBlur)
  • 2.灰度轉換(cv2.cvtColor)
  • 3.使用sobel運算元,計算出每個點的梯度大小和梯度方向
  • 4.使用非極大值抑制(只有最大的保留),消除邊緣檢測帶來的雜散效應
  • 5.應用雙閾值,來確定真實和潛在的邊緣
  • 6.通過抑制弱邊緣來完成最終的邊緣檢測

Canny函數的定義如下:

edge = cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient ]]]) 

引數含義如下:

  • image:要檢測的影象
  • threshold1:閾值1(最小值)
  • threshold2:閾值2(最大值),使用此引數進行明顯的邊緣檢測
  • edges:影象邊緣資訊
  • apertureSize:sobel運算元(折積核)大小
  • L2gradient :布林值。
  • True:使用更精確的L2範數進行計算(即兩個方向的導數的平方和再開方)
  • False:使用L1範數(直接將兩個方向導數的絕對值相加)

其中較大的閾值2用於檢測影象中明顯的邊緣,但一般情況下檢測的效果不會那麼完美,邊緣檢測出來是斷斷續續的。所以這時候用較小的第一個閾值用於將這些間斷的邊緣連線起來。

閾值對檢測結果的影響

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('d:\girl.png')
edges = cv2.Canny(img,100,200,apertureSize=3)
edges2 = cv2.Canny(img,100,200,apertureSize=5)
plt.subplot(131),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image1'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(edges2,cmap = 'gray')
plt.title('Edge Image2'), plt.xticks([]), plt.yticks([])
plt.show()

可以看到,在調整threshold1之後,檢測出的邊緣增多了。

sobel運算元對檢測結果的影響

sobel預設的運算元大小是3,擴大運算元,會獲得更多的細節,但是也更能提取影象了。

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('d:\girl.png')
edges = cv2.Canny(img,100,200,apertureSize=3)
edges2 = cv2.Canny(img,100,200,apertureSize=5)
plt.subplot(131),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image1'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(edges2,cmap = 'gray')
plt.title('Edge Image2'), plt.xticks([]), plt.yticks([])
plt.show()

範數對檢測結果的影響

L2gradient=True時,檢測出的邊緣減少了。

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('d:\girl.png')
edges = cv2.Canny(img,100,200,L2gradient=False)
edges2 = cv2.Canny(img,100,200,L2gradient=True)
plt.subplot(131),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image1'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(edges2,cmap = 'gray')
plt.title('Edge Image2'), plt.xticks([]), plt.yticks([])
plt.show()

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com