【课题总结】OpenCV 抠图项目实战(7)边缘检测
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(7)
本系列是 Python 小白的課題作業(yè)《基于OpenCV 的圖像分割和摳圖》。
需要說(shuō)明的是,本系列并不能算是 OpenCV 的摳圖項(xiàng)目教程,只是以此為主題的課題報(bào)告。其中包括了一個(gè)較為完整的 PyQt 項(xiàng)目。
歡迎關(guān)注『Python 小白的項(xiàng)目實(shí)戰(zhàn) @ youcans』 原創(chuàng)作品
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(1)目錄摘要
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(2)摳圖緒論
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(3)摳圖綜述
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(4)固定閾值摳圖
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(5)自適應(yīng)閾值摳圖
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(6)色彩范圍摳圖
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(7)邊緣檢測(cè)
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(8)圖像輪廓
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(9)評(píng)價(jià)指標(biāo)
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(10)PyQt5 使用
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(11)算法實(shí)驗(yàn)平臺(tái)
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(12)源程序代碼
第四章 圖像分割
4.1 邊緣檢測(cè)
邊緣是指圖像中兩個(gè)不同區(qū)域的邊界線上連續(xù)的像素點(diǎn)的集合,是圖像局部特征不連續(xù)性的反映,體現(xiàn)了灰度、顏色、紋理等圖像特性的突變。
邊緣檢測(cè)是圖像處理和計(jì)算機(jī)視覺(jué)中的基本問(wèn)題,邊緣檢測(cè)的目的是標(biāo)識(shí)數(shù)字圖像中亮度變化明顯的點(diǎn)。
邊緣的灰度值呈現(xiàn)出階躍型或屋頂型變化。階躍型邊緣兩邊像素點(diǎn)的灰度值存在著明顯的差異,而屋頂型邊緣則位于灰度值上升或下降的轉(zhuǎn)折處。
梯度指出了像素值的最大變化率的方向,使用微分算子可以進(jìn)行邊緣檢測(cè):
- 恒定灰度區(qū)域,一階導(dǎo)數(shù)為零,二階導(dǎo)數(shù)為零;
- 灰度臺(tái)階或斜坡起點(diǎn)區(qū)域,一階導(dǎo)數(shù)非零,,二階導(dǎo)數(shù)非零;
- 灰度斜坡區(qū)域,一階導(dǎo)數(shù)非零,二階導(dǎo)數(shù)為零。
一階導(dǎo)數(shù)、二階導(dǎo)數(shù)的有限差分公式為:
?f/?x=f(x+1)?f(x)(?2f)/(?x2)=f(x+1)?2f(x)+f(x?1)?f/?x=f(x+1)-f(x)\\ (?^2 f)/(?x^2 )=f(x+1)-2f(x)+f(x-1) ?f/?x=f(x+1)?f(x)(?2f)/(?x2)=f(x+1)?2f(x)+f(x?1)
圖像梯度提取方法簡(jiǎn)單直接,能夠有效的描述圖像的原始狀態(tài),因此發(fā)展出多種圖像梯度算子,常用的有Laplacian、Soble和Canny算子。
1. 拉普拉斯算子(Laplacian)
最簡(jiǎn)單的各向同性導(dǎo)數(shù)算子(卷積核)是拉普拉斯算子(Laplacian)。
Laplace 是導(dǎo)數(shù)算子,會(huì)突出圖像中的急劇灰度變化,抑制灰度緩慢變化區(qū)域,往往會(huì)產(chǎn)生暗色背景下的灰色邊緣和不連續(xù)圖像。將拉普拉斯圖像與原圖疊加,可以得到保留銳化效果的圖像。
拉普拉斯卷積核很容易通過(guò)卷積操作 cv. filter_2d 實(shí)現(xiàn),OpenCV 也提供了拉普拉斯算子 cv.Laplacian 來(lái)實(shí)現(xiàn)。
函數(shù)說(shuō)明:
cv.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]]) → dst參數(shù)說(shuō)明:
- src:輸入圖像,可以是灰度圖像,也可以是多通道的彩色圖像
- ddepth:輸出圖片的數(shù)據(jù)深度:
- dst:輸出圖像,大小和類型與 src 相同
- ksize:計(jì)算二階導(dǎo)數(shù)濾波器的孔徑大小,必須為正奇數(shù),可選項(xiàng)
- scale:縮放比例因子,可選項(xiàng),默認(rèn)值為 1
- delta:輸出圖像的偏移量,可選項(xiàng),默認(rèn)值為 0
- borderType:邊界擴(kuò)充的類型,注意不支持對(duì)側(cè)填充(BORDER_WRAP)
使用Laplacian算子進(jìn)行邊緣檢測(cè)的基本程序如下:
# MattingLaplacian.py # edge detection by Laplacian # Copyright 2021 youcans, XUPT # Crated:2021-12-10import cv2 as cv from matplotlib.figure import Figureimg = cv2.imread("../images/Fig0338a.tif", flags=0) # NASA 月球影像圖# 使用 cv2.Laplacian 實(shí)現(xiàn) Laplace 卷積算子 imgLaplace2 = cv2.Laplacian(img, -1, ksize=3) imgRecovery = cv2.add(img, imgLaplace2) # 恢復(fù)原圖像# 二值化邊緣圖再卷積 ret, binary = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_TRIANGLE) imgLaplace3 = cv2.Laplacian(binary, cv2.CV_64F) imgLaplace3 = cv2.convertScaleAbs(imgLaplace3)plt.figure(figsize=(9, 6)) plt.subplot(131), plt.axis('off'), plt.title("Original") plt.imshow(img, cmap='gray', vmin=0, vmax=255) plt.subplot(132), plt.axis('off'), plt.title("cv.Laplacian") plt.imshow(imgLaplace2, cmap='gray', vmin=0, vmax=255) plt.subplot(133), plt.axis('off'), plt.title("thresh-Laplacian") plt.imshow(imgLaplace3, cmap='gray', vmin=0, vmax=255) plt.tight_layout() plt.show()使用Laplacian算子進(jìn)行邊緣檢測(cè)的結(jié)果如下圖所示。
圖4.1 Laplacian算子進(jìn)行邊緣檢測(cè)
2. 索貝爾梯度算子(Sobel)
Sobel 算子是一種離散的微分算子,是高斯平滑和微分求導(dǎo)的聯(lián)合運(yùn)算,抗噪聲能力強(qiáng)。
Sobel 梯度算子利用局部差分尋找邊緣,計(jì)算得到梯度的近似值。先計(jì)算水平、垂直方向的梯度,再求總梯度。編程實(shí)現(xiàn)時(shí),可以用絕對(duì)值近似平方根。
OpenCV 也提供了函數(shù) cv.Sobel() 實(shí)現(xiàn) Sobel 梯度算子。
函數(shù)說(shuō)明:
cv.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]]) → dst參數(shù)說(shuō)明:
- src:輸入圖像,灰度圖像,不適用彩色圖像
- dst:輸出圖像,大小和類型與 src 相同
- ddepth:輸出圖片的數(shù)據(jù)深度,由輸入圖像的深度進(jìn)行選擇
- dx:x 軸方向?qū)?shù)的階數(shù),1 或 2
- dy:y 軸方向?qū)?shù)的階數(shù),1 或 2
- ksize:Sobel算子卷積核的大小
- scale:縮放比例因子,可選項(xiàng),默認(rèn)值為 1
- delta:輸出圖像的偏移量,可選項(xiàng),默認(rèn)值為 0
使用Sobel算子進(jìn)行邊緣檢測(cè)的基本程序如下:
# MattingSobel.py # edge detection by Sobel # Copyright 2021 youcans, XUPT # Crated:2021-12-10import cv2 as cv from matplotlib.figure import Figureimg = cv2.imread("../images/imgGaia.tif", flags=0)# 使用函數(shù) filter2D 實(shí)現(xiàn) Sobel 算子 kernSobelX = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) # SobelX kernel kernSobelY = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]]) # SobelY kernel imgSobelX = cv2.filter2D(img, -1, kernSobelX, borderType=cv2.BORDER_REFLECT) imgSobelY = cv2.filter2D(img, -1, kernSobelY, borderType=cv2.BORDER_REFLECT)# 使用 cv2.Sobel 實(shí)現(xiàn) Sobel 算子 SobelX = cv2.Sobel(img, cv2.CV_16S, 1, 0) # 計(jì)算 x 軸方向 SobelY = cv2.Sobel(img, cv2.CV_16S, 0, 1) # 計(jì)算 y 軸方向 absX = cv2.convertScaleAbs(SobelX) # 轉(zhuǎn)回 uint8 absY = cv2.convertScaleAbs(SobelY) # 轉(zhuǎn)回 uint8 SobelXY = cv2.addWeighted(absX, 0.5, absY, 0.5, 0) # 用絕對(duì)值近似平方根plt.figure(figsize=(10, 6)) plt.subplot(141), plt.axis('off'), plt.title("Original") plt.imshow(img, cmap='gray', vmin=0, vmax=255) plt.subplot(142), plt.axis('off'), plt.title("SobelX") plt.imshow(SobelX, cmap='gray', vmin=0, vmax=255) plt.subplot(143), plt.axis('off'), plt.title("SobelY") plt.imshow(SobelY, cmap='gray', vmin=0, vmax=255) plt.subplot(144), plt.axis('off'), plt.title("SobelXY") plt.imshow(SobelXY, cmap='gray') plt.tight_layout() plt.show()使用Sobel算子進(jìn)行邊緣檢測(cè)的結(jié)果如下圖所示。
圖4.2 Sobel算子進(jìn)行邊緣檢測(cè)
3. Canny 邊緣檢測(cè)
Canny邊緣檢測(cè)是由Jhon F.Canny提出的算法,具有低錯(cuò)誤率、定位良好、最小響應(yīng)的特點(diǎn)。
Canny算子在過(guò)濾噪聲、計(jì)算梯度的同時(shí)實(shí)現(xiàn)非最大值抑制,不容易受噪聲的干擾。采用雙閾值法可以分別檢測(cè)到強(qiáng)邊緣和弱邊緣,并且僅當(dāng)弱邊緣與強(qiáng)邊緣相連時(shí),才將弱邊緣包含在輸出結(jié)果中,這就保障了檢測(cè)到真正的弱邊緣。
Canny算法的工作原理為:
(1)使用高斯濾波器對(duì)圖像進(jìn)行平滑去噪;
(2)計(jì)算輸入圖像梯度;
(3)在邊緣上使用非極大值抑制(NMS)進(jìn)行過(guò)濾;
(4)在檢測(cè)到的邊緣上使用雙閾值法去除假陽(yáng)性;
(5)分析所有的邊緣及其連接,以保留真正的邊緣并消除不明顯的邊緣;
OpenCV 也提供了函數(shù) cv.Sobel() 實(shí)現(xiàn) Sobel 梯度算子。
函數(shù)說(shuō)明:
cv.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]]) → edges參數(shù)說(shuō)明:
- image:輸入圖像,灰度圖像,不適用彩色圖像
- edges:輸出圖像,單通道 8bit圖像,大小與images相同
- threshold1:滯后過(guò)程的較小閾值,用于邊緣連接
- threshold2:滯后過(guò)程的較大閾值,用于查找明顯的邊緣
- apertureSize:Sobel算子的卷積核大小
- L2gradient:標(biāo)志,使用 L1范數(shù)或 L2范數(shù)正則化
使用 Canny()進(jìn)行邊緣檢測(cè)的基本程序如下:
# MattingCanny.py # edge detection by Cann # Copyright 2021 youcans, XUPTy # Crated:2021-12-10import cv2 as cv from matplotlib.figure import FigureimgOri = cv2.imread("../images/imgGaia.tif", flags=0)# canny(): 邊緣檢測(cè) imgBlur = cv2.GaussianBlur(imgOri, (3, 3), 0) imgCanny = cv2.Canny(imgBlur, 50, 150)# 形態(tài)學(xué):邊緣檢測(cè) _, imgThr = cv2.threshold(imgOri, 200, 255, cv2.THRESH_BINARY) # 固定閾值二值化 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) # 定義矩形結(jié)構(gòu)元素 gradient = cv2.morphologyEx(Thr_img, cv2.MORPH_GRADIENT, kernel) # 梯度plt.figure(figsize=(9, 6)) plt.subplot(221), plt.axis('off'), plt.title("Original") plt.imshow(imgOri, cmap='gray', vmin=0, vmax=255) plt.subplot(222), plt.axis('off'), plt.title("GaussianBlur") plt.imshow(imgBlur, cmap='gray', vmin=0, vmax=255) plt.subplot(223), plt.axis('off'), plt.title("Canny detection") plt.imshow(imgCanny, cmap='gray', vmin=0, vmax=255) plt.subplot(224), plt.axis('off'), plt.title("Gradient detection") plt.imshow(gradient, cmap='gray') plt.tight_layout() plt.show()使用Canny算子進(jìn)行邊緣檢測(cè)的結(jié)果如下圖所示。
圖4.3 Canny 算子進(jìn)行邊緣檢測(cè)
【本節(jié)完】
版權(quán)聲明:
歡迎關(guān)注『Python 小白的項(xiàng)目實(shí)戰(zhàn) @ youcans』 原創(chuàng)作品
原創(chuàng)作品,轉(zhuǎn)載必須標(biāo)注原文鏈接:https://blog.csdn.net/youcans/article/details/122296231
Copyright 2022 youcans, XUPT
Crated:2022-01-05
歡迎關(guān)注『Python 小白的項(xiàng)目實(shí)戰(zhàn) @ youcans』 原創(chuàng)作品
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(1)目錄摘要
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(2)摳圖緒論
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(3)摳圖綜述
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(4)固定閾值摳圖
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(5)自適應(yīng)閾值摳圖
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(6)色彩范圍摳圖
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(7)邊緣檢測(cè)
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(8)圖像輪廓
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(9)評(píng)價(jià)指標(biāo)
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(10)PyQt5 使用
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(11)算法實(shí)驗(yàn)平臺(tái)
Python 小白的課題報(bào)告—OpenCV 摳圖項(xiàng)目實(shí)戰(zhàn)(12)源程序代碼
總結(jié)
以上是生活随笔為你收集整理的【课题总结】OpenCV 抠图项目实战(7)边缘检测的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: html页div引入pano2显示一半,
- 下一篇: 从一个点云里面创建一个深度图