Advertisement
whoeverest

Runtime binding

Jul 4th, 2012
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.84 KB | None | 0 0
  1. """
  2. I have the following situation: I have an 'iplimage' object that can't be accessed via index (like so: 'image[0][0]'). The only method I can use is image.tostring(), which returns the image data - in a string. And I want to be able to get a specific pixel from the image. So, let's see what my options are.
  3.  
  4.  
  5. 1. Create a function get_pixel(img, x, y)
  6.  
  7. This takes the image object as a first argument, and returns the pixel values at (x,y). What I don't like about this approach is that the function, which logicaly belongs to the 'iplimage' class, is defined outside.
  8.  
  9. The method would look something like:
  10. """
  11.  
  12. def get(im, x, y):
  13.     row = map(ord, im.tostring())
  14.     return [row[i::self.nChannels][self.width * x + y] for i in range(self.nChannels)]
  15.  
  16. """
  17. 2. Make a class which inherits from 'iplimage'
  18.  
  19. Well, that's perfect. I'll define my class:
  20. """
  21.  
  22. class implimage_with_index(object):
  23.     def get(self, x, y):
  24.         row = map(ord, self.tostring)
  25.         # ... etc
  26.  
  27. """
  28. The thing is, what do I do with 'iplimage' objects returned by other functions? Like cv.LoadImage("path/to/image.png")? One way would be to somehow modify the 'cv.LoadImage' class, at runtime, so it returns *my* type of object. This looked needlessly complicated, so I didn't go further.
  29.  
  30. 3. Attach the "get()" method to the "img" object
  31.  
  32. It turns out, you can't do this in Python. Or rather, you can, by only to your own classes, and not for built-ins (and 'iplimage', as we'll see.) So this:
  33. """
  34.  
  35. class MyClass(object):
  36.     pass
  37.  
  38. MyClass.get = lambda self, x,y: return # whatever..
  39.  
  40. my_obj = MyClass()
  41. my_obj.get(0,0)
  42.  
  43. """
  44. works. But if I try to modify the 'iplimage' class this way, it throws an TypeException:
  45.  
  46. TypeError: can't set attributes of built-in/extension type 'cv2.cv.iplimage'
  47.  
  48. From what I know, this limitation is due to the CPython implementation. The last thing I though of (or rather found by googling) is:
  49.  
  50. 4. Use types.MethodType to bind "get()" to the "iplimage" object
  51.  
  52. This approach exploits the way Python binds methods to objects behind the scene. So I can write:
  53. """
  54.  
  55. import types
  56.  
  57. def get(self, x, y):
  58.     return self.whatever
  59.  
  60. img = cv.LoadImage("path/to/image.png")
  61.  
  62. # the signature of the method is: MethodType(function, instance, class)
  63. # and it binds the function to the instance with type 'class'
  64. get_bound = types.MethodType(get, img, cv.iplimage)
  65.  
  66. # so when I call:
  67. print get_bound()
  68. # it returns the 'whatever' property of 'img' (self works as expected)
  69.  
  70. """
  71. And this is where I run out of ideas. This last approach gives me no benefit, becase at the and I'm still calling get(x,y) outside of the object, with the difference of an implicit 'img' argument. It seems that there's no elegant way to dynamically add methods to random imported classes implemented in C. So I'll just use the first approach, def get(img, x, y).
  72. """
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement