
前文傳送門:
「Python 圖像處理 OpenCV (1):入門」
「Python 圖像處理 OpenCV (2):像素處理與 Numpy 操作以及 Matplotlib 顯示圖像」
「Python 圖像處理 OpenCV (3):圖像屬性、圖像感興趣 ROI 區域及通道處理」
「Python 圖像處理 OpenCV (4):圖像算數運算以及修改顔色空間」
「Python 圖像處理 OpenCV (5):圖像的幾何變換」
「Python 圖像處理 OpenCV (6):圖像的門檻值處理」
「Python 圖像處理 OpenCV (7):圖像平滑(濾波)處理」
「Python 圖像處理 OpenCV (8):圖像腐蝕與圖像膨脹」
「Python 圖像處理 OpenCV (9):圖像處理形态學開運算、閉運算以及梯度運算」
「Python 圖像處理 OpenCV (10):圖像處理形态學之頂帽運算與黑帽運算」
「Python 圖像處理 OpenCV (11):Canny 算子邊緣檢測技術」
「Python 圖像處理 OpenCV (12): Roberts 算子、 Prewitt 算子、 Sobel 算子和 Laplacian 算子邊緣檢測技術」
Scharr 算子
在說 Scharr 算子之前,必須要提的是前面我們介紹過的 Sobel 算子, Sobel 算子雖然可以有效的提取圖像邊緣,但是對圖像中較弱的邊緣提取效果較差。
這是由于 Sobel 算子在計算相對較小的核的時候,其近似計算導數的精度比較低,例如一個
3 * 3
的 Sobel 算子,在梯度角度接近水準或垂直方向時,其不精确性就非常明顯。
是以引入 Scharr 算子。 Scharr 算子是對 Sobel 算子差異性的增強,兩者之間的在檢測圖像邊緣的原理和使用方式上相同。
而 Scharr 算子的主要思路是通過将模版中的權重系數放大來增大像素值間的差異。
Scharr 算子又稱為 Scharr 濾波器,也是計算 x 或 y 方向上的圖像差分,在 OpenCV 中主要是配合 Sobel 算子的運算而存在的,其濾波器的濾波系數如下:
\[Gx = \left[
\begin{matrix}
-3 & 0 & 3\\
-10 & 0 & 10\\
\end{matrix}
\right]
\]
\[Gy = \left[
-3 & -10 & -3\\
0 & 0 & 0\\
3 & 10 & 3\\
Scharr 算子在 OpenCV 中的方法原型如下:
def Scharr(src, ddepth, dx, dy, dst=None, scale=None, delta=None, borderType=None):
- src: 表示輸入圖像
- ddepth: 表示目标圖像所需的深度,針對不同的輸入圖像,輸出目标圖像有不同的深度
- dx: 表示 x 方向上的差分階數,取值 1 或 0
- dy: 表示 y 方向上的差分階數,取值 1 或 0
可以看到,函數
Scharr()
和
Sobel()
是非常的相似,在使用上也是完全一樣的,下面看一個示例:
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread("maliao.jpg")
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# Scharr 算子
x = cv.Scharr(gray_img, cv.CV_16S, 1, 0) # X 方向
y = cv.Scharr(gray_img, cv.CV_16S, 0, 1) # Y 方向
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
Scharr = cv.addWeighted(absX, 0.5, absY, 0.5, 0)
# 顯示圖形
plt.rcParams['font.sans-serif']=['SimHei']
titles = ['原始圖像', 'Scharr 算子']
images = [rgb_img, Scharr]
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()
LOG 算子
LOG ( Laplacian of Gaussian ) 邊緣檢測算子是 David Courtnay Marr 和 Ellen Hildreth 在 1980 年共同提出的,也稱為 Marr & Hildreth 算子,它根據圖像的信噪比來求檢測邊緣的最優濾波器。該算法首先對圖像做高斯濾波,然後再求其拉普拉斯( Laplacian )二階導數,根據二階導數的過零點來檢測圖像的邊界,即通過檢測濾波結果的零交叉( Zero crossings )來獲得圖像或物體的邊緣。
LOG 算子實際上是把 Gauss 濾波和 Laplacian 濾波結合了起來,先平滑掉噪聲,再進行邊緣檢測。
LOG 算子與視覺生理中的數學模型相似,是以在圖像處理領域中得到了廣泛的應用。
它具有抗幹擾能力強,邊界定位精度高,邊緣連續性好,能有效提取對比度弱的邊界等特點。
常見的 LOG 算子是
5 * 5
的模闆;
-2 & -4 & -4 & -4 & -2\\
-4 & 0 & 8 & 0 & -4\\
-4 & 8 & 24 & 8 & -4\\
LOG 算子到中心的距離與位置權重系數的關系曲線像墨西哥草帽的剖面,是以 LOG 算子也叫墨西哥草帽濾波器。
示例代碼如下:
import cv2 as cv
import matplotlib.pyplot as plt
# 讀取圖像
img = cv.imread("maliao.jpg")
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 先通過高斯濾波降噪
gaussian = cv.GaussianBlur(gray_img, (3, 3), 0)
# 再通過拉普拉斯算子做邊緣檢測
dst = cv.Laplacian(gaussian, cv.CV_16S, ksize=3)
LOG = cv.convertScaleAbs(dst)
# 用來正常顯示中文标簽
plt.rcParams['font.sans-serif'] = ['SimHei']
# 顯示圖形
titles = ['原始圖像', 'LOG 算子']
images = [rgb_img, LOG]
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()
小結
邊緣檢測算法主要是基于圖像強度的一階和二階導數,但導數通常對噪聲很敏感,是以需要采用濾波器來過濾噪聲,并調用圖像增強或門檻值化算法進行處理,最後再進行邊緣檢測。
參考
https://blog.csdn.net/Eastmount/article/details/89056240
https://blog.csdn.net/qq_42722197/article/details/103825409
https://www.jianshu.com/p/2ac784fd22fc
掃描二維碼關注「極客挖掘機」公衆号!作者:極客挖掘機
定期發表作者的思考:技術、産品、營運、自我提升等。
本文版權歸作者極客挖掘機和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
如果您覺得作者的文章對您有幫助,就來作者個人小站逛逛吧:
極客挖掘機