Python圖像運(yùn)算之圖像銳化和邊緣檢測(cè)
一.圖像銳化
由于收集圖像數(shù)據(jù)的器件或傳輸圖像的通道存在一些質(zhì)量缺陷,或者受其他外界因素的影響,使得圖像存在模糊和有噪聲的情況,從而影響到圖像識(shí)別工作的開(kāi)展。一般來(lái)說(shuō),圖像的能量主要集中在其低頻部分,噪聲所在的頻段主要在高頻段,同時(shí)圖像邊緣信息主要集中在其高頻部分。這將導(dǎo)致原始圖像在平滑處理之后,圖像邊緣和圖像輪廓模糊的情況出現(xiàn)。為了減少這類不利效果的影響,就需要利用圖像銳化技術(shù),使圖像的邊緣變得清晰。
圖像銳化處理的目的是為了使圖像的邊緣、輪廓線以及圖像的細(xì)節(jié)變得清晰,經(jīng)過(guò)平滑的圖像變得模糊的根本原因是圖像受到了平均或積分運(yùn)算,因此可以對(duì)其進(jìn)行逆運(yùn)算,從而使圖像變得清晰。微分運(yùn)算是求信號(hào)的變化率,具有較強(qiáng)高頻分量作用。從頻率域來(lái)考慮,圖像模糊的實(shí)質(zhì)是因?yàn)槠涓哳l分量被衰減,因此可以用高通濾波器來(lái)使圖像清晰。但要注意能夠進(jìn)行銳化處理的圖像必須有較高的性噪比,否則銳化后圖像性噪比反而更低,從而使得噪聲增加比信號(hào)還要多,因此一般是先去除或減輕噪聲后再進(jìn)行銳化處理。這時(shí)需要開(kāi)展圖像銳化和邊緣檢測(cè)處理,加強(qiáng)原圖像的高頻部分,銳化突出圖像的邊緣細(xì)節(jié),改善圖像的對(duì)比度,使模糊的圖像變得更清晰。
圖像銳化和邊緣提取技術(shù)可以消除圖像中的噪聲,提取圖像信息中用來(lái)表征圖像的一些變量,為圖像識(shí)別提供基礎(chǔ)。通常使用灰度差分法對(duì)圖像的邊緣、輪廓進(jìn)行處理,將其凸顯。圖像銳化的方法分為高通濾波和空域微分法,本章主要介紹Robert算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr算子等[2-3]。
1.一階微分算子
一階微分算子一般借助空域微分算子通過(guò)卷積完成,但實(shí)際上數(shù)字圖像處理中求導(dǎo)是利用差分近似微分來(lái)進(jìn)行的。梯度對(duì)應(yīng)一階導(dǎo)數(shù),梯度算子是一階導(dǎo)數(shù)算子。對(duì)一個(gè)連續(xù)函數(shù)f(x,y),它在位置(x,y)梯度可表示為一個(gè)矢量:
梯度的模值為公式(2)所示。
梯度的方向在最大變化率方向上,梯度方向如公式(3)所示。
對(duì)于數(shù)字圖像,導(dǎo)數(shù)可以用差分來(lái)近似,則梯度可以表示為:
在實(shí)際中常用區(qū)域模板卷積來(lái)近似計(jì)算,對(duì)水平方向和垂直方向各用一個(gè)模板,再通過(guò)兩個(gè)模板組合起來(lái)構(gòu)成一個(gè)梯度算子。根據(jù)模板的大小,其中元素值的不同,可以提出多種模板,構(gòu)成不同的檢測(cè)算子,后文中將對(duì)各種算子進(jìn)行詳細(xì)介紹。
由梯度的計(jì)算可知,在圖像灰度變化較大的邊沿區(qū)域其梯度值大,在灰度變化平緩的區(qū)域梯度值較小,而在灰度均勻的區(qū)域其梯度值為零。根據(jù)得到的梯度值來(lái)返回像素值,如將梯度值大的像素設(shè)置成白色,梯度值小的設(shè)置為黑色,這樣就可以將邊緣提取出來(lái)了,或者是加強(qiáng)梯度值大的像素灰度值就可以突出細(xì)節(jié)了達(dá)到了銳化的目的。
2.二階微分算子
二階微分算子是求圖像灰度變化導(dǎo)數(shù)的導(dǎo)數(shù),對(duì)圖像中灰度變化強(qiáng)烈的地方很敏感,從而可以突出圖像的紋理結(jié)構(gòu)。當(dāng)圖像灰度變化劇烈時(shí),進(jìn)行一階微分則會(huì)形成一個(gè)局部的極值,對(duì)圖像進(jìn)行二階微分則會(huì)形成一個(gè)過(guò)零點(diǎn),并且在零點(diǎn)兩邊產(chǎn)生一個(gè)波峰和波谷,設(shè)定一個(gè)閾值檢測(cè)到這個(gè)過(guò)零點(diǎn),如圖1所示。
這樣做的好處有兩個(gè),一是二階微分關(guān)心的是圖像灰度的突變而不強(qiáng)調(diào)灰度緩慢變化的區(qū)域,對(duì)邊緣的定位能力更強(qiáng);二是Laplacian算子是各向同性的,即具有旋轉(zhuǎn)不變性,在一階微分里,是用|dx|+|dy|來(lái)近似一個(gè)點(diǎn)的梯度,當(dāng)圖像旋轉(zhuǎn)一個(gè)角度時(shí),這個(gè)值就會(huì)變化,但對(duì)于Laplacian算子來(lái)說(shuō),不管圖像怎么旋轉(zhuǎn),得到的相應(yīng)值是一樣的。
想要確定過(guò)零點(diǎn)要以p為中心的一個(gè)3×3領(lǐng)域,p點(diǎn)為過(guò)零點(diǎn)意味著至少有兩個(gè)相對(duì)的領(lǐng)域像素的符號(hào)不同。有四種要檢測(cè)的情況:左/右、上/下、兩個(gè)對(duì)角。如果g(x,y)的值與一個(gè)閾值比較,那么不僅要求相對(duì)領(lǐng)域的符號(hào)不同,數(shù)值差的絕對(duì)值也要超過(guò)這個(gè)閾值,這時(shí)p稱為一個(gè)過(guò)零點(diǎn)像素。二階微分的定義為:
二階微分在恒定灰度區(qū)域的微分值為零,在灰度臺(tái)階或斜坡起點(diǎn)處微分值非零,沿著斜坡的微分值為零。與一階微分算子相比較,一階微分算子獲得的邊界是比較粗略的邊界,反映的邊界信息較少,但是所反映的邊界比較清晰;二階微分算子獲得的邊界是比較細(xì)致的邊界,反映的邊界信息包括了許多的細(xì)節(jié)信息,但是所反映的邊界不是太清晰。
二.Roberts算子
Roberts算子又稱為交叉微分算法,它是基于交叉差分的梯度算法,通過(guò)局部差分計(jì)算檢測(cè)邊緣線條。常用來(lái)處理具有陡峭的低噪聲圖像,當(dāng)圖像邊緣接近于正45度或負(fù)45度時(shí),該算法處理效果更理想,其缺點(diǎn)是對(duì)邊緣的定位不太準(zhǔn)確,提取的邊緣線條較粗。
Roberts算子的模板分為水平方向和垂直方向,如公式(6)所示,從其模板可以看出,Roberts算子能較好的增強(qiáng)正負(fù)45度的圖像邊緣[4]。
如公式(7)所示,分別表示圖像的水平方向和垂直方向的計(jì)算公式。
Roberts算子像素的最終計(jì)算公式如下:
在Python中,Roberts算子主要通過(guò)Numpy定義模板,再調(diào)用OpenCV的filter2D()函數(shù)實(shí)現(xiàn)邊緣提取[3]。該函數(shù)主要是利用內(nèi)核實(shí)現(xiàn)對(duì)圖像的卷積運(yùn)算,其函數(shù)原型如下所示:
dst = filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
- – src表示輸入圖像
- – dst表示輸出的邊緣圖,其大小和通道數(shù)與輸入圖像相同
- – ddepth表示目標(biāo)圖像所需的深度
- – kernel表示卷積核,一個(gè)單通道浮點(diǎn)型矩陣
- – anchor表示內(nèi)核的基準(zhǔn)點(diǎn),其默認(rèn)值為(-1,-1),位于中心位置
- – delta表示在儲(chǔ)存目標(biāo)圖像前可選的添加到像素的值,默認(rèn)值為0
- – borderType表示邊框模式
在進(jìn)行Roberts算子處理之后,還需要調(diào)用convertScaleAbs()函數(shù)計(jì)算絕對(duì)值,并將圖像轉(zhuǎn)換為8位圖進(jìn)行顯示。其算法原型如下:
dst = convertScaleAbs(src[, dst[, alpha[, beta]]])
- – src表示原數(shù)組
- – dst表示輸出數(shù)組,深度為8位
- – alpha表示比例因子
- – beta表示原數(shù)組元素按比例縮放后添加的值
最后調(diào)用addWeighted()函數(shù)計(jì)算水平方向和垂直方向的Roberts算子。其運(yùn)行代碼如下:
# -*- coding: utf-8 -*- # By:Eastmount import cv2 import numpy as np import matplotlib.pyplot as plt #讀取圖像 img = cv2.imread('luo.png') lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #灰度化處理圖像 grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #Roberts算子 kernelx = np.array([[-1,0],[0,1]], dtype=int) kernely = np.array([[0,-1],[1,0]], dtype=int) x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx) y = cv2.filter2D(grayImage, cv2.CV_16S, kernely) #轉(zhuǎn)uint8 absX = cv2.convertScaleAbs(x) absY = cv2.convertScaleAbs(y) Roberts = cv2.addWeighted(absX,0.5,absY,0.5,0) #用來(lái)正常顯示中文標(biāo)簽 plt.rcParams['font.sans-serif']=['SimHei'] #顯示圖形 titles = ['原始圖像', 'Roberts算子'] images = [lenna_img, Roberts] for i in range(2): plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
其運(yùn)行結(jié)果如圖2所示,左邊為原始圖像,右邊為Roberts算子圖像銳化提取的邊緣輪廓。
三.Prewitt算子
Prewitt是一種圖像邊緣檢測(cè)的微分算子,其原理是利用特定區(qū)域內(nèi)像素灰度值產(chǎn)生的差分實(shí)現(xiàn)邊緣檢測(cè)。由于Prewitt算子采用3×3模板對(duì)區(qū)域內(nèi)的像素值進(jìn)行計(jì)算,而Robert算子的模板為2×2,故Prewitt算子的邊緣檢測(cè)結(jié)果在水平方向和垂直方向均比Robert算子更加明顯。Prewitt算子適合用來(lái)識(shí)別噪聲較多、灰度漸變的圖像,其計(jì)算公式如下所示。
具體的水平和垂直方向計(jì)算公式如下所示:
Prewitt算子像素的最終計(jì)算如公式(11)所示。
在Python中,Prewitt算子的實(shí)現(xiàn)過(guò)程與Roberts算子比較相似。通過(guò)Numpy定義模板,再調(diào)用OpenCV的filter2D()函數(shù)實(shí)現(xiàn)對(duì)圖像的卷積運(yùn)算,最終通過(guò)convertScaleAbs()和addWeighted()函數(shù)實(shí)現(xiàn)邊緣提取,代碼如下所示:
# -*- coding: utf-8 -*- # By:Eastmount import cv2 import numpy as np import matplotlib.pyplot as plt #讀取圖像 img = cv2.imread('luo.png') lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #灰度化處理圖像 grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #Prewitt算子 kernelx = np.array([[1,1,1],[0,0,0],[-1,-1,-1]],dtype=int) kernely = np.array([[-1,0,1],[-1,0,1],[-1,0,1]],dtype=int) x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx) y = cv2.filter2D(grayImage, cv2.CV_16S, kernely) #轉(zhuǎn)uint8 absX = cv2.convertScaleAbs(x) absY = cv2.convertScaleAbs(y) Prewitt = cv2.addWeighted(absX,0.5,absY,0.5,0) #用來(lái)正常顯示中文標(biāo)簽 plt.rcParams['font.sans-serif']=['SimHei'] #顯示圖形 titles = ['原始圖像', 'Prewitt算子'] images = [lenna_img, Prewitt] for i in range(2): plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
最終運(yùn)行結(jié)果如圖3所示,左邊為原始圖像,右邊為Prewitt算子圖像銳化提取的邊緣輪廓,其效果圖的邊緣檢測(cè)結(jié)果在水平方向和垂直方向均比Robert算子更加明顯。
四.總結(jié)
本文主要介紹圖像銳化和邊緣檢測(cè)知識(shí),詳細(xì)講解了Roberts算子和Prewitt算子,并通過(guò)小珞珞圖像進(jìn)行邊緣輪廓提取。圖像銳化和邊緣提取技術(shù)可以消除圖像中的噪聲,提取圖像信息中用來(lái)表征圖像的一些變量,為圖像識(shí)別提供基礎(chǔ)。
以上就是Python圖像運(yùn)算之圖像銳化和邊緣檢測(cè)的詳細(xì)內(nèi)容,更多關(guān)于Python圖像銳化 邊緣檢測(cè)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
對(duì)于Python的框架中一些會(huì)話程序的管理
這篇文章主要介紹了對(duì)于Python的框架中一些會(huì)話程序的管理,會(huì)話的實(shí)現(xiàn)是Python框架的基本功能,本文主要講述了對(duì)其的一些管理維護(hù)要點(diǎn),需要的朋友可以參考下2015-04-04python不相等的兩個(gè)字符串的 if 條件判斷為T(mén)rue詳解
這篇文章主要介紹了python不相等的兩個(gè)字符串的 if 條件判斷為T(mén)rue詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03python不使用for計(jì)算兩組、多個(gè)矩形兩兩間的iou方式
今天小編就為大家分享一篇python不使用for計(jì)算兩組、多個(gè)矩形兩兩間的iou方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-01-01pandas數(shù)據(jù)清洗實(shí)現(xiàn)刪除的項(xiàng)目實(shí)踐
本文主要介紹了pandas數(shù)據(jù)清洗實(shí)現(xiàn)刪除的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06YOLOv5車(chē)牌識(shí)別實(shí)戰(zhàn)教程(八)Web應(yīng)用與API開(kāi)發(fā)
這篇文章主要介紹了YOLOv5車(chē)牌識(shí)別實(shí)戰(zhàn)教程(八)Web應(yīng)用與API開(kāi)發(fā),在這個(gè)教程中,我們將一步步教你如何使用YOLOv5進(jìn)行車(chē)牌識(shí)別,幫助你快速掌握YOLOv5車(chē)牌識(shí)別技能,需要的朋友可以參考下2023-04-04Python數(shù)據(jù)結(jié)構(gòu)與算法之圖結(jié)構(gòu)(Graph)實(shí)例分析
這篇文章主要介紹了Python數(shù)據(jù)結(jié)構(gòu)與算法之圖結(jié)構(gòu)(Graph),結(jié)合實(shí)例形式分析了圖結(jié)構(gòu)的概念、原理、使用方法及相關(guān)操作技巧,需要的朋友可以參考下2017-09-09