圖像平滑
使用低通濾波器可以達(dá)到圖像模糊的目的。這對(duì)與去除噪音很有幫助。其實(shí)就是去除圖像中的高頻成分(比如:噪音,邊界)。所以邊界也會(huì)被模糊一點(diǎn)。(當(dāng)然,也有一些模糊技術(shù)不會(huì)模糊掉邊界)。
平均濾波
這是由一個(gè)歸一化卷積框完成的。他只是用卷積框覆蓋區(qū)域所有像素的平均值來(lái)代替中心元素??梢允褂煤瘮?shù) cv2.blur() 和 cv2.boxFilter() 來(lái)完這個(gè)任務(wù)??梢酝床榭次臋n了解更多卷積框的細(xì)節(jié)。我們需要設(shè)定卷積框的寬和高。
一個(gè)3x3的歸一化卷積框:
K
=
1
9
[
1
1
1
1
1
1
1
1
1
]
K=\frac{1}{9}\left[\begin{matrix} 1&1&1 \\1&1&1\\1&1&1\end{matrix}\right]
K=91?
?111?111?111?
?
注意:如果不想使用歸一化卷積框,你應(yīng)該使用 cv2.boxFilter(),這時(shí)要傳入?yún)?shù) normalize=False。
dst=cv2.boxFilter(src,ddepth,ksize)
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 在圖片上生成椒鹽噪聲
def add_peppersalt_noise(image, n=10000):
result = image.copy()
# 測(cè)量圖片的長(zhǎng)和寬
w, h, = image.shape[:2]
# 生成n個(gè)椒鹽噪聲
for i in range(n):
x = np.random.randint(1, w)
y= np.random.randint(1, h)
if np.random.randint(0, 2) == 0 :
result[x, y] = 0
else:
result[x,y] = 255
return result
# 平均
# 這是由一個(gè)歸一化卷積框完成的,
# cv2.blur()和cv2.boxFiter()來(lái)實(shí)現(xiàn)。
img = cv2.imread('./resource/opencv/image/logo/opencv-logo-white.png', cv2.IMREAD_COLOR)
# 原圖添加椒鹽噪聲
saltnoise_img = add_peppersalt_noise(img, 10000)
blur = cv2.blur(saltnoise_img, (5,5))
boxfilter = cv2.boxFilter(saltnoise_img, -1, (3,3))
# boxfilter = cv2.boxFilter(saltnoise_img, -1, (3,3), normalize=0)
plt.subplot(221), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)), plt.title('origin'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(cv2.cvtColor(saltnoise_img, cv2.COLOR_BGR2RGB)), plt.title('add noise'), plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(cv2.cvtColor(blur, cv2.COLOR_BGR2RGB)), plt.title('blur'), plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(cv2.cvtColor(boxfilter, cv2.COLOR_BGR2RGB)), plt.title('boxfilter'), plt.xticks([]), plt.yticks([])
plt.show()
高斯模糊
現(xiàn)在把卷積核換成高斯核(簡(jiǎn)單來(lái)說(shuō),方框不變,將原來(lái)每個(gè)方框的值是相等的,現(xiàn)在里面的值是符合高斯分布的,方框中心的值最大,其余方框根據(jù)距離中心元素的距離遞減,構(gòu)成一個(gè)高斯小山包。原來(lái)的求平均數(shù)現(xiàn)在變成求加權(quán)平均數(shù),全就是方框里的值)。實(shí)現(xiàn)的函數(shù)是 cv2.GaussianBlur()。我們需要指定高斯核的寬和高(必須是奇數(shù))。以及高斯函數(shù)沿 X, Y 方向的標(biāo)準(zhǔn)差。如果我們只指定了 X 方向的的標(biāo)準(zhǔn)差, Y 方向也會(huì)取相同值。如果兩個(gè)標(biāo)準(zhǔn)差都是 0,那么函數(shù)會(huì)根據(jù)核函數(shù)的大小自己計(jì)算。高斯濾波可以有效的從圖像中去除高斯噪音。如果你愿意的話,你也可以使用函數(shù) cv2.getGaussianKernel() 自己構(gòu)建一個(gè)高斯核。
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 高斯模糊
# 卷積核換成高斯核,即方框不變,將原來(lái)方框相等的值,換成符合高斯分部的值,方框中心值最大,其余值遞減,構(gòu)成一個(gè)高斯小山包
# 高斯核的寬和高必須是奇數(shù)
# 在圖片上生成椒鹽噪聲
def add_peppersalt_noise(image, n=10000):
result = image.copy()
# 測(cè)量圖片的長(zhǎng)和寬
w, h, = image.shape[:2]
# 生成n個(gè)椒鹽噪聲
for i in range(n):
x = np.random.randint(1, w)
y= np.random.randint(1, h)
if np.random.randint(0, 2) == 0 :
result[x, y] = 0
else:
result[x,y] = 255
return result
# 獲取高斯核
k1 = cv2.getGaussianKernel(3, 1)
k2 = cv2.getGaussianKernel(5,2)
print(k1)
print(k2)
# 彩色圖像高斯模糊
img = cv2.imread('./resource/opencv/image/logo/opencv-logo-white.png', cv2.IMREAD_COLOR)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)
img = add_peppersalt_noise(img)
dst1 = cv2.GaussianBlur(img, (5,5), 0)
# 灰度圖像高斯模糊
gray = cv2.imread('./resource/opencv/image/logo/opencv-logo-white.png', cv2.IMREAD_GRAYSCALE)
gray = add_peppersalt_noise(gray)
dst2 = cv2.GaussianBlur(gray, (5,5), 0)
plt.subplot(221), plt.imshow(img, 'gray'), plt.title('original'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(dst1, 'gray'), plt.title('gaussianBlur'), plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(gray, 'gray'), plt.title('gray'), plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(dst2, 'gray'), plt.title('gaussianBlur'), plt.xticks([]), plt.yticks([])
plt.show()
中值模糊
顧名思義就是用與卷積框?qū)?yīng)像素的中值來(lái)替代中心像素的值。這個(gè)濾波器經(jīng)常用來(lái)去除椒鹽噪聲。前面的濾波器都是用計(jì)算得到的一個(gè)新值來(lái)取代中心像素的值,而中值濾波是用中心像素周圍(也可以使他本身)的值來(lái)取代他。他能有效的去除噪聲。卷積核的大小也應(yīng)該是一個(gè)奇數(shù)。
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 中值濾波
# 在圖片上生成椒鹽噪聲
def add_peppersalt_noise(image, n=10000):
result = image.copy()
# 測(cè)量圖片的長(zhǎng)和寬
w, h, = image.shape[:2]
# 生成n個(gè)椒鹽噪聲
for i in range(n):
x = np.random.randint(1, w)
y= np.random.randint(1, h)
if np.random.randint(0, 2) == 0 :
result[x, y] = 0
else:
result[x,y] = 255
return result
img = cv2.imread('./resource/opencv/image/logo/opencv-logo-white.png', cv2.IMREAD_COLOR)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)
img = add_peppersalt_noise(img)
median = cv2.medianBlur(img, 5)
gray = cv2.imread('./resource/opencv/image/logo/opencv-logo-white.png', cv2.IMREAD_GRAYSCALE)
gray = add_peppersalt_noise(gray)
median_gray = cv2.medianBlur(gray, 5)
plt.subplot(221), plt.imshow(img, 'gray'), plt.title('original')
plt.subplot(222), plt.imshow(median, 'gray'), plt.title('medianBlur')
plt.subplot(223), plt.imshow(gray, 'gray'), plt.title('gray')
plt.subplot(224), plt.imshow(median_gray, 'gray'), plt.title('medianBlur')
plt.show()
雙邊濾波
函數(shù) cv2.bilateralFilter() 能在保持邊界清晰的情況下有效的去除噪音。但是這種操作與其他濾波器相比會(huì)比較慢。我們已經(jīng)知道高斯濾波器是求中心點(diǎn)鄰近區(qū)域像素的高斯加權(quán)平均值。這種高斯濾波器只考慮像素之間的空間關(guān)系,而不會(huì)考慮像素值之間的關(guān)系(像素的相似度)。所以這種方法不會(huì)考慮一個(gè)像素是否位于邊界。因此邊界也會(huì)別模糊掉,而這正不是我們想要。雙邊濾波在同時(shí)使用空間高斯權(quán)重和灰度值相似性高斯權(quán)重??臻g高斯函數(shù)確保只有鄰近區(qū)域的像素對(duì)中心點(diǎn)有影響,灰度值相似性高斯函數(shù)確保只有與中心像素灰度值相近的才會(huì)被用來(lái)做模糊運(yùn)算。所以這種方法會(huì)確保邊界不會(huì)被模糊掉,因?yàn)檫吔缣幍幕叶戎底兓容^大。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-636509.html
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 雙邊濾波
img = cv2.imread('./resource/opencv/image/rubberwhale1.png', cv2.IMREAD_GRAYSCALE)
# 9:鄰域直徑,75:空間高斯函數(shù)標(biāo)準(zhǔn)差,75:灰度值相似性高斯函數(shù)標(biāo)準(zhǔn)差
dst1 = cv2.bilateralFilter(img, 9, 75, 75)
plt.subplot(121), plt.imshow(img, 'gray'), plt.title('origin')
plt.subplot(122), plt.imshow(dst1, 'gray'), plt.title('bilateralFiter')
plt.show()
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-636509.html
到了這里,關(guān)于Python-OpenCV中的圖像處理-圖像平滑的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!