Personal tools
You are here: Home メンバー 菊地時夫 メモ Cython ちょこっとお試し
Document Actions

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
« December 2010 »
Su Mo Tu We Th Fr Sa
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
About this blog
メモ代わりのブログ
Recent entries
JIS を戻すって tkikuchi 2010-06-14
ゼネラリスト tkikuchi 2010-04-26
Solaris 10 で 64bit tkikuchi 2010-04-11
なんかマヌケ? tkikuchi 2010-02-22
Oracle + ASP.NET なんですね tkikuchi 2010-01-28
Recent comments
Re:lock できないので tkikuchi 2009-06-03
Re:挨拶用メモ tkikuchi 2009-05-27
Re:挨拶用メモ knakahasi 2009-05-04
Re:Xgrid (続編) tkikuchi 2008-10-09
PILでのグラフ出力 ytoshio 2008-03-06
Categories
なんでも
 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: