Re: [Q] Extending Python for computer vision [LONG]

Dan Connolly (connolly@hal.com)
20 Feb 1995 22:18:29 GMT

In article <GRENDEL.95Feb16145831@fen.arc.nasa.gov> grendel@fen.arc.nasa.gov (Raymond E. Suorsa) writes:

I need some advice and sanity checks from those of you who have
extended Python with a good size C based library.

I've done a little hacking like this... see:

WWWLib and Python Integration (alpha)
Thu Jul 21 07:47:57 1994
http://www.hal.com/~connolly/dist/pywwwlib.html

I also used to work on the AVS (Application Visualization System)
when I was at convex, so I have some experience with image processing.

[1] I would assume the logical way to proceed is to define a type (lets
call it a kimage) with methods that are composed of the "in place"
library functions. Thus if B is a kimage then:

import pykhoros

B = pykhoros.get("someimage")
B.histogramEqualize()

Sounds good.

[2] The operators that have multiple input images would be (well in
C++ they would be friend functions)

(you mean static members functions?)

methods to the module itself thus:

import pykhoros

A = pykhoros.get("mandrill")
B = pykhoros.get("lena")

C = pykhoros.add(A,B)

You could do it smalltalk-style where op(x,y,z) is implemented
as a method on x, i.e. x.op(y,z). This would facilitate A + B
style overloading as you suggest...

We could then make some intelligent mappings when we treat a kimage
as_a_number so:

C = A + B

By the way... please don't call the module pykhoros: just call
it khoros: since the interface is a python interface, the fact
that it's python is self-evident. The .c files that implement
the glue code might be called pykhoros.c, but not the python
module itself.

[1] Many of the "in place" kimage methods and the module methods (<-
what is the proper Python phrase for these) take quite a few
arguments. Many of these arguments are integers and real numbers to
tweak filter parameters. How is the best way to do it:

import pykhoros

B = pykhoros.get("someimage")

B.filter(1.0,2.0,0.4,0.3)

This doesn't give me warm fuzzies... I have never liked ordered
function arguments. Would a dictionary be better?

B.filter( {'K1': 1.0, 'K2': 2.0, 'C1': 0.4, 'C2': 0.3 } )

But would I have to build up this dictionary myself? How does one get
the default argument dictionary from the function? Can it be designed
such that:

B.filter( {'C2': 0.3 } )

Would this dictionary manipulation be done at a python layer just
above my extension type or in the C-Python binding code? The dictionary
method is very much like parameter passing while programming in
Mathematica for those unfamiliar with it.

I'm afraid you would have to do your own default handling, if
you want to use keyword parameter passing. If only python supported
Modula-3 style argument lists! See:

http://www.research.digital.com/SRC/m3defn/html/calls.html

|For example, suppose that the type of P is
|
| PROCEDURE(ch: CHAR; n: INTEGER := 0)
|
|Then the following calls are all equivalent:
|
| P('a', 0)
| P('a')
| P(ch := 'a')
| P(n := 0, ch := 'a')
| P('a', n := 0)
|
|The call P() is illegal, since it doesn't bind ch. The call P(n := 0,
|'a') is illegal, since it has a keyword parameter before a positional
|parameter.

I'm afraid that Modula-3 has the advantage of resolving these
bindings statically at compile-time, whereas python has to
do it at runtime for each function application, so I think
the performance costs would be prohibitive.

The other way (maybe not implementable in python)

B.filter.C2 = 0.3
B.filter.K1 = 1.0
B.filter()

Is this a possible (desirable) construct in Python?

Yuk. Terrible concurrency implimplications. And if there's
any application that lends itself to parallelism, it's
image processing.

[2] The last issue. When confronted with the possibility of extending
Python with a very large library one must seriously how much
programming effort it takes to add each method to Python. I don't
quite know at what point in the design to delegate task to a python
layer module and what to perform in the type extension. Essentially
this project would entail writing a large number of routines that are
probably each just different enough that it could not be easily
automated. Any general opinions and experience with this would be
welcome.

The tricky part is the reference counting. I'm hoping python's
heap gets replaced by somthing like the conservative garbage
collector from SCM, or the Boehm collector or some such. But
for now, INCREF/DECREF works. Remeber: getargs() and mkvalue()
are your friends.

Some of it can be automated. Look at the way the X, Xt, and Xm
support was done: Guido (or somebody else) wrote some scripts
to automate a bunch of the glue code.

In short: python glue code is significantly more painful than, say,
Tcl code. On the other hand, the python interface to a module like
this is going to be much more powerful and easy to build on than a Tcl
interface.

Python glue code is comparable to XLISP or any of the other extension
languages with automated storage management in the extension
language. It's not as nice as SCM, which has automatic storage
management in the glue language.

I think you will be happy with the results of marrying python with
Khoros. When you consider that you can use all the other modules that
have been interfaced to python (Tk, md5, ftp, http/url, various
databases...) along with python's object model and exception system,
you'll have a very comfortable, powerful, reliable, scalable
development platform.

Dan

--
Daniel W. Connolly        "We believe in the interconnectedness of all things"
Software Engineer, Hal Software Systems, OLIAS project   (512) 834-9962 x5010
<connolly@hal.com>                             http://www.hal.com/%7Econnolly