daily pastebin goal
68%
SHARE
TWEET

OpenCV connection to Blender25

a guest Sep 18th, 2010 1,203 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/python
  2. # OpenCV and Blender - Test1 Sept 19, 2010
  3. # by HartsAntler - bhartsho@yahoo.com
  4. # License: GNU GPL3
  5. # Tested with Ubuntu Lucid and Blender2.54
  6.  
  7. '''
  8. Hacking - Ram Drive Workaround:
  9.         mkdir /tmp/ramdrive
  10.         sudo mount -t ramfs /dev/ram10 /tmp/ramdrive/
  11.         sudo chmod 777 /tmp/ramdrive
  12.  
  13.  
  14. Getting Blender Connected:
  15.         0. sudo apt-get install python-opencv python-pygame python3
  16.  
  17.         1. download posix_ipc from http://semanchuk.com/philip/posix_ipc
  18.         2. cd posix_ipc-0.8.1/
  19.         3. sudo python setup.py install
  20.         4. sudo python3 setup.py install
  21.         5. set the path to blender25 below `PATH2BLENDER`
  22.  
  23.         (blender will not respect local py3 installations? this step should be optional)
  24.         6. cp -Rv /usr/local/lib/python3.1/dist-packages/posix_ipc.so /<change me>/blender25/2.53/python/lib/python3.1/site-packages/.
  25.  
  26. #6 will fail if your local python is Python 3.1.2 [GCC 4.4.3] and Blender is compiled with Python 3.1.1 [GCC 4.3.3]
  27. ImportError: /home/brett/pyppet2/blender25/2.53/python/lib/python3.1/site-packages/posix_ipc.so: undefined symbol: PyUnicodeUCS4_FromString
  28.  
  29. '''
  30. PATH2BLENDER = 'blender25/blender'
  31.  
  32. Size640x480_RGBA = 1228800
  33. import os, sys, time
  34.  
  35. SHARED_MEMORY = '/mysharedmem'          # '/tmp/something' is invlid is tmp sharedmemory has not been created
  36. SEMAPHORE_NAME = '/mysemaphore'
  37.  
  38. PY_MAJOR_VERSION = sys.version_info[0]
  39. if PY_MAJOR_VERSION > 2: NULL_CHAR = 0
  40. else: NULL_CHAR = '\0'
  41.  
  42.  
  43. import multiprocessing, ctypes
  44. from multiprocessing import sharedctypes
  45.  
  46. posix_ipc = None
  47. try: import posix_ipc
  48. except: print( 'posix_ipc not installed' )
  49.  
  50. import mmap
  51.  
  52.  
  53. def shm_write(mapfile, s):
  54.         """Writes the string s to the mapfile"""
  55.         mapfile.seek(0)
  56.         #s += '\0'      # I append a trailing NULL in case I'm communicating with a C program.
  57.         if PY_MAJOR_VERSION > 2: s = s.encode()
  58.         mapfile.write(s)
  59.  
  60. def shm_read_slowly(mapfile):
  61.         """Reads a string from the mapfile and returns that string"""
  62.         mapfile.seek(0)
  63.         s = [ ]
  64.         c = mapfile.read_byte()
  65.         while c != NULL_CHAR:
  66.                 s.append(c)
  67.                 c = mapfile.read_byte()
  68.         if PY_MAJOR_VERSION > 2: s = [chr(c) for c in s]
  69.         s = ''.join(s)  
  70.         return s
  71.  
  72. def shm_read(mapfile):
  73.         """Reads a string from the mapfile and returns that string"""
  74.         mapfile.seek(0)
  75.         return mapfile.read(Size640x480_RGBA)
  76.  
  77. '''
  78. if 0:           # ctypes can not load libc
  79.         import ctypes.util
  80.         libc = ctypes.util.find_library('libc')
  81.         print libc
  82.         libc = ctypes.CDLL('/usr/lib/libc.a')
  83.         print libc
  84.         raise
  85. '''
  86.  
  87. class BlenderConnection(object):
  88.         def __init__(self):
  89.                 if posix_ipc:
  90.                         print( 'trying to open sharedmemory')
  91.                         self.shm = memory = posix_ipc.SharedMemory(SHARED_MEMORY)
  92.                         # MMap the shared memory
  93.                         self.mapfile = mmap.mmap(memory.fd, memory.size, mmap.MAP_PRIVATE)              # MAP_PRIVATE=copy-on-write
  94.                         #os.close(memory.fd)            # also valid
  95.                         memory.close_fd()
  96.                         print( 'sharedmem', self.mapfile)
  97.                         self.semaphore = posix_ipc.Semaphore(SEMAPHORE_NAME)
  98.  
  99.                 self.bimage = im = bpy.data.images.new('_opencv_')
  100.                 im.source = 'FILE'
  101.                 im.filepath = '/tmp/ramdrive/dump.png'
  102.                 tex = bpy.data.textures[0]
  103.                 tex.type = 'IMAGE'              # invalidates object, get again
  104.                 self.btexture = tex = bpy.data.textures[0]
  105.                 tex.image = im
  106.                 self.bmat = mat = bpy.data.materials[0]
  107.                 mat.use_transparency=True
  108.                 mat.alpha = .0
  109.                 mat.emit = 1.0
  110.                 mat.specular_intensity = .0
  111.  
  112.                 ts = mat.texture_slots[0]
  113.                 ts.use_map_alpha=True
  114.  
  115.                 scn = bpy.data.scenes[0]
  116.                 scn.game_settings.material_mode = 'GLSL'
  117.  
  118.                 self.setup_blender_loop()
  119.  
  120.         def setup_blender_loop(self):           # hacks like this should not have to be pulled anymore!?
  121.                 bpy.ops.screen.animation_play('EXEC_DEFAULT')
  122.                 for area in bpy.context.window.screen.areas:
  123.                         print(area.type)
  124.                         if area.type == 'VIEW_3D':
  125.                                 #print('viewportshade', area.viewport_shade)
  126.                                 for reg in area.regions:
  127.                                         print( '\tregion: ', reg.type )
  128.                                         if reg.type == 'WINDOW':
  129.                                                 print( 'adding callback' )
  130.                                                 reg.callback_add(self.loop, (area,reg), 'POST_PIXEL')
  131.  
  132.         def loop( self, area, reg ):
  133.                 if posix_ipc:
  134.                         self.semaphore.acquire()
  135.                         data = shm_read( self.mapfile )
  136.                         self.semaphore.release()
  137.                         print( len(data) )
  138.                 if self.bimage.bindcode:
  139.                         #self.bimage.gl_free()
  140.                         self.bimage.reload()
  141.  
  142. if '--blender' in sys.argv:
  143.         import bpy
  144.         bc = BlenderConnection()
  145.  
  146. else:
  147.         import pygame
  148.         #import Image, ImageDraw, ImageChops
  149.         import gtk, glib, cairo, pango, gobject
  150.  
  151.         import opencv as cv
  152.         from opencv import highgui
  153.         cv.cvSetNumThreads(3)           # 4 threads might be wasteful
  154.         print( 'opencv threads', cv.cvGetNumThreads() )
  155.  
  156.         _colorspaces = '''
  157.         CV_BGR2GRAY
  158.         CV_BGR2HLS
  159.         CV_BGR2HSV
  160.         CV_BGR2Lab
  161.         CV_BGR2Luv
  162.         CV_BGR2RGB
  163.         CV_BGR2XYZ
  164.         CV_BGR2YCrCb
  165.         '''
  166.         ColorSpaces = {}
  167.         ColorSpacesByValue = {}
  168.         for name in _colorspaces.splitlines():
  169.                 name = name.strip()
  170.                 if name:
  171.                         value = getattr(cv,name)
  172.                         ColorSpacesByValue[ value ] = name
  173.                         ColorSpaces[ name ] = value
  174.  
  175. BG_RED = 0.98
  176. BG_GREEN = 0.98
  177. BG_BLUE = 0.99
  178. BG_ALPHA = 0.0
  179. BG_COLOR = (BG_RED,BG_GREEN,BG_BLUE,BG_ALPHA)
  180.  
  181. def transparent_window( win, color=BG_COLOR, decorate=False ):
  182.         win.set_decorated( decorate )
  183.         # Tell GTK+ that we want to draw the windows background ourself.
  184.         # If we don't do this then GTK+ will clear the window to the
  185.         # opaque theme default color, which isn't what we want.
  186.         win.set_app_paintable(True)
  187.         make_transparent( win, color )
  188.  
  189.  
  190. def expose_transparent(widget, event):
  191.         cr = widget.window.cairo_create()
  192.         r,g,b,a = widget._trans_color_hack
  193.         cr.set_source_rgba(r, g, b, a) # Transparent
  194.         # Draw the background
  195.         cr.set_operator(cairo.OPERATOR_SOURCE)
  196.         cr.paint()
  197.         return False
  198.  
  199. def make_transparent(widget, color=BG_COLOR ):
  200.         widget._trans_color_hack = color
  201.         # The X server sends us an expose event when the window becomes
  202.         # visible on screen. It means we need to draw the contents.  On a
  203.         # composited desktop expose is normally only sent when the window
  204.         # is put on the screen. On a non-composited desktop it can be
  205.         # sent whenever the window is uncovered by another.
  206.         #
  207.         # The screen-changed event means the display to which we are
  208.         # drawing changed. GTK+ supports migration of running
  209.         # applications between X servers, which might not support the
  210.         # same features, so we need to check each time.
  211.         widget.connect('expose-event', expose_transparent)
  212.         #win.connect('screen-changed', self.screen_changed)
  213.         # To check if the display supports alpha channels, get the colormap
  214.         screen = widget.get_screen()
  215.         colormap = screen.get_rgba_colormap()
  216.         # Now we have a colormap appropriate for the screen, use it
  217.         widget.set_colormap(colormap)
  218.         return False
  219.  
  220.  
  221. '''
  222. useful utils:
  223. cv.Ipl2NumPy
  224. cv.Ipl2PIL
  225. cv.NumPy2Ipl
  226. cv.NumPy2PIL
  227. cv.PIL2Ipl
  228. cv.PIL2NumPy
  229.  
  230. notes:
  231. CV_ADAPTIVE_THRESH_GAUSSIAN_C
  232. CV_ADAPTIVE_THRESH_MEAN_C
  233. CV_CALIB_CB_ADAPTIVE_THRESH
  234. CV_THRESH_BINARY
  235. CV_THRESH_BINARY_INV
  236. #something else? CV_THRESH_MASK         # adaptive only?
  237. #CV_THRESH_OTSU
  238. CV_THRESH_TOZERO
  239. CV_THRESH_TOZERO_INV
  240. CV_THRESH_TRUNC
  241. cvAdaptiveThreshold
  242. cvThreshHist
  243. cvThreshold
  244.  
  245. cvAdaptiveThreshold(*args)
  246.    cvAdaptiveThreshold(CvArr src, CvArr dst, double max_value, int adaptive_method = 0,
  247.        int threshold_type = 0, int block_size = 3,
  248.        double param1 = 5)
  249.  
  250. cvThreshold(*args)
  251.    cvThreshold(CvArr src, CvArr dst, double threshold, double max_value,
  252.        int threshold_type) -> double
  253.  
  254.  
  255. '''
  256.  
  257.  
  258.  
  259. def pygame_to_pil_img(pg_img):
  260.         imgstr = pygame.image.tostring(pg_img, 'RGB')
  261.         return Image.fromstring('RGB', pg_img.get_size(), imgstr)
  262.  
  263. def pil_to_pygame_img(pil_img):
  264.         imgstr = pil_img.tostring()
  265.         return pygame.image.fromstring(imgstr, pil_img.size, 'RGB')
  266.  
  267. class Trackable(object):
  268.         def __init__(self, haar):
  269.                 self.haar = haar
  270.                 self._cv_storage = cv.cvCreateMemStorage(0)
  271.                 self.score = .0
  272.                 self.rects = []
  273.                 self.color = None
  274.                 self.grayscale = None
  275.  
  276.         #               cv.cvSetImageROI( grayscale, cv.cvRect(fx, fy, fw, fh) )
  277.         #               cv.cvClearMemStorage(storage)   # this invalidates the f.x, f.* attributes
  278.         def detector( self, grayscale, scale=1 ):
  279.                 self.grayscale = grayscale
  280.                 storage = self._cv_storage
  281.                 cv.cvClearMemStorage(storage)
  282.                 # equalize histogram
  283.                 cv.cvEqualizeHist(grayscale, grayscale)
  284.  
  285.                 _rects = cv.cvHaarDetectObjects(grayscale, self.haar, storage, 1.2, 2, cv.CV_HAAR_DO_CANNY_PRUNING, cv.cvSize(25, 25))
  286.                 rects = []
  287.                 if _rects:
  288.                         for r in _rects:
  289.                                 rects.append( pygame.rect.Rect(r.x*scale, r.y*scale, r.width*scale, r.height*scale) )
  290.                 return rects
  291.  
  292. _cfg_ubytes =  'active alpha blur athresh_block_size thresh_min thresh_max'.split()
  293. _cfg_ubytes += 'sobel_xorder sobel_yorder sobel_aperture'.split()
  294. _cfg_ubytes += 'split_red split_green split_blue'.split()
  295. FXtypes = 'FXsplit FXstencil FXblur FXsobel FXathresh FXthresh FXdetect'.split()
  296. _cfg_ubytes += FXtypes
  297. class LayerConfig( ctypes.Structure ):
  298.         _fields_ = [ ('colorspace',ctypes.c_int) ]
  299.         for tag in _cfg_ubytes: _fields_.append( (tag, ctypes.c_ubyte) )
  300.         #for tag in _cfg_ints: _fields_.append( (tag, ctypes.c_int) )
  301.         del tag
  302.  
  303. class UI(object):
  304.         def __init__(self, active, layers, rawimage):
  305.                 self.active = active            # shared
  306.                 self.layers = layers            # shared
  307.                 self.rawimage = rawimage
  308.  
  309.                 ## gtk ##
  310.                 self.window = win = gtk.Window()
  311.                 win.set_size_request( 900, 480 )
  312.                 win.set_title( 'Harts OpenCV Blender Demo' )
  313.                 win.connect('destroy', lambda w: gtk.main_quit() )
  314.                 transparent_window( win, decorate=True )
  315.                 root = gtk.HBox(); root.set_border_width( 3 )
  316.                 win.add( root )
  317.  
  318.                 #####################################
  319.                 eb = gtk.EventBox()
  320.                 root.pack_start( eb, expand=False )
  321.                 self._drawing_area = da = gtk.DrawingArea()
  322.                 da.set_size_request( 640,480 )
  323.                 da.connect('realize', self.realize)
  324.                 eb.add( da )
  325.                 make_transparent(da)
  326.  
  327.                 ##################
  328.                 eb = gtk.EventBox()
  329.                 root.pack_start( eb, expand=True )
  330.                 split = gtk.VBox(); eb.add( split )
  331.                 make_transparent(split)
  332.  
  333.                 header = gtk.HBox(); split.pack_start( header, expand=False )
  334.                 b = gtk.Button('open blender')
  335.                 b.connect('clicked', lambda b: os.system('%s -P %s --blender &'%(PATH2BLENDER, sys.argv[0])) )
  336.                 header.pack_start( b, expand=False )
  337.  
  338.                 b = gtk.ToggleButton('[-]'); b.set_active(True)
  339.                 b.connect('toggled', lambda b: win.set_decorated( b.get_active() ) )
  340.                 header.pack_start( b, expand=False )
  341.                
  342.  
  343.                 #ex = gtk.Expander( 'settings' ); ex.set_expanded(False)
  344.                 #split.pack_start( ex, expand=False )
  345.                 #ex = gtk.Expander( 'adjust layers' ); ex.set_expanded(True)
  346.                 #split.pack_start( ex, expand=True)
  347.  
  348.                 note = gtk.Notebook()
  349.                 note.set_tab_pos( gtk.POS_RIGHT )
  350.                 #ex.add( note )
  351.                 split.pack_start( note )
  352.                 for layer in layers:
  353.                                 cspace = ColorSpacesByValue[ layer.colorspace ]
  354.                                 tag = cspace.split('2')[-1]
  355.                                 page = gtk.HBox()
  356.                                 h = gtk.HBox()
  357.                                 b = gtk.CheckButton()
  358.                                 b.connect('toggled', lambda b,lay: setattr(lay,'active',bool(b.get_active())), layer)
  359.                                 h.pack_start( b, expand=False )
  360.                                 h.pack_start( gtk.Label(tag) )
  361.                                 note.append_page( page, h )
  362.                                 h.show_all()
  363.                                 b.set_active( bool(layer.active) )
  364.  
  365.                                 col1, col2 = gtk.VBox(), gtk.VBox()
  366.                                 page.pack_start( col1, expand=False )
  367.                                 page.pack_start( col2, expand=True )
  368.  
  369.                                 fxgroups = {}
  370.                                 for name in FXtypes:
  371.                                         bx = gtk.VBox()
  372.                                         fxgroups[ name.split('FX')[-1] ] = bx
  373.                                         frame = gtk.Frame(); frame.add( bx )
  374.                                         val = getattr( layer, name )
  375.                                         b = gtk.CheckButton( name )
  376.                                         b.set_active( bool(val) )
  377.                                         b.connect('toggled', lambda b,lay,nam: setattr(lay,nam,bool(b.get_active())), layer, name)
  378.                                         frame.set_label_widget( b )
  379.                                         col2.pack_end( frame )
  380.  
  381.                                 for name in dir(layer):
  382.                                         if not name.startswith('_') and name not in ['colorspace','active']+FXtypes:
  383.                                                 val = getattr( layer, name )
  384.                                                 bx = None
  385.                                                 for fx in fxgroups:
  386.                                                         if name.startswith(fx):
  387.                                                                 bx = fxgroups[fx]
  388.                                                                 break
  389.                                                 if not bx:
  390.                                                         adjust = gtk.Adjustment(
  391.                                                                 value=val,
  392.                                                                 lower=0, upper=255,
  393.                                                                 step_incr=1 )
  394.                                                         adjust.connect("value_changed", lambda a,lay,nam: setattr(lay,nam,int(a.value)), layer,name)
  395.                                                         scale = gtk.HScale( adjust ); scale.set_value_pos(gtk.POS_RIGHT)
  396.                                                         scale.set_digits(0)
  397.                                                         frame = gtk.Frame( name )
  398.                                                         frame.add( scale )
  399.                                                         col2.pack_start( frame )
  400.                                                 else:
  401.                                                         if fx=='split':
  402.                                                                 b = gtk.CheckButton( name )
  403.                                                                 b.set_active( bool(getattr(layer,name)) )
  404.                                                                 b.connect('toggled', lambda b,lay,nam: setattr(lay,nam,bool(b.get_active())), layer, name)
  405.                                                                 bx.pack_start( b )
  406.                                                         else:
  407.                                                                 upper = 255
  408.                                                                 lower = 0
  409.                                                                 step = 1
  410.                                                                 if name.startswith('sobel'):
  411.                                                                         upper = 31; lower = 1; step=2
  412.                                                                 adjust = gtk.Adjustment(
  413.                                                                         value=val,
  414.                                                                         lower=lower, upper=upper,
  415.                                                                         step_incr=step )
  416.                                                                 adjust.connect("value_changed", lambda a,lay,nam: setattr(lay,nam,int(a.value)), layer,name)
  417.                                                                 scale = gtk.HScale( adjust ); scale.set_value_pos(gtk.POS_RIGHT)
  418.                                                                 scale.set_digits(0)
  419.                                                                 row = gtk.HBox()
  420.                                                                 row.pack_start( gtk.Label( name.split(fx)[-1].replace('_',' ') ), expand=False )
  421.                                                                 row.pack_start( scale )
  422.                                                                 bx.pack_start( row )
  423.  
  424.                 win.show_all()
  425.  
  426.         def realize( self, da ):
  427.                 wid = da.window.xid
  428.                 os.environ['SDL_WINDOWID'] = str(wid)           # child fork respects environ
  429.                 self.subprocess = p = multiprocessing.Process(target=subprocess, args=(self.active,self.layers,self.rawimage))
  430.                 p.start()
  431.                 #p.join()
  432.                 time.sleep(1)
  433.                 print( 'trying to open sharedmemory')
  434.                 #self.shm = memory = posix_ipc.SharedMemory(SHARED_MEMORY)
  435.                 # MMap the shared memory
  436.                 #self.mapfile = mmap.mmap(memory.fd, memory.size, mmap.MAP_PRIVATE)
  437.                 #os.close(memory.fd)            # also valid
  438.                 #memory.close_fd()
  439.                 #print( 'sharedmem', self.mapfile)
  440.                 #self.semaphore = posix_ipc.Semaphore(SEMAPHORE_NAME)
  441.                 #glib.timeout_add( 300, self.check_shm )
  442.  
  443.         def check_shm( self ):
  444.                 self.semaphore.acquire()
  445.                 data = shm_read( self.mapfile )
  446.                 self.semaphore.release()
  447.                 #print len(data)
  448.                 #print self.rawimage[0]         # ctypes is slightly faster or slower than posix_ipc?
  449.                 return True
  450.  
  451. class Camera(object):
  452.         try:    ## opencv haar detect is multithreaded! ##
  453.                 DO_HAAR = True
  454.                 FaceCascade = cv.cvLoadHaarClassifierCascade('haarcascades/haarcascade_frontalface_alt.xml', cv.cvSize(1,1))
  455.                 EyesCascade = cv.cvLoadHaarClassifierCascade('haarcascades/haarcascade_eye.xml', cv.cvSize(1,1))
  456.         except:
  457.                 print( 'download opencv latest source code, and copy the haarcascades folder to here')
  458.                 DO_HAAR = False
  459.  
  460.         def exit(self):
  461.                 self.mapfile.close()
  462.                 # I could call memory.unlink() here but in order to demonstrate
  463.                 # unlinking at the module level I'll do it that way.
  464.                 posix_ipc.unlink_shared_memory( SHARED_MEMORY )
  465.                 print( 'subprocess clean exit')
  466.  
  467.         def __init__(self, layers, rawimage):
  468.                 self.layers = layers
  469.                 self.rawimage = rawimage
  470.                 self.shm = memory = posix_ipc.SharedMemory(SHARED_MEMORY, posix_ipc.O_CREAT, size=Size640x480_RGBA)
  471.                 self.mapfile = mmap.mmap(memory.fd, memory.size, mmap.ACCESS_WRITE)#, mmap.MAP_PRIVATE)
  472.                 memory.close_fd()
  473.                 print( 'sharedmemory created', self.mapfile)
  474.                 self.semaphore = posix_ipc.Semaphore(SEMAPHORE_NAME, posix_ipc.O_CREAT)
  475.  
  476.  
  477.                 pygame.display.init()
  478.                 SSBACKEND = pygame.transform.get_smoothscale_backend()
  479.                 if SSBACKEND == 'GENERIC':
  480.                         try: pygame.transform.set_smoothscale_backend( 'SSE' ); SSBACKEND = 'SSE'
  481.                         except: print( 'SSE backend not available')
  482.                 print( 'smooth scale backend', SSBACKEND)
  483.  
  484.  
  485.                 self.prevfaces = None
  486.                 self.active = True
  487.                 self.index = 0
  488.                 for arg in sys.argv:
  489.                         if arg.startswith('camera='): self.index = int(arg.split('=')[-1]); break
  490.                 self.camera_pointer = highgui.cvCreateCameraCapture(self.index)         # this is the old swig bindings ubuntu lucid works fine
  491.  
  492.                 # HIGHGUI ERROR: V4L: setting property #16 is not supported
  493.                 #highgui.cvSetCaptureProperty( self.camera_pointer, highgui.CV_CAP_PROP_CONVERT_RGB, True )
  494.                 ## default color space is BGR - linux ##
  495.                 self.resize_capture( 640, 480 )
  496.                 self.resize_output( 640, 480 )
  497.  
  498.                 if self.DO_HAAR:
  499.                         self.track_face = Trackable( self.FaceCascade )
  500.  
  501.         def resize_capture( self, x,y ):
  502.                 self.cwidth = x
  503.                 self.cheight = y
  504.                 highgui.cvSetCaptureProperty( self.camera_pointer, highgui.CV_CAP_PROP_FRAME_WIDTH, self.cwidth )
  505.                 highgui.cvSetCaptureProperty( self.camera_pointer, highgui.CV_CAP_PROP_FRAME_HEIGHT, self.cheight )
  506.                 highgui.cvSetCaptureProperty( self.camera_pointer, highgui.CV_CAP_PROP_FPS, 30 )
  507.  
  508.                 self._rgb8 = cv.cvCreateImage((self.cwidth,self.cheight), cv.IPL_DEPTH_8U, 3)
  509.                 self._rgb32 = cv.cvCreateImage((self.cwidth,self.cheight), cv.IPL_DEPTH_32F, 3)
  510.                 self._gray8 = cv.cvCreateImage((self.cwidth,self.cheight), cv.IPL_DEPTH_8U, 1)
  511.                 self._gray32 = cv.cvCreateImage((self.cwidth,self.cheight), cv.IPL_DEPTH_32F, 1)
  512.  
  513.                 self._R = cv.cvCreateImage((self.cwidth,self.cheight), cv.IPL_DEPTH_8U, 1)
  514.                 self._G = cv.cvCreateImage((self.cwidth,self.cheight), cv.IPL_DEPTH_8U, 1)
  515.                 self._B = cv.cvCreateImage((self.cwidth,self.cheight), cv.IPL_DEPTH_8U, 1)
  516.                 self._A = cv.cvCreateImage((self.cwidth,self.cheight), cv.IPL_DEPTH_8U, 1)
  517.  
  518.  
  519.         def resize_output( self, x, y ):
  520.                 self.owidth = x
  521.                 self.oheight = y
  522.                 pygame.display.set_mode((x,y), 0, 32 )          # size, flags, depth
  523.                 self.screen = pygame.display.get_surface()
  524.  
  525.         def loop(self):
  526.                 self.semaphore.release()
  527.                 ## BGR - linux
  528.                 _frame = highgui.cvQueryFrame(self.camera_pointer)              # grabFrame returns 1?
  529.                 if not _frame: print( 'lost connection to webcam?')
  530.  
  531.                 self.screen.fill( (0,0,0,0) )
  532.                 surf = self.screen.copy()
  533.                 surf.fill( (0,0,255) )
  534.                 surf.set_alpha(255)
  535.                 stencil = []
  536.  
  537.                 ## pre allocated ##
  538.                 _rgb8 = self._rgb8
  539.                 _rgb32 = self._rgb32
  540.                 _gray8 = self._gray8
  541.                 _gray32 = self._gray32
  542.  
  543.                 for layer in self.layers:
  544.                         if layer.active:
  545.                                 a = cv.cvCreateImage((self.cwidth,self.cheight), cv.IPL_DEPTH_8U, 3)
  546.                                 cv.cvCvtColor(_frame, a, layer.colorspace)
  547.                                 #print 'colorspaced converted'
  548.                                 ## FX
  549.                                 if layer.FXsplit:
  550.                                         _a = cv.cvCreateImage((self.cwidth,self.cheight), cv.IPL_DEPTH_8U, 4)
  551.                                         cv.cvCvtColor(a, _a, cv.CV_RGB2RGBA)
  552.                                         cv.cvSplit( _a, self._R, self._G, self._B, self._A )
  553.                                         if layer.split_red: a = self._R
  554.                                         elif layer.split_green: a = self._G
  555.                                         elif layer.split_blue: a = self._B
  556.  
  557.                                 if layer.FXblur:                        # blur before threshing
  558.                                         blur = layer.blur
  559.                                         if blur < 1: blur = 1
  560.                                         cv.cvSmooth( a, a, cv.CV_BLUR, blur )
  561.                                 if layer.FXsobel and layer.sobel_aperture % 2 and layer.sobel_aperture < 32:
  562.                                         if layer.sobel_xorder < layer.sobel_aperture and layer.sobel_yorder < layer.sobel_aperture:
  563.                                                 if a.nChannels == 1:
  564.                                                         cv.cvSobel( a, _gray32, layer.sobel_xorder, layer.sobel_yorder, layer.sobel_aperture )  #xorder, yorder, aperture
  565.                                                         cv.cvConvert( _gray32, a )#; cv.cvCvtColor(_sobel8, _sobel, cv.CV_GRAY2RGB)
  566.                                                 else:
  567.                                                         cv.cvSobel( a, _rgb32, layer.sobel_xorder, layer.sobel_yorder, layer.sobel_aperture )   #xorder, yorder, aperture
  568.                                                         cv.cvConvert( _rgb32, a )#; cv.cvCvtColor(_sobel8, _sobel, cv.CV_GRAY2RGB)
  569.                                 if layer.FXthresh:
  570.                                         cv.cvThreshold( a, a, layer.thresh_min, layer.thresh_max, cv.CV_THRESH_BINARY )
  571.                                 if layer.FXathresh:
  572.                                         blocksize = layer.athresh_block_size
  573.                                         if blocksize <= 2: blocksize = 3
  574.                                         if blocksize % 2 != 1: blocksize += 1
  575.                                         if a.nChannels == 1:
  576.                                                 cv.cvAdaptiveThreshold(a, a, 255, cv.CV_ADAPTIVE_THRESH_MEAN_C, cv.CV_THRESH_BINARY, blocksize )
  577.                                         else:
  578.                                                 cv.cvCvtColor(a, _gray8, cv.CV_RGB2GRAY)
  579.                                                 cv.cvAdaptiveThreshold(_gray8, _gray8, 255, cv.CV_ADAPTIVE_THRESH_MEAN_C, cv.CV_THRESH_BINARY, blocksize )
  580.                                                 cv.cvCvtColor(_gray8, a, cv.CV_GRAY2RGB)
  581.  
  582.                                 if a.nChannels == 1:
  583.                                                 cv.cvCvtColor(a, _rgb8, cv.CV_GRAY2RGB)
  584.                                                 a = _rgb8
  585.                                 ## pygame
  586.                                 b = pygame.image.frombuffer(a.imageData, (self.cwidth,self.cheight), 'RGB')
  587.                                 b.set_alpha( layer.alpha )
  588.                                 if layer.FXstencil: stencil.append( b )
  589.                                 surf.blit(b, (0,0))
  590.  
  591.                 self.screen.lock()
  592.                 array = pygame.surfarray.pixels_alpha(self.screen)
  593.                 if stencil:
  594.                         stencil = pygame.transform.average_surfaces( stencil )
  595.                         alpha = pygame.surfarray.pixels3d( stencil )
  596.                         array[:] = alpha[:,:,0]
  597.                         del alpha
  598.                 else: array[:] = 255                    # values higher than 256 are additive!
  599.                 del array
  600.                 self.screen.unlock()
  601.                 self.screen.blit( surf, (0,0) )
  602.                 #data = pygame.image.tostring(self.screen, 'RGBA')
  603.                 pygame.display.flip()
  604.                 #self.rawimage.value = data
  605.                 #self.semaphore.acquire()               # waiting for Blender to update to python 3.1.2 and support directly setting a RGBA buffer
  606.                 #shm_write( self.mapfile, data )
  607.                 #self.semaphore.release()
  608.  
  609.                 # this is an ugly hack #
  610.                 #tmp = pygame.transform.scale( self.screen, (320,240) )
  611.                 os.system('mv /tmp/ramdrive/_dump.png /tmp/ramdrive/dump.png')          # atomic
  612.                 pygame.image.save(self.screen, '/tmp/ramdrive/_dump.png')
  613.  
  614.                 return self.active
  615.  
  616.  
  617.  
  618. def subprocess( active, layers, rawimage ):
  619.         cam = Camera( layers, rawimage )
  620.         while active.value: cam.loop()
  621.         cam.exit()
  622.  
  623.  
  624. if __name__ == '__main__' and '--blender' not in sys.argv:
  625.         #CV_BGR2HLS
  626.         #CV_BGR2Luv
  627.         #CV_BGR2XYZ
  628.         _default_spaces = [
  629.                 (cv.CV_BGR2RGB,),
  630.                 (cv.CV_BGR2HSV,),
  631.                 (cv.CV_BGR2Lab,),
  632.                 (cv.CV_BGR2YCrCb,),
  633.         ]
  634.         active = sharedctypes.Value('i', 1, lock=False)
  635.         rawimage = sharedctypes.Array( ctypes.c_char, Size640x480_RGBA, lock=True )
  636.         layers = sharedctypes.Array( LayerConfig, _default_spaces, lock=True )
  637.         for layer in layers:
  638.                 layer.alpha = 32
  639.                 layer.thresh_min = 32
  640.                 layer.thresh_max = 200
  641.                 layer.blur = 2
  642.                 layer.athresh_block_size = 3
  643.                 layer.sobel_xorder = 1
  644.                 layer.sobel_yorder = 1
  645.                 layer.sobel_aperture = 5
  646.         layers[0].active = 1
  647.         layers[0].alpha = 128
  648.  
  649.         gui = UI( active, layers, rawimage )
  650.         gtk.main()
  651.         gui.active.value = 0
  652.         print( 'waiting for child to exit')
  653.         time.sleep(1)
  654.         gui.subprocess.join()
  655.         print( 'main process exit')
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top