pure python gaussian blur
Gerdus van Zyl
gerdusvanzyl at gmail.com
Sat Aug 25 09:38:42 EDT 2007
Ok, now answering my own question :-)
Gaussian blurs can be optimized by seperating the equation and
applying in two passes.
I also implemented a version using State Vector Machines from www-
personal.engin.umd.umich.edu/~jwvm/ece581/21_GBlur.pdf but it does not
produce correct results. Most probably my fault, but it is 4x faster.
(code available on request)
Then after all this i learnt that using multiple box blurs approximate
a gaussian blur within 3%. This is the solution i use now and is fast
enough for my needs and in pure python.
Code for gaussian blur and box blur below.
~Gerdus van Zyl
Seperated Gaussian blur:
def blurB(self):
pixels = self.array
temp1 = copy.copy(pixels)
#temp2 = copy.copy(pixels)
stride = self.width * 4
clr = array.array('B',[255,255,255,255])
w = self.width
h = self.height
def pascal(n):
"""Prints n first lines of Pascal`s triangle
author: DR#m <dnpsite.narod.ru>
last rev 20.03.05"""
#n += 1
l=[1]
p=[]
for i in xrange(n):
l2=[1]
for j in xrange(len(l)-1):
l2.append(l[j]+l[j+1])
l2.append(1)
#print l
l=l2
return l
N = 5
g = pascal(N)
print '>',g
gauss_fact = g
#gauss_fact = [1,2,1]
#gauss_fact = [1,1]
gauss_width = len(gauss_fact)
s = 0
for n in gauss_fact:
s += n
gauss_sum = s
print "Pass01"
for i in range(1,w-1):
#print i," of ",w
for j in range(1,h-1):
sumr=0
sumg=0
sumb=0
for k in range(0,gauss_width):
x = i-((gauss_width-1)>>1)+k
y = j
offset = y * stride + x * 4
pixel = pixels[offset:offset
+4]
r = pixel[0]
g = pixel[1]
b = pixel[2]
sumr+=r*gauss_fact[k]
sumg+=g*gauss_fact[k]
sumb+=b*gauss_fact[k]
clr[0] = sumr/gauss_sum
clr[1] = sumg/gauss_sum
clr[2] = sumb/gauss_sum
x = i
y = j
offset = y * stride + x * 4
temp1[offset:offset+4] =
clr
print "Pass02"
for i in range(1,w-1):
#print i," of ",w
for j in range(1,h-1):
sumr=0
sumg=0
sumb=0
for k in range(0,gauss_width):
x = i-((gauss_width-1)>>1)+k
y = j
offset = y * stride + x * 4
pixel = temp1[offset:offset+4]
r = pixel[0]
g = pixel[1]
b = pixel[2]
sumr+=r*gauss_fact[k]
sumg+=g*gauss_fact[k]
sumb+=b*gauss_fact[k]
clr[0] = sumr/gauss_sum
clr[1] = sumg/gauss_sum
clr[2] = sumb/gauss_sum
self.setPixel(i,j,clr) #to temp1
Box Blur:
def _boxBlur(self):
N = 5
xsum = 0
xsumar = []
pixels = self.array
opixels = copy.copy(pixels)
stride = self.width * 4
clr = array.array('B',[255,255,255,255])
w = self.width
h = self.height
pixel = 0
for rgb in [0,1,2]:
for x in range(0,w):
#print i," of ",w
for y in range(0,h):
hN = N/2
offset = (y-hN) * stride + (x-hN) * 4
if offset < 0: offset = 0
pixel = pixels[offset+rgb]
xsumar.append(pixel)
if len(xsumar) > N:
xsumar = xsumar[-N:]
xsum = 0
for v in xsumar:
xsum += v
xsum /= len(xsumar)
pixels[offset+rgb] = xsum
#x
for rgb in [0,1,2]:
for y in range(0,h):
#print i," of ",w
for x in range(0,w):
hN = N/2
offset = (y-hN) * stride + (x-hN) * 4
if offset < 0: offset = 0
pixel = pixels[offset+rgb]
xsumar.append(pixel)
if len(xsumar) > N:
xsumar = xsumar[-N:]
xsum = 0
for v in xsumar:
xsum += v
xsum /= len(xsumar)
pixels[offset+rgb] = xsum
More information about the Python-list
mailing list