[PYTHON MATRIX-SIG] Naming Conventions And Practical Experience
Perry A. Stoll
stoll@atr-sw.atr.co.jp
Thu, 08 Feb 1996 18:22:12 +0900
>>>>> "FL" == Fredrik Lundh <Fredrik_Lundh@ivab.se> writes:
FL> would like to use the matrix extension to do some of the
FL> serious processing stuff in my forthcoming Python Imaging
FL> library, like FFTs and 2D convolutions. Any ideas on how to
FL> achieve this?
I'm working on something similar. I've got various FFT packages off
the net - I'll try to interface them, but I don't have time right
now. If you are interested in doing it, let me know.
In the mean time, for those wanting to play take a look at the file
attached at the end. It's not the stuff legends are made of, but it
should work.
-Perry
--------------------- cut here ------------------------------------
""" conv2 - support convolution of a 2 dimensional matrix by a 2
dimensional kernel.
This routine was inspired by the matlab(c) version of conv2.
Sample usage:
>>> import conv2
# a sobel edge finding kernel
>>> sobel = Numeric.array([[1.0 ,2, 1],[0, 0, 0],[-1, -2, -1]])
# a test array
>>> A = Numeric.zeros(10,10)
>>> S = Numeric.Slice(2,8)
>>> A[(S,S)] = 1
# do the convolution
>>> conv2.conv2(A,sobel)
"""
# Two dimension convolution for the Python Numeric package.
# Should be redone in C.
#
# questions to:
# Perry A. Stoll
# <stoll@atr-sw.atr.co.jp> or <pas@lems.brown.edu>
import Numeric,umath
class AddSlice(Numeric.Slice):
def __init__(self, start=0, stop=None, step=1):
Numeric.Slice.__init__(self,start,stop, step)
def __add__(self,x):
newslice = AddSlice(self.start,self.stop,self.step)
newslice.start = newslice.start + x
if newslice.stop != None:
newslice.stop = newslice.stop + x
return newslice
__radd__ = __add__
class IncSlice(Numeric.Slice):
def __init__(self, start=0, stop=None, step=1):
Numeric.Slice.__init__(self,start,stop,step)
def inc(self):
self.start = self.start + 1
if self.stop != None:
self.stop = self.stop + 1
def conv2(arg1,arg2,shape='full'):
""" C = conv2(A, B) performs the 2-D convolution of matrices A and B.
If [ya,xa] == A.shape and [yb,xb] == B.shape, then
C.shape == [ya+yb-1,xa+xb-1].
"""
if (len(arg1.shape) != 2) or (len(arg2.shape) !=2):
raise TypeError, "both arguments must be 2 dimensional"
# we always want to use the small matrix as arg2,
# so swap args if necessary
swapped = 0
Nmr = Numeric.multiply.reduce
size1,size2 = Nmr(arg1.shape),Nmr(arg2.shape)
if (size2 > size1):
swapped = 1
arg1,arg2 = arg2,arg1
# unpack shape tuples
(y1,x1),(y2,x2) = arg1.shape,arg2.shape
# create output matrix
out = Numeric.zeros(y2+y1-1,x2+x1-1)
cols,rows = IncSlice(0,x2),IncSlice(0,y2)
for j in range(0,y1):
rows.start,rows.stop = 0,y2
for i in range(0,x1):
w = arg1[j,i]
if w != 0:
out[cols,rows] = out[cols,rows] + w*arg2
rows.inc()
cols.inc()
# not sure we need to do this...
#if swapped:
#arg1,arg2 = arg2,arg1
if (shape == 'full'):
pass
elif (shape == 'same'):
rows = int(umath.floor(x2/2.0)) + AddSlice(0,x1)
cols = int(umath.floor(y2/2.0)) + AddSlice(0,y1)
out = out[cols,rows]
elif (shape == 'valid'):
rows = x2 -1 + AddSlice(0,x1-x2 + 1)
cols = y2 -1 + AddSlice(0,y1-y2 + 1)
out = out[cols,rows]
return out
=================
MATRIX-SIG - SIG on Matrix Math for Python
send messages to: matrix-sig@python.org
administrivia to: matrix-sig-request@python.org
=================