圖像平滑處理(濾波操作)
讓有噪音點(diǎn)(圖像上顯得突兀的像素點(diǎn))的圖像變得更加自然順眼
1.均值濾波 blur()
根據(jù)核的大小(rowcol),每個(gè)像素值就等于以此像素為中心的周圍rowcol個(gè)像素的平均值。
核大一點(diǎn),顯然越平滑、模糊。
result = cv2.blur(img, (15, 15))
2.方框?yàn)V波 boxFilter()
normalize=true的時(shí)候,效果同均值濾波;normalize=false的時(shí)候,α=1,僅求和。
result1 = cv2.boxFilter(img, -1, (3,3), normalize=0)
result2 = cv2.boxFilter(img, -1, (6,6), normalize=1)
3.高斯濾波GaussianBlur()
原理為高斯分布(正態(tài)分布)
與均值濾波對(duì)比,其實(shí)還是利用周圍的元素,不過(guò)周圍每個(gè)元素的權(quán)重不同。
核寬度和高度必須是奇數(shù)。
讓臨近的像素具有更高的重要度,對(duì)周圍像素計(jì)算加權(quán)平均值,較近的像素具有較大的權(quán)重值。
result = cv2.GaussianBlur(img, (15, 15), 0)
注:(15, 15)表示高斯濾波器的長(zhǎng)和寬,0表示濾波器的標(biāo)準(zhǔn)差
4.中值濾波medianBlur()
非常適用于有椒鹽點(diǎn)的圖像
依據(jù)核大小,選取以某個(gè)像素為中心的那些像素的中位數(shù)作為本像素的值。
本濾波,核寬度核高度是相同的,只需要指明邊長(zhǎng)。
result = cv2.medianBlur(img, 3)
形態(tài)學(xué)操作morphology
使用卷積核
1.腐蝕操作
cv2.erode(img,kernel,iterations)
就像土壤侵蝕一樣,這個(gè)操作會(huì)把前景物體的邊界腐蝕掉(但是前景仍然是白色)。
卷積核沿著圖像滑動(dòng),如果與卷積核對(duì)應(yīng)的原圖像的所有像素值都是1,
那么中心元素就保持原來(lái)的像素值,否則就變?yōu)榱恪?/p>
- 作用:去除白噪聲、斷開(kāi)兩個(gè)連在一塊的物體…
img = cv2.imread('j.png',0)
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)
其中,
- img 指需要腐蝕的圖
- kernel 指腐蝕操作的內(nèi)核,默認(rèn)是一個(gè)簡(jiǎn)單的3X3矩陣,
我們也可以利用getStructuringElement()函數(shù)指明它的形狀 - iterations 指的是腐蝕次數(shù),省略是默認(rèn)為1
2.膨脹操作
cv2.dilate(img,kernel,iterations)
dilation = cv2.dilate(img,kernel,iterations = 1)
與腐蝕相反,與卷積核對(duì)應(yīng)的原圖像的像素值中只要有一個(gè)是1,中心元素的像素值就是1。
可以彌補(bǔ)腐蝕操作后的結(jié)果(填充被腐蝕的部分、連接兩個(gè)被分開(kāi)的物體…)
腐蝕是我們將“腐蝕”邊緣。 它的工作方式是使用滑塊(核)。
我們讓滑塊滑動(dòng),如果所有的像素是白色的,那么我們得到白色,否則是黑色。 這可能有助于消除一些白色噪音。
另一個(gè)版本是膨脹,它基本上是相反的:讓滑塊滑動(dòng),如果整個(gè)區(qū)域不是黑色的,就會(huì)轉(zhuǎn)換成白色。
3.開(kāi)運(yùn)算 cv2.morphologyEx()
先進(jìn)性腐蝕再進(jìn)行膨脹就叫做開(kāi)運(yùn)算。它被用來(lái)去除噪聲。
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
4.閉運(yùn)算 cv2.morphologyEx()
先膨脹再腐蝕。它經(jīng)常被用來(lái)填充前景物體中的小洞,或者前景物體上的小黑點(diǎn)。
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
5.梯度運(yùn)算
梯度 = 膨脹后的圖像 - 腐蝕后的圖像
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
6.禮帽與黑帽
禮帽 = 原始輸入 - 開(kāi)運(yùn)算結(jié)果
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
黑帽 = 閉運(yùn)算結(jié)果 - 原始輸入
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
計(jì)算圖像梯度
梯度
圖像函數(shù)f(x,y)在點(diǎn)(x,y)的梯度是一個(gè)具有大小和方向的矢量,梯度的方向是函數(shù)f(x,y)變化最快的方向,當(dāng)圖像中存在邊緣時(shí),一定有較大的梯度值,相反,當(dāng)圖像中有比較平滑的部分時(shí),灰度值變化較小,則相應(yīng)的梯度也較小,圖像處理中把梯度的模簡(jiǎn)稱為梯度。
簡(jiǎn)單理解,一個(gè)圖像是一個(gè)函數(shù),梯度就是灰度值的變化率
圖像的梯度是多少?哪些地方有梯度、找出來(lái)。
相當(dāng)于邊緣檢測(cè)(在圖像中物體的邊緣像素點(diǎn)才有明顯的數(shù)值變化,即梯度)
1.Sobel算子
從右到左,從下到上
右邊減左邊,下邊減上邊
得到邊緣
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
其中,
- ddepth 圖像的深度,通常為-1,或cv2.CV_64F表示負(fù)數(shù)
- dx、dy 表示水平和豎直方向
- ksize 是Sobel算子的大小,通常用33或55
注:cv2會(huì)默認(rèn)進(jìn)行截?cái)?,即像素點(diǎn)數(shù)值范圍為0-255,小于0的全為0,大于255為255
白到黑是正數(shù),黑到白就是負(fù)數(shù)了,所有的負(fù)數(shù)會(huì)被截?cái)?,?,即都是黑的
故為了左右兩側(cè)邊緣都能顯示,需要加上絕對(duì)值cv2.convertScaleAbs(),即
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobelx = cv2.convertScaleAbs(sobely)
以上為求Gx,即dx=1,dy=0,下面求Gy
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobely = cv2.convertScaleAbs(sobely)
分別計(jì)算x和y,再求和
sobleXY = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
注:兩個(gè)0.5是兩個(gè)圖像的比例權(quán)重,最后的0是偏置項(xiàng),一般為0
以上為一般步驟,即x、y分開(kāi)算再求和。若直接dx=1,dy=1一次算的話,效果不好。
2.Scharr算子
scharrx = cv2.Scharr(img,cv2.CV_64F, 1, 0)
scharry = cv2.Scharr(img,cv2.CV_64F, 0, 1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv.addWeighted(scharrx, 0.5, scharry, 0.5)
其中,
- scharrx = cv2.Scharr(img, cv2.CV_64F, 1, 0): 這一行對(duì)輸入圖像 img 沿著x軸應(yīng)用Scharr算子。Scharr算子是一種用于邊緣檢測(cè)的卷積濾波器。
- scharry = cv2.Scharr(img, cv2.CV_64F, 0, 1): 這一行對(duì)輸入圖像 img 沿著y軸應(yīng)用Scharr算子。
- scharrx = cv2.convertScaleAbs(scharrx): 將 scharrx 轉(zhuǎn)換為無(wú)符號(hào)整數(shù)類型。這是因?yàn)镾charr算子的計(jì)算結(jié)果可能包含負(fù)值,而轉(zhuǎn)換為無(wú)符號(hào)整數(shù)可以保留正數(shù)部分。
- scharry = cv2.convertScaleAbs(scharry): 將 scharry 轉(zhuǎn)換為無(wú)符號(hào)整數(shù)類型。
- scharrxy = cv.addWeighted(scharrx, 0.5, scharry, 0.5): 使用 cv.addWeighted 函數(shù)將經(jīng)過(guò)Scharr算子處理的x方向和y方向的圖像疊加起來(lái),創(chuàng)建一個(gè)新的圖像 scharrxy。這里權(quán)重分別為0.5,表示對(duì)兩個(gè)方向的處理結(jié)果進(jìn)行平均。
3.laplacian算子
對(duì)像素點(diǎn)數(shù)值變化更敏感,也就意味著對(duì)圖像上的噪音點(diǎn)敏感,容易認(rèn)為是邊緣。
單獨(dú)使用效果不好。
Laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
- scharr最深刻,然后soble,laplacian最淺。算子的核不同。
- 這里舉一個(gè)簡(jiǎn)單的例子:
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 讀取圖像
img = cv2.imread('./image/car1.jpg', cv2.IMREAD_GRAYSCALE)
# 進(jìn)行形態(tài)學(xué)膨脹操作
kernel = np.ones((5,5), np.uint8) # 5x5 的卷積核
dilation = cv2.dilate(img, kernel, iterations=1)
# 進(jìn)行形態(tài)學(xué)腐蝕操作
erosion = cv2.erode(img, kernel, iterations=1)
# 顯示原始圖像、膨脹和腐蝕的結(jié)果
plt.subplot(131), plt.imshow(img, cmap='gray'), plt.title('Original Image')
plt.subplot(132), plt.imshow(dilation, cmap='gray'), plt.title('Dilation')
plt.subplot(133), plt.imshow(erosion, cmap='gray'), plt.title('Erosion')
plt.show()
# 進(jìn)行邊緣檢測(cè)(使用Sobel算子)
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=5)
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=5)
edges = cv2.magnitude(sobelx, sobely)
# 顯示邊緣檢測(cè)結(jié)果
plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title('Original Image')
plt.subplot(122), plt.imshow(edges, cmap='gray'), plt.title('Edge Detection (Sobel)')
plt.show()
結(jié)果如下:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-800643.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-800643.html
到了這里,關(guān)于python數(shù)字圖像處理基礎(chǔ)(四)——圖像平滑處理、形態(tài)學(xué)操作、圖像梯度的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!