圖像腐蝕與圖像膨脹
圖像的膨脹(Dilation)和腐蝕(Erosion)是兩種基本的形態(tài)學(xué)運(yùn)算哮肚,主要用來(lái)尋找圖像中的極大區(qū)域和極小區(qū)域秫舌。
?
圖像腐蝕
該公式表示圖像A用卷積模板B來(lái)進(jìn)行腐蝕處理凰兑,通過(guò)模板B與圖像A進(jìn)行卷積計(jì)算谣辞,得出B覆蓋區(qū)域的像素點(diǎn)最小值甸私,并用這個(gè)最小值來(lái)替代參考點(diǎn)的像素值欧芽。如圖所示,將左邊的原始圖像A腐蝕處理為右邊的效果圖A-B朴摊。
形態(tài)學(xué)轉(zhuǎn)換主要針對(duì)的是二值圖像(0或1)默垄。圖像腐蝕類(lèi)似于“領(lǐng)域被蠶食”,將圖像中的高亮區(qū)域或白色部分進(jìn)行縮減細(xì)化甚纲,其運(yùn)行結(jié)果圖比原圖的高亮區(qū)域更小口锭。
dst = cv2.erode(src, kernel, iterations)
- dst表示處理的結(jié)果
- src表示原圖像
- kernel表示卷積核
- iterations表示迭代次數(shù),迭代次數(shù)默認(rèn)是1,表示進(jìn)行一次腐蝕,也可以根據(jù)需要進(jìn)行多次迭代鹃操,進(jìn)行多次腐蝕
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 4))
#讀取圖片
src = cv2.imread('data/test4.jpg', cv2.IMREAD_UNCHANGED)
#設(shè)置卷積核
kernel = np.ones((5,5), np.uint8)
#圖像腐蝕處理
erosion = cv2.erode(src, kernel)
#顯示結(jié)果
titles = ['src', 'erosion']
images = [src, erosion]
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()
圖像膨脹
該公式表示用B來(lái)對(duì)圖像A進(jìn)行膨脹處理韭寸,其中B是一個(gè)卷積模板或卷積核,其形狀可以為正方形或圓形荆隘,通過(guò)模板B與圖像A進(jìn)行卷積計(jì)算恩伺,掃描圖像中的每一個(gè)像素點(diǎn),用模板元素與二值圖像元素做“與”運(yùn)算椰拒,如果都為0晶渠,那么目標(biāo)像素點(diǎn)為0,否則為1燃观。從而計(jì)算B覆蓋區(qū)域的像素點(diǎn)最大值褒脯,并用該值替換參考點(diǎn)的像素值實(shí)現(xiàn)膨脹。下圖是將左邊的原始圖像A膨脹處理為右邊的效果圖A⊕B缆毁。
圖像膨脹是腐蝕操作的逆操作番川,類(lèi)似于“領(lǐng)域擴(kuò)張”,將圖像中的高亮區(qū)域或白色部分進(jìn)行擴(kuò)張脊框,其運(yùn)行結(jié)果圖比原圖的高亮區(qū)域更大爽彤,線條變粗了,主要用于去噪缚陷。
(1) 圖像被腐蝕后适篙,去除了噪聲,但是會(huì)壓縮圖像箫爷。
(2) 對(duì)腐蝕過(guò)的圖像嚷节,進(jìn)行膨脹處理,可以去除噪聲虎锚,并且保持原有形狀硫痰。
dst = cv2.dilate(src, kernel, iterations)
- dst表示處理的結(jié)果
- src表示原圖像
- kernel表示卷積核
- iterations表示迭代次數(shù)
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 4))
#讀取圖片
src = cv2.imread('data/test4.jpg', cv2.IMREAD_UNCHANGED)
#設(shè)置卷積核
kernel = np.ones((5,5), np.uint8)
#圖像膨脹處理
dilate = cv2.dilate(src, kernel)
#顯示結(jié)果
titles = ['src', 'dilate']
images = [src, dilate]
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()
# 依次進(jìn)行腐蝕、膨脹處理
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 4))
#讀取圖片
src = cv2.imread('data/test5.jpg', cv2.IMREAD_UNCHANGED)
#設(shè)置卷積核
kernel1 = np.ones((9,9), np.uint8)
#圖像腐蝕處理
result1 = cv2.erode(src, kernel1)
#設(shè)置卷積核
kernel2 = np.ones((9,9), np.uint8)
#圖像膨脹處理
result2 = cv2.dilate(result1, kernel2)
#顯示結(jié)果
titles = ['Image', 'erode', 'dilate']
images = [src, result1, result2]
for i in range(3):
plt.subplot(1, 3, i + 1)
plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
圖像開(kāi)運(yùn)算窜护、閉運(yùn)算效斑、梯度運(yùn)算、頂帽運(yùn)算柱徙、黑帽運(yùn)算
?
圖像開(kāi)運(yùn)算
圖像開(kāi)運(yùn)算是圖像依次經(jīng)過(guò)腐蝕缓屠、膨脹處理后的過(guò)程。圖像被腐蝕后护侮,去除了噪聲敌完,但是也壓縮了圖像;接著對(duì)腐蝕過(guò)的圖像進(jìn)行膨脹處理羊初,可以去除噪聲滨溉,并保留原有圖像。
dst = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)
- dst表示處理的結(jié)果
- src表示原圖像
- cv2.MORPH_OPEN表示開(kāi)運(yùn)算
- kernel表示卷積核
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
src = cv2.imread('data/test6.jpg', cv2.IMREAD_UNCHANGED)
#設(shè)置卷積核
kernel = np.ones((12,12), np.uint8)
#圖像開(kāi)運(yùn)算
result = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)
#顯示結(jié)果
titles = ['src', 'result']
images = [src, result]
plt.figure(figsize=(10, 4))
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()
圖像閉運(yùn)算
圖像閉運(yùn)算是圖像依次經(jīng)過(guò)膨脹、腐蝕處理后的過(guò)程晦攒。圖像先膨脹闽撤,后腐蝕,它有助于關(guān)閉前景物體內(nèi)部的小孔脯颜,或物體上的小黑點(diǎn)哟旗。
dst = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)
- dst表示處理的結(jié)果
- src表示原圖像
- cv2.MORPH_CLOSE
- kernel表示卷積核
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
src = cv2.imread('data/test7.jpg', cv2.IMREAD_UNCHANGED)
#設(shè)置卷積核
kernel = np.ones((10,10), np.uint8)
#圖像閉運(yùn)算
result = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)
#顯示結(jié)果
titles = ['src', 'result']
images = [src, result]
plt.figure(figsize=(10, 4))
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()
圖像梯度運(yùn)算
圖像梯度運(yùn)算是膨脹圖像減去腐蝕圖像的結(jié)果,得到圖像的輪廓伐脖,其中二值圖像1表示白色點(diǎn),0表示黑色點(diǎn)乐设。
dst = cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel)
- dst表示處理的結(jié)果
- src表示原圖像
- cv2.MORPH_GRADIENT表示梯度運(yùn)算
- kernel表示卷積核
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
src = cv2.imread('data/test8.jpg', cv2.IMREAD_UNCHANGED)
#設(shè)置卷積核
kernel = np.ones((10,10), np.uint8)
#圖像閉運(yùn)算
result = cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel)
#顯示結(jié)果
titles = ['src', 'result']
images = [src, result]
plt.figure(figsize=(10, 4))
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()
頂帽運(yùn)算
圖像頂帽(或圖像禮帽)運(yùn)算是原始圖像減去圖像開(kāi)運(yùn)算的結(jié)果讼庇,得到圖像的噪聲。常用于解決由于光照不均勻圖像分割出錯(cuò)的問(wèn)題近尚。
dst = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel)
- dst表示處理的結(jié)果
- src表示原圖像
- cv2.MORPH_TOPHAT表示頂帽運(yùn)算
- kernel表示卷積核
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
src = cv2.imread('data/test5.jpg', cv2.IMREAD_UNCHANGED)
#設(shè)置卷積核
kernel = np.ones((9,9), np.uint8)
#圖像頂帽運(yùn)算
result = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel)
#顯示結(jié)果
titles = ['src', 'result']
images = [src, result]
plt.figure(figsize=(10, 4))
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()
黑帽運(yùn)算
圖像黑帽運(yùn)算是圖像閉運(yùn)算操作減去原始圖像的結(jié)果蠕啄,得到圖像內(nèi)部的小孔,或者前景色中的小黑點(diǎn)戈锻。也常用于解決由于光照不均勻圖像分割出錯(cuò)的問(wèn)題歼跟。
dst = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel)
- dst表示處理的結(jié)果
- src表示原圖像
- cv2.MORPH_BLACKHAT表示頂帽運(yùn)算
- kernel表示卷積核
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
src = cv2.imread('data/test7.jpg', cv2.IMREAD_UNCHANGED)
#設(shè)置卷積核
kernel = np.ones((5,5), np.uint8)
#圖像黑帽運(yùn)算
result = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel)
#顯示結(jié)果
titles = ['src', 'result']
images = [src, result]
plt.figure(figsize=(10, 4))
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()
# 基于灰度三維圖的頂帽黑帽運(yùn)算
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
#讀取圖像
img = cv.imread("data/test5.jpg")
img = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
imgd = np.array(img) #image類(lèi)轉(zhuǎn)numpy
#準(zhǔn)備數(shù)據(jù)
sp = img.shape
h = int(sp[0]) #圖像高度(rows)
w = int(sp[1]) #圖像寬度(colums) of image
#繪圖初始處理
fig = plt.figure(figsize=(16,12))
ax = fig.gca(projection="3d")
x = np.arange(0, w, 1)
y = np.arange(0, h, 1)
x, y = np.meshgrid(x,y)
z = imgd
surf = ax.plot_surface(x, y, z, cmap=cm.coolwarm)
#自定義z軸
ax.set_zlim(-10, 255)
ax.zaxis.set_major_locator(LinearLocator(10)) #設(shè)置z軸網(wǎng)格線的疏密
#將z的value字符串轉(zhuǎn)為float并保留2位小數(shù)
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
# 設(shè)置坐標(biāo)軸的label和標(biāo)題
ax.set_xlabel('x', size=15)
ax.set_ylabel('y', size=15)
ax.set_zlabel('z', size=15)
ax.set_title("surface plot", weight='bold', size=20)
#添加右側(cè)的色卡條
fig.colorbar(surf, shrink=0.6, aspect=8)
plt.show()
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
#讀取圖像
img = cv.imread("data/test5.jpg")
img = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
#圖像黑帽運(yùn)算
kernel = np.ones((10,10), np.uint8)
result = cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel)
#image類(lèi)轉(zhuǎn)numpy
imgd = np.array(result)
#準(zhǔn)備數(shù)據(jù)
sp = result.shape
h = int(sp[0]) #圖像高度(rows)
w = int(sp[1]) #圖像寬度(colums) of image
#繪圖初始處理
fig = plt.figure(figsize=(16,12))
ax = fig.gca(projection="3d")
x = np.arange(0, w, 1)
y = np.arange(0, h, 1)
x, y = np.meshgrid(x,y)
z = imgd
surf = ax.plot_surface(x, y, z, cmap=cm.coolwarm)
#自定義z軸
ax.set_zlim(-10, 255)
ax.zaxis.set_major_locator(LinearLocator(10)) #設(shè)置z軸網(wǎng)格線的疏密
#將z的value字符串轉(zhuǎn)為float并保留2位小數(shù)
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
# 設(shè)置坐標(biāo)軸的label和標(biāo)題
ax.set_xlabel('x', size=15)
ax.set_ylabel('y', size=15)
ax.set_zlabel('z', size=15)
ax.set_title("surface plot", weight='bold', size=20)
#添加右側(cè)的色卡條
fig.colorbar(surf, shrink=0.6, aspect=8)
plt.show()