關於高斯模糊的詳細介紹及python代碼實現

高斯模糊的算法 html

講的是Gaussian Blur,講的很詳細,值得仔細閱讀!python

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#這個地方明顯不對
    def filter(self, image):
        return image.gaussian_blur(self.radius)

本身改正過來:ide

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()#圖片顯示

原圖像:spa


高斯模糊後的圖像:日誌


我這個例子同時提供了設置radius和sigema的方法。歡迎你們批評指正。code

缺點:

運算時間太長了,跟要處理圖像的大小成正比。爲了測試能快一點,我只能把lena只取一張臉來測試了!另外,沒有考慮邊緣像素!


相關文章
相關標籤/搜索