Difference between revisions of "CompSciWeek9"
(→Class 2, python's ctypes) |
(→vis.py - visualize the DWT by running on image data) |
||
(One intermediate revision by the same user not shown) | |||
Line 59: | Line 59: | ||
Reference: [https://docs.python.org/2/library/ctypes.html Python Docs] [http://wiki.scipy.org/Cookbook/Ctypes Numpy + Ctypes Cookbook] |
Reference: [https://docs.python.org/2/library/ctypes.html Python Docs] [http://wiki.scipy.org/Cookbook/Ctypes Numpy + Ctypes Cookbook] |
||
− | '''dwt.c''' - run one step of a discrete wavelet transformation. |
+ | === '''dwt.c''' - run one step of a discrete wavelet transformation. === |
<source lang="C"> |
<source lang="C"> |
||
#include <stdint.h> |
#include <stdint.h> |
||
Line 91: | Line 91: | ||
</source> |
</source> |
||
− | Compile the C code to a shared library using gcc: |
+ | === Compile the C code to a shared library using gcc: === |
<source lang="bash"> |
<source lang="bash"> |
||
gcc -o dwt_c.so -shared dwt.c |
gcc -o dwt_c.so -shared dwt.c |
||
</source> |
</source> |
||
⚫ | |||
+ | |||
− | '''dwt.py''' |
||
⚫ | |||
<source lang="python"> |
<source lang="python"> |
||
from ctypes import CDLL, c_int32, c_double |
from ctypes import CDLL, c_int32, c_double |
||
Line 133: | Line 133: | ||
</source> |
</source> |
||
− | '''vis.py''' - visualize the DWT by running on image data |
+ | === '''vis.py''' - visualize the DWT by running on image data === |
<source lang="python"> |
<source lang="python"> |
||
− | import PIL |
||
+ | from PIL import Image |
||
+ | from pylab import imshow, show |
||
from dwt import run_dwt, np |
from dwt import run_dwt, np |
||
# convert to 1-color (luminance) |
# convert to 1-color (luminance) |
||
− | img = |
+ | img = Image.open("Mitosis.png").convert("L") |
x = np.array(img) |
x = np.array(img) |
||
y = np.array(map(run_dwt, x)) |
y = np.array(map(run_dwt, x)) |
||
− | img = PIL.Image.fromarray(y) |
||
+ | imshow(y) |
||
− | + | show() |
|
+ | #img = Image.fromarray(y) |
||
+ | #img.show() |
||
</source> |
</source> |
||
Here's a test image to use: |
Here's a test image to use: |
||
− | [[File:Mitosis.png]] |
+ | [[File:Mitosis.png|300px|alt=Mitosis]] |
Image from [http://brookeborel.com/2011/06/02/363/ Brooke Borel]. |
Image from [http://brookeborel.com/2011/06/02/363/ Brooke Borel]. |
Latest revision as of 11:14, 22 October 2014
Contents
Class 1, an in-depth look at class structure
- magic methods, __init__, etc.
- class inheritance - extending something that does almost what you want
- ex. inheriting from dict
- isinstance() function
- methods and calling convention - the first argument to a class method is always the class (i.e. self)
- Binary operations __add__, __mul__, etc. - these have type class -> class -> class
- static (immutable) vs. dynamic (mutable)
- classes are static
- instances are dynamic
- unless you only initialize and don't ever change them
- if you know it's static and __hash__ is implemented, you can use it as a key
Example - wrapping a numpy array in a static class to build a cache: <source lang="python"> from numpy import *
- TODO: make static!
class s_ndarray:
def __init__(self, x): self.x = x def __hash__(self): return hash(self.x.__repr__())
a = s_ndarray(arange(12))
- array -> float
def en(x): print "Running (expensive) energy calculation." return x[0]
- { s_ndarray : float } -> s_ndarray -> float
def en_cached(cache, x): if x not in cache: cache[x] = en(x.x) # peel off s_ndarray and run the en function return cache[x]
cache = {} x = s_ndarray(arange(12)) y = s_ndarray(ones(12)) print en_cached(cache, x) print en_cached(cache, y)
print cache
- these don't need to call en
print en_cached(cache, y) print en_cached(cache, y) </source>
Class 2, python's ctypes
- Compiling a c code as a shared object
- the trouble with integers - always pick a fixed size!
- loading with ctypes
- Declaring function types.
- Performance test
Reference: Python Docs Numpy + Ctypes Cookbook
dwt.c - run one step of a discrete wavelet transformation.
<source lang="C">
- include <stdint.h>
/* Calculate the step-function discrete wavelet transformation
* on the data x, placing the result in y. * * This assumes x and y are already allocated and of size n. * * x = ababab ababab * y = (a+b) (b-a) */
int32_t dwt(double *x, double *y, int32_t n) { int i; // index into x, moves from 0, ..., n-1 int a = 0; // index into y sum, moves from 0, ..., ceil n/2 int b = (n+1)/2; // index into y difference, moves from (ceil n/2)+1, ..., n-1
for(i=0; i<n-1; i+=2) { y[a] = 0.5*(x[i+1]+x[i]); y[b] = x[i+1]-x[i]; a += 1; b += 1; } // odd case, ceil n/2 = (n+1)/2 and we have an extra sum if(i == n-1) { y[a] = x[i]; }
return 0; } </source>
<source lang="bash"> gcc -o dwt_c.so -shared dwt.c </source>
dwt.py - load and run the object from python
<source lang="python"> from ctypes import CDLL, c_int32, c_double import numpy as np import numpy.ctypeslib as ct import os
cwd = os.path.dirname(os.path.abspath(__file__)) dw = CDLL(os.path.join(cwd, "dwt_c.so"))
- Shorthand for setting function prototypes
def decl_fn(a, *args):
a.argtypes = args[:-1] a.restype = args[-1]
def void_fn(a, *args):
decl_fn(a, *(args+(None,)))
def int_fn(a, *args):
decl_fn(a, *(args+(c_int32,)))
def dbl_fn(a, *args):
decl_fn(a, *(args+(c_double,)))
- Building up common, useful data types
intarr = np.ctypeslib.ndpointer(dtype=np.int32, flags='C_CONTIGUOUS') dblarr = np.ctypeslib.ndpointer(dtype=np.float64, flags='C_CONTIGUOUS')
decl_fn(dw.dwt, dblarr, dblarr, c_int32)
def run_dwt(x): y = np.zeros(x.shape, dtype=np.float64) print dw.dwt(x.astype(np.float64), y, len(x)) return y
print run_dwt(np.arange(12)) print run_dwt(np.arange(11)) </source>
vis.py - visualize the DWT by running on image data
<source lang="python"> from PIL import Image from pylab import imshow, show from dwt import run_dwt, np
- convert to 1-color (luminance)
img = Image.open("Mitosis.png").convert("L") x = np.array(img)
y = np.array(map(run_dwt, x))
imshow(y) show()
- img = Image.fromarray(y)
- img.show()
</source>
Here's a test image to use:
Image from Brooke Borel.