G
Gerdus van Zyl
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[offsetffset
+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)
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[offsetffset
+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)