小花今天和我说:“她想要一种朦胧美”,我直接安排
图像的高斯模糊是经典的图像卷积案例,其本质是将图像和一个高斯核进行卷积操作。scipy 中的 gaussian_filter 利用快速的一维分离方式实现卷积。
(具体高斯模糊算法和卷积算法这里不赘述,后续会有讲解)
这里使用 scipy
库里的高斯滤波。
from PIL import Image
from pylab import *
from scipy.ndimage import gaussian_filter
plt.rcParams['font.sans-serif'] = ['SimHei']
hua = array(Image.open('hua.jpg').convert('L'))
figure(figsize=(16,9))
gray()
axis('off')
subplot(141)
title(u'小花原图')
imshow(hua)
for bi, blur in enumerate([2,4,8]):
im2 = np.zeros(hua.shape)
im3 = gaussian_filter(hua,blur)
im4 = np.uint8(im3)
imNum = str(blur)
subplot(1,4,2 + bi)
axis('off')
title(u"标准差为" + imNum)
imshow(im4)
show()
如图,高斯标准差分别为2、4、8
彩色图像:scipy实现彩色图像高斯模糊,本质不变。
将每一个通道都进行卷积得到彩色图像模糊的效果。
from PIL import Image
from pylab import *
from scipy.ndimage import gaussian_filter
plt.rcParams['font.sans-serif'] = ['SimHei']
hua = array(Image.open('hua.jpg'))
figure(figsize=(16,9))
axis('off')
subplot(141)
title(u'小花原图')
imshow(hua)
for bi, blur in enumerate([2,4,8]):
im2 = np.zeros(hua.shape)
for i in range(3):
im2[:,:,i] = gaussian_filter(hua[:,:,i],blur)
im3 = np.uint8(im2)
imNum = str(blur)
subplot(1,4,2 + bi)
axis('off')
title(u"标准差为" + imNum)
imshow(im3)
show()
这不“朦胧美”就出来了?
对灰度图像进行任意方向的求导都可以让图像强度发生变化,利用这种方法来
设Ix
为图像在x方向上的导数 Iy
为图像在y方向上的导数。
图像的梯度向量用来描述图像强度变化的强弱,公式为
∇
I
=
I
x
2
+
I
y
2
\nabla I = \sqrt{I_x^2 + I_y^2}
∇I=Ix2+Iy2
梯度的角度用来描述图像中在每个像素点上强度变化最大的方向,公式为:
a
=
a
r
c
t
a
n
(
I
y
,
I
x
)
a = arctan(I_y,I_x)
a=arctan(Iy,Ix)
可以用 离散近似 的方式来计算图像导数,使用卷积操作
卷积详细操作在这里暂不提及,原理大概就是将两个矩阵相乘,如下:
I
x
=
I
×
H
x
I
y
=
I
×
H
y
I_x = I \times H_x \\I_y = I \times H_y
Ix=I×HxIy=I×Hy
其中Hx
和Hy
这里使用Sobel滤波器
Sobel长这样:
H
x
=
∣
−
1
0
1
−
2
0
2
−
1
0
1
∣
H
y
=
∣
−
1
−
2
−
1
0
0
0
1
2
1
∣
H_x=
代码部分
from PIL import Image
from pylab import *
import numpy as np
import matplotlib.pyplot as plt
#导入sobel算子
from scipy.ndimage import sobel
#设中文,读灰度图
plt.rcParams['font.sans-serif'] = ['SimHei']
im = array(Image.open('hua.jpg').convert('L'))
gray()
subplot(141)
axis('off')
title(u'(a)原图')
imshow(im)
#sobel算子
imx = zeros(im.shape)
sobel(im,1,imx)
subplot(142)
axis('off')
title(u'(b)x方向差分')
imshow(imx)
imy = zeros(im.shape)
sobel(im,0,imy)
subplot(143)
axis('off')
title(u'(c)y方向差分')
imshow(imy)
#求梯度向量
mag = 255-np.sqrt(imx ** 2 + imy ** 2)
subplot(144)
title(u'(d)y梯度幅值')
axis('off')
imshow(mag)
show()
运行程序,效果如图
原图是小花的灰度图,x方向使用sobel算子进行卷积操作和y方向的如中间两幅图,各自显示出了其细节。最后将梯度幅值展现出来,显示出了细节