讲的是Gaussian Blur,讲的很详细,值得仔细阅读!
python最常用的图像处理库是PIL(PythonImaging Library),它内置了高斯模糊方法,简单代码如下:
- import Image
- import ImageFilter
- im=Image.open('im.jpg')
- im=im.filter(ImageFilter.GaussianBlur(radius=2))
- im.show()
其中这个GaussianBlur()函数源代码有错误:设置radius无效,也就是说radius不管设置成多大,都是按2来计算的。错误太明显了!我们都知道radius越大图像越模糊。这个错误在PIL源文件的ImageFilter.py中,第156行。截取部分源码可知:
- # Gaussian blur filter.
- class GaussianBlur(Filter):
- name = "GaussianBlur"
- def __init__(self, radius=2):
- self.radius = 2<span style="white-space:pre;"> </span>#这个地方明显不对
- def filter(self, image):
- return image.gaussian_blur(self.radius)
- class MyGaussianBlur(ImageFilter.Filter):
- name="GaussianBlur"
- def __init__(self, radius=2):
- self.radius=radius
- def filter(self, image):
- return image.gaussian_blur(self.radius)
其实,上面的例子关于高斯模糊是不完整的。它没有提供设置sigema值的方法,只提供了设置radius的方法。在pyOpenCV中应该有完整的高斯模糊函数,可以直接调用。我决定简单地自己实现一下:
下面是具体代码,只用了PIL库和numpy,PIL仅用于读写图像, numpy用于矩阵计算。全过程完全符合阮一峰的网络日志
- # -*- coding: utf-8 -*-
- import math
- import numpy as np
- import Image
- class MyGaussianBlur():
- #初始化
- def __init__(self, radius=1, sigema=1.5):
- self.radius=radius
- self.sigema=sigema
- #高斯的计算公式
- def calc(self,x,y):
- res1=1/(2*math.pi*self.sigema*self.sigema)
- res2=math.exp(-(x*x+y*y)/(2*self.sigema*self.sigema))
- return res1*res2
- #得到滤波模版
- def template(self):
- sideLength=self.radius*2+1
- result = np.zeros((sideLength, sideLength))
- for i in range(sideLength):
- for j in range(sideLength):
- result[i,j]=self.calc(i-self.radius, j-self.radius)
- all=result.sum()
- return result/all
- #滤波函数
- def filter(self, image, template):
- arr=np.array(image)
- height=arr.shape[0]
- width=arr.shape[1]
- newData=np.zeros((height, width))
- for i in range(self.radius, height-self.radius):
- for j in range(self.radius, width-self.radius):
- t=arr[i-self.radius:i+self.radius+1, j-self.radius:j+self.radius+1]
- a= np.multiply(t, template)
- newData[i, j] = a.sum()
- newImage = Image.fromarray(newData)
- return newImage
- r=1 #模版半径,自己自由调整
- s=2 #sigema数值,自己自由调整
- GBlur=MyGaussianBlur(radius=r, sigema=s)#声明高斯模糊类
- temp=GBlur.template()#得到滤波模版
- im=Image.open('lena1.bmp')#打开图片
- image=GBlur.filter(im, temp)#高斯模糊滤波,得到新的图片
- image.show()#图片显示
原图像:
高斯模糊后的图像:
我这个例子同时提供了设置radius和sigema的方法。欢迎大家批评指正。
缺点:
运算时间太长了,跟要处理图像的大小成正比。为了测试能快一点,我只能把lena只取一张脸来测试了!另外,没有考虑边缘像素!
注:
os.listdir(path)遍历文件夹下的所有文件名