參考資料:
參考視頻
視頻參考資料:鏈接: https://pan.baidu.com/s/1_DJTOerxpu5_dSfd4ZNlAA 提取碼: 8v2n
相關代碼
概述:
? ? ? ? 因為本人是用于機器視覺的圖像處理,所以只記錄了OpenCV的形態學操作和圖像平滑處理兩部分
形態學操作:
? ? ? ? 形態學操作主要包括:膨脹和腐蝕 、開閉運算、黑帽和禮帽
膨脹和腐蝕
- 腐蝕和膨脹是最基本的形態學操作,腐蝕和膨脹都是針對白色部分(高亮部分)而言的。
- 膨脹就是使圖像中高亮部分擴張,效果圖擁有比原圖更大的高亮區域;
- 腐蝕是原圖中的高亮區域被蠶食,效果圖擁有比原圖更小的高亮區域
- 膨脹是求局部最大值的操作,腐蝕是求局部最小值的操作。
腐蝕
1. 原理
????????具體操作是:用一個結構元素掃描圖像中的每一個像素,用結構元素中的每一個像素與其覆蓋的像素做“與”操作,如果都為1,則該像素為1,否則為0。
????????如下圖所示,結構A被結構B腐蝕后:
腐蝕的作用是消除物體邊界點,使目標縮小,可以消除小于結構元素的噪聲點。
2. API:
cv.erode(img,kernel,iterations)
參數:
- img: 要處理的圖像
- kernel: 核結構
- iterations: 腐蝕的次數,默認是1
膨脹
1. 原理
????????具體操作是:用一個結構元素掃描圖像中的每一個像素,用結構元素中的每一個像素與其覆蓋的像素做“與”操作,如果都為0,則該像素為0,否則為1。
????????如下圖所示,結構A被結構B腐蝕后:
膨脹的作用是將與物體接觸的所有背景點合并到物體中,使目標增大,可添補目標中的孔洞。
2. API
cv.dilate(img,kernel,iterations)
參數:
-
img: 要處理的圖像
-
kernel: 核結構
- iterations: 腐蝕的次數,默認是1
示例
import matplotlib
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 支持中文
matplotlib.rcParams['font.sans-serif'] = ['Microsoft YaHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 1 讀取圖像
img = cv.imread("./image/image3.png")
# 2 創建核結構
kernel = np.ones((5, 5), np.uint8)# 3 圖像腐蝕和膨脹
erosion = cv.erode(img, kernel) # 腐蝕
dilate = cv.dilate(img,kernel) # 膨脹# 4 圖像展示
fig,axes=plt.subplots(nrows=1,ncols=3,figsize=(10,8),dpi=100)
axes[0].imshow(img)
axes[0].set_title("原圖")
axes[1].imshow(erosion)
axes[1].set_title("腐蝕后結果")
axes[2].imshow(dilate)
axes[2].set_title("膨脹后結果")
plt.show()
?
開閉運算?
- 開運算和閉運算是將腐蝕和膨脹按照一定的次序進行處理
- 但這兩者并不是互為逆運算,即先開后閉并不能得到原來的圖像。
開運算
- 原理:?先腐蝕后膨脹
- 作用:
- 1.?分離物體,消除小區域
- 2.?消除噪點,去除小的干擾塊,而不影響原來的圖像。
閉運算?
- 原理:先膨脹后腐蝕
- 作用:
- 是消除/“閉合”物體里面的孔洞
- 可以填充閉合區域
?API
cv.morphologyEx(img, op, kernel)
參數:
- img: 要處理的圖像
- op: 處理方式:若進行開運算,則設為cv.MORPH_OPEN,若進行閉運算,則設為cv.MORPH_CLOSE
- Kernel: 核結構
示例
import matplotlib
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 支持中文
matplotlib.rcParams['font.sans-serif'] = ['Microsoft YaHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 1 讀取圖像
img1 = cv.imread("./image/image5.png")
img2 = cv.imread("./image/image6.png")
# 2 創建核結構
kernel = np.ones((10, 10), np.uint8)
# 3 圖像的開閉運算
cvOpen = cv.morphologyEx(img1,cv.MORPH_OPEN,kernel) # 開運算
cvClose = cv.morphologyEx(img2,cv.MORPH_CLOSE,kernel)# 閉運算
# 4 圖像展示
fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8))
axes[0,0].imshow(img1)
axes[0,0].set_title("原圖")
axes[0,1].imshow(cvOpen)
axes[0,1].set_title("開運算結果")
axes[1,0].imshow(img2)
axes[1,0].set_title("原圖")
axes[1,1].imshow(cvClose)
axes[1,1].set_title("閉運算結果")
plt.show()
黑帽禮帽
? ? ? ? 黑帽和禮帽運算通常是用來得到圖形的輪廓的
禮帽運算
- ?原理:原圖和開運算之差
- ?作用:得到比原圖輪廓更明亮的輪廓 ,效果和核大小有關
- ?用來分離比鄰近點亮一些的斑塊
黑帽運算
- ?原理:原圖和閉運算之差
- ?作用:得到比原圖輪廓更明暗的輪廓 ,效果和核大小有關
- ?用來分離比鄰近點暗一些的斑塊
API
cv.morphologyEx(img, op, kernel)
參數:
-
img: 要處理的圖像
-
op: 處理方式:
-
Kernel: 核結構
示例
import matplotlib
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
matplotlib.rcParams['font.sans-serif'] = ['Microsoft YaHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 1 讀取圖像
img1 = cv.imread("./image/image5.png")
img2 = cv.imread("./image/image6.png")
# 2 創建核結構
kernel = np.ones((10, 10), np.uint8)
# 3 圖像的禮帽和黑帽運算
cvOpen = cv.morphologyEx(img1,cv.MORPH_TOPHAT,kernel) # 禮帽運算
cvClose = cv.morphologyEx(img2,cv.MORPH_BLACKHAT,kernel)# 黑帽運算
# 4 圖像顯示
fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8))
axes[0,0].imshow(img1)
axes[0,0].set_title("原圖")
axes[0,1].imshow(cvOpen)
axes[0,1].set_title("禮帽運算結果")
axes[1,0].imshow(img2)
axes[1,0].set_title("原圖")
axes[1,1].imshow(cvClose)
axes[1,1].set_title("黑帽運算結果")
plt.show()
圖像平滑:
噪聲的分類
椒鹽噪聲
- 隨機的黑點或白點
高斯噪聲?
- 顏色或灰度值隨機,位置隨機的彩色斑點
- 通常灰度值符合高斯分布
?噪聲的處理
均值濾波
原理:將核區域內的灰度值進行平均,來代替中心元素
優點:速度快
缺點:去除噪點的效果很差,且被處理的圖像會變得模糊
?
?API
cv.blur(src, ksize, anchor, borderType)
參數:
- src:輸入圖像
- ksize:卷積核的大小
- anchor:默認值 (-1,-1) ,表示核中心
- borderType:邊界類型
相關代碼:
import cv2 as cv
import matplotlib
import numpy as np
from matplotlib import pyplot as plt
# 支持中文
matplotlib.rcParams['font.sans-serif'] = ['Microsoft YaHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 1 圖像讀取
img = cv.imread('./image/dogsp.jpeg')
# 2 均值濾波
blur = cv.blur(img,(5,5))
# 3 圖像顯示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img[:,:,::-1]),plt.title('原圖')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur[:,:,::-1]),plt.title('均值濾波后結果')
plt.xticks([]), plt.yticks([])
plt.show()
高斯濾波
- 以當前像素點為中心,以所規定的核為單位,根據與中心點距離獲得權重,核中所有像素點權重和為1
- 然后每個像素點的灰度值*權重
- 然后9個點的結果相加,就是中心點的灰度值
- 高斯濾波對高斯噪聲效果比較好,但是對椒鹽噪聲效果一般
API:
cv2.GaussianBlur(src,ksize,sigmaX,sigmay,borderType)
參數:
- src: 輸入圖像
- ksize:高斯卷積核的大小,注意?: 卷積核的寬度和高度都應為奇數,且可以不同
- sigmaX: 水平方向的標準差
- sigmaY: 垂直方向的標準差,默認值為0,表示與sigmaX相同
- borderType:填充邊界類型
示例:
import cv2 as cv
import matplotlib
import numpy as np
from matplotlib import pyplot as plt
# 支持中文
matplotlib.rcParams['font.sans-serif'] = ['Microsoft YaHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 1 圖像讀取
img = cv.imread('./image/dogGauss.jpeg')
# 2 高斯濾波
blur = cv.GaussianBlur(img,(3,3),1)
# 3 圖像顯示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img[:,:,::-1]),plt.title('原圖')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur[:,:,::-1]),plt.title('高斯濾波后結果')
plt.xticks([]), plt.yticks([])
plt.show()
中值濾波
- 取中心點所在核的灰度值的中值,作為中心點新的灰度值
- 中值濾波對椒鹽噪聲尤為有效,是處理椒鹽噪聲的首選之一
API
cv.medianBlur(src, ksize )
?示例
import cv2 as cv
import matplotlib
import numpy as np
from matplotlib import pyplot as plt
# 支持中文
matplotlib.rcParams['font.sans-serif'] = ['Microsoft YaHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 1 圖像讀取
img = cv.imread('./image/dogsp.jpeg')
# 2 中值濾波
blur = cv.medianBlur(img,5)
# 3 圖像展示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img[:,:,::-1]),plt.title('原圖')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur[:,:,::-1]),plt.title('中值濾波后結果')
plt.xticks([]), plt.yticks([])
plt.show()
總結
? ? ? ? 相對于膨脹和腐蝕,開閉運算效果會更好
? ? ? ? 噪聲的消除中,中值濾波和高斯濾波是不錯的選擇