pure python gaussian blur

Gerdus van Zyl gerdusvanzyl at gmail.com
Tue Aug 14 12:24:39 EDT 2007


Does anyone have a relatively fast gaussian blur implemented in pure
python? Below is my attempt but it takes 2.9 seconds for a 320x240
image. Image comes from byte string: self.array =
array.array('B',srcstring). Would some sort of matrix multiplication
be faster? I don't have experience in that.

I don't want to use PIL or http://filters.sourceforge.net/ to avoid
the 300kb dll just for a simple blur.


    def blur(self):
        # Convolution Kernels
        blurFilter = [[0,1,2,1,0],
                      [1,2,4,2,1],
                      [2,4,8,4,2],
                      [1,2,4,2,1],
                      [0,1,2,1,0]]
        blurDiv = 48
        blurFilterSize = len(blurFilter) #5
        blurFilterSize2 = blurFilterSize * blurFilterSize

        pixels = self.array

        stride = self.width * 4
        w = self.width
        h = self.height
        red = 0
        green = 0
        blue = 0
        sx = 0
        ex = 0
        sy = 0
        ey = 0
        ss = 0
        f1 = 0
        f2 = 0
        ff = 0
        idx = 0
        samplesize = 0

        offset1 = blurFilterSize/2
        offset2 = blurFilterSize/2+2

        clr = array.array('B',[255,255,255,255])
        px = array.array('B',[255,255,255,255])

        for x in xrange(0,w): #w

            sx = x - offset1
            ex = x + offset2
            if sx < 0: sx = x
            if ex > w:  ex = w

            for y in xrange(0,h):
                sy = y - offset1
                ey = y + offset2

                if sy < 0: sy = y

                if ey > h:  ey = h

                samplesize = (ex-sx) * (ey-sy)
                if samplesize > 0:
                    ss = blurFilterSize2 / samplesize
                    if ss > blurFilterSize - 2:
                        ss = blurFilterSize - 2
                else:
                    ss = 0


                idx = 0
                ffx = 0
                red = 0
                green = 0
                blue = 0

                for vx in xrange(sx,ex):
                    for vy in xrange(sy,ey):
                        offset = vy * stride + vx * 4

                        px = pixels[offset:offset
+4]

                        f1 = idx / 5
                        f2 = (idx - f1) % 5
                        f1 += ss
                        if f1 > 4:
                            f1 = 4

                        ff = blurFilter[f1]
[f2]
                        #ff = 1
                        ffx += ff
                        red   += px[0] * ff
                        green += px[1] * ff
                        blue  += px[2] * ff
                        idx += 1


                if samplesize > 0:
                    red   = red / ffx
                    green = green / ffx
                    blue  = blue / ffx
                    if red > 255: red = 255
                    if green > 255: green = 255
                    if blue > 255: blue = 255

                    clr[0] = red
                    clr[1] = green
                    clr[2] = blue

                    self.setPixel(x, y, clr)




More information about the Python-list mailing list