Python利用OpenCV和skimage實(shí)現(xiàn)圖像邊緣檢測
一、簡介
提取圖片的邊緣信息是底層數(shù)字圖像處理的基本任務(wù)之一。邊緣信息對進(jìn)一步提取高層語義信息有很大的影響。大部分邊緣檢測算法都是上個(gè)世紀(jì)的了,OpenCV 的使用的算法是 Canny 邊緣檢測算法,大概是在 1986 年由 John F. Canny 提出了,似乎說明邊緣檢測算法的研究已經(jīng)到達(dá)了瓶頸期。跟人眼系統(tǒng)相比,邊緣檢測算法仍然遜色不少。
Canny 邊緣檢測算法是比較出色的算法,也是一種多步算法,可用于檢測任何輸入圖像的邊緣。利用它檢測圖像邊緣時(shí)主要有以下步驟:
- 應(yīng)用高斯濾波來平滑圖像,目的是去除噪聲。
- 計(jì)算高斯濾波器的導(dǎo)數(shù),計(jì)算圖像像素的梯度,得到沿x和y維度的梯度。
- 應(yīng)用非最大抑制(non-maximum suppression)技術(shù)來消除邊緣誤檢(本來不是但檢測出來是)
- 應(yīng)用雙閾值的方法來決定可能的(潛在的)邊界
- 利用滯后閾值方法保留高于梯度幅值的像素,忽略低于低閾值的像素,實(shí)現(xiàn)邊緣追蹤。
Canny 的目標(biāo)是找到一個(gè)最優(yōu)的邊緣檢測算法,最優(yōu)邊緣檢測的含義是:
- 最優(yōu)檢測:算法能夠盡可能多地標(biāo)識(shí)出圖像中的實(shí)際邊緣,漏檢真實(shí)邊緣的概率和誤檢非邊緣的概率都盡可能??;
- 最優(yōu)定位準(zhǔn)則:檢測到的邊緣點(diǎn)的位置距離實(shí)際邊緣點(diǎn)的位置最近,或者是由于噪聲影響引起檢測出的邊緣偏離物體的真實(shí)邊緣的程度最?。?/li>
- 檢測點(diǎn)與邊緣點(diǎn)一一對應(yīng):算子檢測的邊緣點(diǎn)與實(shí)際邊緣點(diǎn)應(yīng)該是一一對應(yīng)。
為了滿足這些要求 Canny 使用了變分法(calculus of variations),這是一種尋找優(yōu)化特定功能的函數(shù)的方法。最優(yōu)檢測使用四個(gè)指數(shù)函數(shù)項(xiàng)表示,它可以由高斯函數(shù)的一階導(dǎo)數(shù)來近似。
二、opencv 實(shí)踐
cv2.Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None): # 用自定義梯度 cv2.Canny(dx, dy, threshold1, threshold2[, edges[, L2gradient]]) -> edges
- image:參表示8位輸入圖像
- threshold1:設(shè)置的低閾值
- threshold2:設(shè)置的高閾值
- edges:輸出邊緣圖像,單通道8位圖像
- apertureSize:Sobel算子的大小
- L2gradient:一個(gè)布爾值,如果為真,則使用更精確的 L2 范數(shù)進(jìn)行計(jì)算(即兩個(gè)方向的倒數(shù)的平方和再開方),否則使用 L1 范數(shù)(直接將兩個(gè)方向?qū)?shù)的絕對值相加)。
def opencv_canny(image): # 高斯模糊 降低噪聲 blurred = cv.GaussianBlur(image, (5, 5), 0) # 轉(zhuǎn)為灰度圖像 gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY) # 計(jì)算x y 方向梯度 grad_x = cv.Sobel(gray, cv.CV_16SC1, 1, 0) grad_y = cv.Sobel(gray, cv.CV_16SC1, 0, 1) edge_output = cv.Canny(grad_x, grad_y, 60, 120) # 英文字體 Times New Roman plt.rcParams['font.sans-serif'] = ['Times New Roman'] # 可視化結(jié)果 plt.figure(figsize=(8, 4), dpi=500) plt.subplot(121) plt.imshow(gray, cmap='gray') plt.title('Original Image', fontsize=18) plt.xticks([]), plt.yticks([]) plt.subplot(122) plt.imshow(edge_output, cmap='gray') plt.title('Edge Image', fontsize=18) plt.xticks([]), plt.yticks([]) plt.savefig("002.png", dpi=500) plt.show() if __name__ == "__main__": # 讀取圖像 傳入 src = cv.imread("Lenna.png") opencv_canny(src)
結(jié)果如下:
三、skimage 實(shí)踐
import numpy as np from skimage.io import imread from skimage.feature import canny import matplotlib.pyplot as plt # 讀取圖像 img = imread("Lenna.png", as_gray=True) # 高斯模糊 降低噪聲 img = cv.GaussianBlur(img, (5, 5), 0) # Canny邊緣檢測 edges = canny(img, sigma=1.6) # 可視化結(jié)果 plt.rcParams['font.sans-serif'] = ['Times New Roman'] plt.figure(figsize=(8, 4), dpi=500) plt.subplot(121) plt.imshow(img, cmap='gray') plt.title('Original Image', fontsize=18) plt.xticks([]), plt.yticks([]) plt.subplot(122) plt.imshow(edges, cmap='gray') plt.title('Edge Image', fontsize=18) plt.xticks([]), plt.yticks([]) plt.show()
結(jié)果如下:
import numpy as np import matplotlib.pyplot as plt from scipy import ndimage as ndi from skimage import feature # 產(chǎn)生帶有噪聲的舉行圖案 im = np.zeros((128, 128)) im[32:-32, 32:-32] = 1 im = ndi.rotate(im, 15, mode='constant') # 旋轉(zhuǎn)一定角度 im = ndi.gaussian_filter(im, 4) im += 0.2 * np.random.random(im.shape) # Compute the Canny filter for two values of sigma edges1 = feature.canny(im, sigma=1) edges2 = feature.canny(im, sigma=3) # display results fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, figsize=(8, 4), sharex=True, sharey=True, dpi=500) ax1.imshow(im, cmap=plt.cm.gray) ax1.axis('off') ax1.set_title('Noisy image', fontsize=20) ax2.imshow(edges1, cmap=plt.cm.gray) ax2.axis('off') ax2.set_title(r'Canny filter, $\sigma=1$', fontsize=20) ax3.imshow(edges2, cmap=plt.cm.gray) ax3.axis('off') ax3.set_title(r'Canny filter, $\sigma=3$', fontsize=20) fig.tight_layout() plt.show()
結(jié)果如下:
skimage 庫中函數(shù)
skimage.feature.canny(image, sigma=1.0, low_threshold=None, high_threshold=None, mask=None, use_quantiles=False)
- sigma:高斯濾波器的標(biāo)準(zhǔn)差
- low_threshold:Canny算法最后一步中,小于該閾值的像素直接置為0
- high_threshold:Canny算法最后一步中,大于該閾值的像素直接置為255
以上就是Python利用OpenCV和skimage實(shí)現(xiàn)圖像邊緣檢測的詳細(xì)內(nèi)容,更多關(guān)于Python圖像邊緣檢測的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用python opencv對目錄下圖片進(jìn)行去重的方法
今天小編就為大家分享一篇使用python opencv對目錄下圖片進(jìn)行去重的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01Python使用selenium + headless chrome獲取網(wǎng)頁內(nèi)容的方法示例
這篇文章主要介紹了Python使用selenium + headless chrome獲取網(wǎng)頁內(nèi)容的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10Python實(shí)現(xiàn)抓取頁面上鏈接的簡單爬蟲分享
這篇文章主要介紹了Python實(shí)現(xiàn)抓取頁面上鏈接的簡單爬蟲分享,本文使用了一個(gè)開源模塊requests實(shí)現(xiàn)需求,需要的朋友可以參考下2015-01-01python數(shù)據(jù)可視化JupyterLab實(shí)用擴(kuò)展程序Mito
這篇文章主要為大家介紹了python數(shù)據(jù)可視化JupyterLab實(shí)用擴(kuò)展程序Mito的功能應(yīng)用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11解決python遞歸函數(shù)及遞歸次數(shù)受到限制的問題
這篇文章主要介紹了解決python遞歸函數(shù)及遞歸次數(shù)受到限制的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06