石家莊手機(jī)網(wǎng)站制作多少錢企業(yè)網(wǎng)頁設(shè)計(jì)公司
9.1 Roberts算子
Roberts算子又稱為交叉微分算法,是基于交叉差分的梯度算法,通過局部差分計(jì)算檢測(cè)邊緣線條。
常用來處理具有陡峭的低噪聲圖像,當(dāng)圖像邊緣接近于正45度或負(fù)45度時(shí),該算法處理效果更理想。
其缺點(diǎn)是對(duì)邊緣的定位不太準(zhǔn)確,提取的邊緣線條較粗。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt # 讀取圖像
img = cv.imread('bridge.png', cv.COLOR_BGR2GRAY)
# cv.COLOR_BGR2GRAY將BGR圖像轉(zhuǎn)換為灰度圖像
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)# 灰度化處理圖像
grayImage = cv.cvtColor(img, cv.COLOR_BGR2GRAY)# Roberts算子的兩個(gè)卷積核kernelx和kernely,分別用于檢測(cè)水平和垂直方向的邊緣。
kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
kernely = np.array([[0, -1], [1, 0]], dtype=int)# 使用cv.filter2D函數(shù)對(duì)灰度圖像進(jìn)行卷積操作,得到水平和垂直方向的梯度圖像。
x = cv.filter2D(grayImage, cv.CV_16S, kernelx)
y = cv.filter2D(grayImage, cv.CV_16S, kernely)# 將卷積后的圖像數(shù)據(jù)轉(zhuǎn)換為絕對(duì)值,并轉(zhuǎn)換為uint8類型,以便于顯示。
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
# 將兩個(gè)方向的梯度圖像融合,得到最終的Roberts算子邊緣檢測(cè)圖像。
Roberts = cv.addWeighted(absX, 0.5, absY, 0.5, 0)# 顯示圖形
titles = ['src', 'Roberts operator']
images = [rgb_img, Roberts]for i in range(2):# 使用matplotlib的subplot和imshow函數(shù)顯示原始圖像和Roberts算子處理后的圖像plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')plt.title(titles[i])plt.xticks([]), plt.yticks([])
plt.show()
Sobel算子邊緣檢測(cè)
Sobel算子(索貝爾算子)利用像素上、下、左、右鄰域的灰度加權(quán)算法,根據(jù)在邊緣點(diǎn)處達(dá)到極值這一原理進(jìn)行邊緣檢測(cè)。
該方法不但產(chǎn)生較好的檢測(cè)效果,而且對(duì)噪聲具有平滑作用,可以提供較為精確的邊緣方向信息。缺點(diǎn)是Sobel算子并沒有將圖像的主題和背景嚴(yán)格區(qū)分開。
使用Sobel邊緣檢測(cè)算子提取圖像邊緣的過程大致可以分為以下三個(gè)步驟:
提取x方向的邊緣,x方向一階Sobel邊緣檢測(cè)算子如下圖1所示;
提取y方向的邊緣,y方向一階Sobel邊緣檢測(cè)算子如下圖2所示;
綜合兩個(gè)方向的邊緣信息得到整幅圖像的邊緣。
import cv2 as cv
import matplotlib.pyplot as plt# 讀取圖像
img = cv.imread('bridge.png', cv.COLOR_BGR2GRAY)
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)# 灰度化處理圖像
grayImage = cv.cvtColor(img, cv.COLOR_BGR2GRAY)# 使用cv.Sobel函數(shù)計(jì)算圖像的水平和垂直方向的梯度
# cv.CV_16S指定數(shù)據(jù)類型為16位有符號(hào)整數(shù)。
x = cv.Sobel(grayImage, cv.CV_16S, 1, 0)
y = cv.Sobel(grayImage, cv.CV_16S, 0, 1)# 將計(jì)算得到的梯度圖像轉(zhuǎn)換為絕對(duì)值,并轉(zhuǎn)換為uint8類型,以便顯示。
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
# 將水平和垂直方向的梯度圖像融合,得到最終的Sobel算子邊緣檢測(cè)圖像。
Sobel = cv.addWeighted(absX, 0.5, absY, 0.5, 0)# 用來正常顯示中文標(biāo)簽
plt.rcParams['font.sans-serif'] = ['SimHei']# 顯示圖形
titles = ['原始圖像', 'Sobel 算子']
images = [rgb_img, Sobel]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邊緣檢測(cè)算子
該算法首先對(duì)圖像做高斯濾波,然后求其拉普拉斯(Laplacian)二階導(dǎo)數(shù),即圖像與Laplacian of the Gaussian function 進(jìn)行濾波運(yùn)算。
LoG算子也就是高斯拉普拉斯函數(shù),常用于數(shù)字圖像的邊緣提取和二值化。首先對(duì)原始圖像進(jìn)行最佳平滑處理,最大限度地抑制噪聲,再對(duì)平滑后的圖像求取邊緣。
該算法的主要思路和步驟:濾波、增強(qiáng)、檢測(cè)。
import cv2 as cv
import matplotlib.pyplot as plt# 讀取圖像
img = cv.imread("bridge.png")
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)# 先通過高斯濾波降噪
gaussian = cv.GaussianBlur(gray_img, (3, 3), 0)# 再通過拉普拉斯算子做邊緣檢測(cè),cv.Laplacian函數(shù)計(jì)算圖像的二階導(dǎo)數(shù)
dst = cv.Laplacian(gaussian, cv.CV_16S, ksize=3)
LOG = cv.convertScaleAbs(dst)# 用來正常顯示中文標(biāo)簽
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()
示例: