2009/03/16
Cython ちょこっとお試し
by
菊地時夫
—
posted at
2009-03-16 10:46
last modified
2009-03-16 10:48
- Python Announce List で Cython というのがあるのを知った。
- 昔、Basic + Assembler で遊んでいたので、高速化にどうかなということで、お試し。
- 気象情報頁の画像色付けに使ってる、uv で色付けというやつを:
# py_colorize.py def _limit(x): if x > 255.: x = 255 if x < 0.: x = 0 return chr(int(x)) def adduv(bwdata, uvdata): size = len(bwdata) x = [] for i in xrange(size): r = float(ord(uvdata[i*3])) g = float(ord(uvdata[i*3+1])) b = float(ord(uvdata[i*3+2])) u = -0.169 * r - 0.331 * g + 0.500 *b; v = 0.500 * r - 0.419 * g - 0.081 *b; y = float(ord(bwdata[i])) r = _limit(y + 1.402 * v) g = _limit(y - 0.344 * u - 0.714 * v) b = _limit(y + 1.772 * u) x.append(r+g+b) return ''.join(x)
- Cython にしてみる:
# Cython test # cy_colorize.pyx def _limit(x): if x > 255.: x = 255 if x < 0.: x = 0 return chr(int(x)) def adduv(bwdata, uvdata): cdef int size, i size = len(bwdata) x = [] for i in xrange(size): r = float(ord(uvdata[i*3])) g = float(ord(uvdata[i*3+1])) b = float(ord(uvdata[i*3+2])) u = -0.169 * r - 0.331 * g + 0.500 *b; v = 0.500 * r - 0.419 * g - 0.081 *b; y = float(ord(bwdata[i])) r = _limit(y + 1.402 * v) g = _limit(y - 0.344 * u - 0.714 * v) b = _limit(y + 1.772 * u) x.append(r+g+b) return ''.join(x)
- 実は Python-C API を使って作ったのがあるので、それも:
/* c_colorize.c */ #include <Python.h> #include <stdlib.h> #include <math.h> static unsigned char limit(double x) { if (x > 255.) x = 255.; if (x < 0.) x = 0.; return (unsigned char)x; } static PyObject * c_colorize_adduv(PyObject *self, PyObject *args) { long i, size, dummy; double r, g, b, u, v, y; unsigned char *bwdata, *uvdata, *cldata, *cl; if (!PyArg_ParseTuple(args, "s#s#", &bwdata, &size, &uvdata, &dummy)) return NULL; if ((cldata = malloc(3*size)) == NULL) return NULL; cl = cldata; for (i = 0; i < size; i++) { r = (double)(*uvdata++); g = (double)(*uvdata++); b = (double)(*uvdata++); u = -0.169 * r - 0.331 * g + 0.500 *b; v = 0.500 * r - 0.419 * g - 0.081 *b; y = (double)(*bwdata++); *cldata++ = limit(y + 1.402 * v); *cldata++ = limit(y - 0.344 * u - 0.714 * v); *cldata++ = limit(y + 1.772 * u); } return Py_BuildValue("s#", cl, size*3); } static PyMethodDef c_colorizeMethods[] = { {"adduv", c_colorize_adduv, METH_VARARGS, "adduv(bwdata, uvdata)"}, {NULL, NULL, 0, NULL} }; PyMODINIT_FUNC initc_colorize(void) { (void) Py_InitModule("c_colorize", c_colorizeMethods); }
- テストプログラム:
import Image from py_colorize import adduv as py_adduv from cy_colorize import adduv as cy_adduv from c_colorize import adduv as c_adduv import time m = Image.open('sample.gif') m = m.convert('L') c = Image.open('sample.jpg') md = m.tostring() cd = c.tostring() # python t = time.time() xd = py_adduv(md, cd) print time.time() - t x = Image.fromstring('RGB', m.size, xd) x.save('sample-py.jpg') # cython t = time.time() xd = cy_adduv(md, cd) print time.time() - t x = Image.fromstring('RGB', m.size, xd) x.save('sample-cy.jpg') # c t = time.time() xd = c_adduv(md, cd) print time.time() - t x = Image.fromstring('RGB', m.size, xd) x.save('sample-c.jpg')
- テスト結果(400x300の画像を使用):
$ python testcol.py 1.12569904327 0.657740831375 0.00496792793274
- こんなもんか。Cython コードは、多分もっと早くなるように改良できるのだろう。
- ところで、Cython の発音は? カイソン?チャイソン?ツァイソン?
- Category(s)
- なんでも
- The URL to Trackback this entry is:
- http://sango.lab.tkikuchi.net/Members/tkikuchi/30e130e2/cython-30613087305330633068304a8a663057/tbping
- 教科「情報」で入試をやる理由
- ¦
- Main
- ¦
- 挨拶用メモ