摘要:影像銳化和邊緣提取技術可以消除影像中的噪聲,提取影像資訊中用來表征影像的一些變數,為影像識別提供基礎,本章主要介紹Robert算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr算子等,
本文分享自華為云社區《[Python從零到壹] 五十七.影像增強及運算篇之影像銳化Roberts、Prewitt算子實作邊緣檢測》,作者: eastmount ,
一.影像銳化
由于收集影像資料的器件或傳輸影像的通道存在一些質量缺陷,或者受其他外界因素的影響,使得影像存在模糊和有噪聲的情況,從而影響到影像識別作業的開展,一般來說,影像的能量主要集中在其低頻部分,噪聲所在的頻段主要在高頻段,同時影像邊緣資訊主要集中在其高頻部分,這將導致原始影像在平滑處理之后,影像邊緣和影像輪廓模糊的情況出現,為了減少這類不利效果的影響,就需要利用影像銳化技術,使影像的邊緣變得清晰[1],
影像銳化處理的目的是為了使影像的邊緣、輪廓線以及影像的細節變得清晰,經過平滑的影像變得模糊的根本原因是影像受到了平均或積分運算,因此可以對其進行逆運算,從而使影像變得清晰,微分運算是求信號的變化率,具有較強高頻分量作用,從頻率域來考慮,影像模糊的實質是因為其高頻分量被衰減,因此可以用高通濾波器來使影像清晰,但要注意能夠進行銳化處理的影像必須有較高的性噪比,否則銳化后影像性噪比反而更低,從而使得噪聲增加比信號還要多,因此一般是先去除或減輕噪聲后再進行銳化處理,這時需要開展影像銳化和邊緣檢測處理,加強原影像的高頻部分,銳化突出影像的邊緣細節,改善影像的對比度,使模糊的影像變得更清晰,
影像銳化和邊緣提取技術可以消除影像中的噪聲,提取影像資訊中用來表征影像的一些變數,為影像識別提供基礎,通常使用灰度差分法對影像的邊緣、輪廓進行處理,將其凸顯,影像銳化的方法分為高通濾波和空域微分法,本章主要介紹Robert算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr算子等[2-3],
1.一階微分算子
一階微分算子一般借助空域微分算子通過卷積完成,但實際上數字影像處理中求導是利用差分近似微分來進行的,梯度對應一階導數,梯度算子是一階導數算子,對一個連續函式f(x,y),它在位置(x,y)梯度可表示為一個矢量:
梯度的模值為公式(2)所示,
梯度的方向在最大變化率方向上,梯度方向如公式(3)所示,
對于數字影像,導數可以用差分來近似,則梯度可以表示為:
在實際中常用區域模板卷積來近似計算,對水平方向和垂直方向各用一個模板,再通過兩個模板組合起來構成一個梯度算子,根據模板的大小,其中元素值的不同,可以提出多種模板,構成不同的檢測算子,后文中將對各種算子進行詳細介紹,
由梯度的計算可知,在影像灰度變化較大的邊沿區域其梯度值大,在灰度變化平緩的區域梯度值較小,而在灰度均勻的區域其梯度值為零,根據得到的梯度值來回傳像素值,如將梯度值大的像素設定成白色,梯度值小的設定為黑色,這樣就可以將邊緣提取出來了,或者是加強梯度值大的像素灰度值就可以突出細節了達到了銳化的目的,
2.二階微分算子
二階微分算子是求影像灰度變化導數的導數,對影像中灰度變化強烈的地方很敏感,從而可以突出影像的紋理結構,當影像灰度變化劇烈時,進行一階微分則會形成一個區域的極值,對影像進行二階微分則會形成一個過零點,并且在零點兩邊產生一個波峰和波谷,設定一個閾值檢測到這個過零點,如圖1所示,
這樣做的好處有兩個,一是二階微分關心的是影像灰度的突變而不強調灰度緩慢變化的區域,對邊緣的定位能力更強;二是Laplacian算子是各向同性的,即具有旋轉不變性,在一階微分里,是用|dx|+|dy|來近似一個點的梯度,當影像旋轉一個角度時,這個值就會變化,但對于Laplacian算子來說,不管影像怎么旋轉,得到的相應值是一樣的,
想要確定過零點要以p為中心的一個3×3領域,p點為過零點意味著至少有兩個相對的領域像素的符號不同,有四種要檢測的情況:左/右、上/下、兩個對角,如果g(x,y)的值與一個閾值比較,那么不僅要求相對領域的符號不同,數值差的絕對值也要超過這個閾值,這時p稱為一個過零點像素,二階微分的定義為:
二階微分在恒定灰度區域的微分值為零,在灰度臺階或斜坡起點處微分值非零,沿著斜坡的微分值為零,與一階微分算子相比較,一階微分算子獲得的邊界是比較粗略的邊界,反映的邊界資訊較少,但是所反映的邊界比較清晰;二階微分算子獲得的邊界是比較細致的邊界,反映的邊界資訊包括了許多的細節資訊,但是所反映的邊界不是太清晰,
二.Roberts算子
Roberts算子又稱為交叉微分演算法,它是基于交叉差分的梯度演算法,通過區域差分計算檢測邊緣線條,常用來處理具有陡峭的低噪聲影像,當影像邊緣接近于正45度或負45度時,該演算法處理效果更理想,其缺點是對邊緣的定位不太準確,提取的邊緣線條較粗,
Roberts算子的模板分為水平方向和垂直方向,如公式(6)所示,從其模板可以看出,Roberts算子能較好的增強正負45度的影像邊緣[4],
如公式(7)所示,分別表示影像的水平方向和垂直方向的計算公式,
Roberts算子像素的最終計算公式如下:
在Python中,Roberts算子主要通過Numpy定義模板,再呼叫OpenCV的filter2D()函式實作邊緣提取[3],該函式主要是利用內核實作對影像的卷積運算,其函式原型如下所示:
- dst = filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
– src表示輸入影像
– dst表示輸出的邊緣圖,其大小和通道數與輸入影像相同
– ddepth表示目標影像所需的深度
– kernel表示卷積核,一個單通道浮點型矩陣
– anchor表示內核的基準點,其默認值為(-1,-1),位于中心位置
– delta表示在儲存目標影像前可選的添加到像素的值,默認值為0
– borderType表示邊框模式
在進行Roberts算子處理之后,還需要呼叫convertScaleAbs()函式計算絕對值,并將影像轉換為8位圖進行顯示,其演算法原型如下:
- dst = convertScaleAbs(src[, dst[, alpha[, beta]]])
– src表示原陣列
– dst表示輸出陣列,深度為8位
– alpha表示比例因子
– beta表示原陣列元素按比例縮放后添加的值
最后呼叫addWeighted()函式計算水平方向和垂直方向的Roberts算子,其運行代碼如下:
# -*- 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) #轉uint8 absX = cv2.convertScaleAbs(x) absY = cv2.convertScaleAbs(y) Roberts = cv2.addWeighted(absX,0.5,absY,0.5,0) #用來正常顯示中文標簽 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()
其運行結果如圖2所示,左邊為原始影像,右邊為Roberts算子影像銳化提取的邊緣輪廓,
三.Prewitt算子
Prewitt是一種影像邊緣檢測的微分算子,其原理是利用特定區域內像素灰度值產生的差分實作邊緣檢測,由于Prewitt算子采用3×3模板對區域內的像素值進行計算,而Robert算子的模板為2×2,故Prewitt算子的邊緣檢測結果在水平方向和垂直方向均比Robert算子更加明顯,Prewitt算子適合用來識別噪聲較多、灰度漸變的影像,其計算公式如下所示,
具體的水平和垂直方向計算公式如下所示:
Prewitt算子像素的最終計算如公式(11)所示,
在Python中,Prewitt算子的實作程序與Roberts算子比較相似,通過Numpy定義模板,再呼叫OpenCV的filter2D()函式實作對影像的卷積運算,最終通過convertScaleAbs()和addWeighted()函式實作邊緣提取,代碼如下所示:
# -*- 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) #轉uint8 absX = cv2.convertScaleAbs(x) absY = cv2.convertScaleAbs(y) Prewitt = cv2.addWeighted(absX,0.5,absY,0.5,0) #用來正常顯示中文標簽 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()
最終運行結果如圖3所示,左邊為原始影像,右邊為Prewitt算子影像銳化提取的邊緣輪廓,其效果圖的邊緣檢測結果在水平方向和垂直方向均比Robert算子更加明顯,
四.總結
本文主要介紹影像銳化和邊緣檢測知識,詳細講解了Roberts算子和Prewitt算子,并通過小珞珞影像進行邊緣輪廓提取,影像銳化和邊緣提取技術可以消除影像中的噪聲,提取影像資訊中用來表征影像的一些變數,為影像識別提供基礎,
參考文獻:
- [1] 岡薩雷斯著,阮秋琦譯. 數字影像處理(第3版)[M]. 北京:電子工業出版社,2013.
- [2] 阮秋琦. 數字影像處理學(第3版)[M]. 北京:電子工業出版社,2008.
- [3] 陳初俠. 影像濾波及邊緣檢測與增強技術研究[D].合肥工業大學, 2009.
- [4] Eastmount. [Python影像處理] 四.影像平滑之均值濾波、方框濾波、高斯濾波及中值濾波[EB/OL]. (2018-09-02). https://blog.csdn.net/Eastmount/article/details/82216380.
- [5] Eastmount. [數字影像處理] 七.MFC影像增強之影像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt銳化詳解[EB/OL]. (2015-06-08). https://blog.csdn.net/eastmount/article/ details/46378783.
- [6] 毛星云. [OpenCV入門教程之九] 非線性濾波專場:中值濾波、雙邊濾波[EB/OL]. (2014-04-08). https://blog.csdn.net/poem_qianmo/article/details/23184547.
- [7] C. Tomasi, R Manduchi. Bilateral Filtering for Gray and Color images[C]. Proceedings of the IEEE International Conference on Computer Vision, Bombay, India. 1998:839-846.
點擊關注,第一時間了解華為云新鮮技術~
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/552608.html
標籤:Python
上一篇:Celery入坑記錄
下一篇:返回列表
