diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/camera_sensor/camera_sensor.py | 141 | ||||
-rw-r--r-- | plugins/camera_sensor/tacamera.py | 40 | ||||
-rw-r--r-- | plugins/turtle_blocks_extras/turtle_blocks_extras.py | 28 |
3 files changed, 113 insertions, 96 deletions
diff --git a/plugins/camera_sensor/camera_sensor.py b/plugins/camera_sensor/camera_sensor.py index 5bd21ee..bb9698f 100644 --- a/plugins/camera_sensor/camera_sensor.py +++ b/plugins/camera_sensor/camera_sensor.py @@ -19,6 +19,8 @@ import gst import gtk from fcntl import ioctl import os +from time import time + from gettext import gettext as _ from plugins.camera_sensor.tacamera import Camera @@ -37,22 +39,18 @@ from TurtleArt.taconstants import MEDIA_SHAPES, NO_IMPORT, SKIN_PATHS, \ class Camera_sensor(Plugin): def __init__(self, parent): + ''' Make sure there is a camera device ''' self._parent = parent self._status = False - self._camera = None + self.function = None + self.camera = None v4l2src = gst.element_factory_make('v4l2src') if v4l2src.props.device_name is not None: - - if self._parent.running_sugar: - self._imagepath = get_path(self._parent.activity, - 'data/turtlepic.png') - else: - self._imagepath = '/tmp/turtlepic.png' - self._status = True def setup(self): + ''' Set up the palettes ''' palette = make_palette('sensor', colors=["#FF6060", "#A06060"], help_string=_('Palette of sensor blocks')) @@ -134,13 +132,18 @@ is pushed to the stack'), ''' Initialize the camera if there is an camera block in use ''' if len(self._parent.block_list.get_similar_blocks('block', ['camera', 'read_camera', 'luminance'])) > 0: - if self._status and self._camera is None: - self._camera = Camera(self._imagepath) + if self._status and self.camera is None: + self.camera = Camera() def stop(self): ''' This gets called by the stop button ''' - if self._status and self._camera is not None: - self._camera.stop_camera_input() + if self._status and self.camera is not None: + self.camera.stop_camera_input() + + def clear(self): + ''' This gets called by the clean button and erase button ''' + if self._status and self.camera is not None: + self.camera.stop_camera_input() def _status_report(self): debug_output('Reporting camera status: %s' % (str(self._status)), @@ -150,19 +153,15 @@ is pushed to the stack'), # Block primitives used in talogo def prim_take_picture(self): - if self._status: - ''' method called by media block ''' - self._camera.save_camera_input_to_file() - self._camera.stop_camera_input() - self._parent.lc.filepath = self._imagepath - else: - self._parent.lc.filepath = os.path.join( - self._parent.path, 'samples', 'images', 'me.jpg') + ''' method called by media block ''' + self._get_pixbuf_from_camera() + self._parent.lc.pixbuf = self.camera.pixbuf def prim_read_camera(self, luminance_only=False): """ Read average pixel from camera and push b, g, r to the stack """ + self.luminance_only = luminance_only if not self._status: - if luminance_only: + if self.luminance_only: return -1 else: self._parent.lc.heap.append(-1) @@ -170,52 +169,64 @@ is pushed to the stack'), self._parent.lc.heap.append(-1) return - pixbuf = None array = None + try: + self._video_capture_device = open('/dev/video0', 'rw') + except: + self._video_capture_device = None + debug_output('video capture device not available', + self._parent.running_sugar) + self._set_autogain(0) # disable AUTOGAIN + self._get_pixbuf_from_camera() + self.calc_luminance() + if self.luminance_only: + self._parent.lc.update_label_value('luminance', self.luminance) + return self.luminance + else: + self._parent.lc.heap.append(self.b) + self._parent.lc.heap.append(self.g) + self._parent.lc.heap.append(self.r) - if self._status: - try: - self._video_capture_device = open('/dev/video0', 'rw') - except: - self._video_capture_device = None - debug_output('video capture device not available', - self._parent.running_sugar) - - self._set_autogain(0) # disable AUTOGAIN - - pixbuf = self._get_pixbuf_from_camera() - try: - array = pixbuf.get_pixels() - except: - array = None - - self._set_autogain(1) # reenable AUTOGAIN + def calc_luminance(self): + array = self.camera.pixbuf.get_pixels() + width = self.camera.pixbuf.get_width() + height = self.camera.pixbuf.get_height() + self._set_autogain(1) # reenable AUTOGAIN if array is not None: - length = len(array) / 3 - r, g, b, i = 0, 0, 0, 0 - for j in range(length): - r += ord(array[i]) - i += 1 - g += ord(array[i]) - i += 1 - b += ord(array[i]) - i += 1 - if luminance_only: - lum = int((r * 0.3 + g * 0.6 + b * 0.1) / length) - self._parent.lc.update_label_value('luminance', lum) - return lum + length = int(len(array) / 3) + if length != width * height: + debug_output('array length != width x height (%d != %dx%d)' % \ + (length, width, height), + self._parent.running_sugar) + + # Average the 100 pixels in the center of the screen + r, g, b = 0, 0, 0 + row_offset = int((height / 2 - 5) * width * 3) + column_offset = int(width / 2 - 5) * 3 + for y in range(10): + i = row_offset + column_offset + for x in range(10): + r += ord(array[i]) + i += 1 + g += ord(array[i]) + i += 1 + b += ord(array[i]) + i += 1 + row_offset += width * 3 + if self.luminance_only: + self.luminance = int((r * 0.3 + g * 0.6 + b * 0.1) / 100) else: - self._parent.lc.heap.append(int((b / length))) - self._parent.lc.heap.append(int((g / length))) - self._parent.lc.heap.append(int((r / length))) + self.r = int(r / 100) + self.g = int(g / 100) + self.b = int(b / 100) else: - if luminance_only: - return -1 + if self.luminance_only: + self.luminance = -1 else: - self._parent.lc.heap.append(-1) - self._parent.lc.heap.append(-1) - self._parent.lc.heap.append(-1) + self.r = -1 + self.g = -1 + self.b = -1 def _set_autogain(self, state): ''' 0 is off; 1 is on ''' @@ -232,10 +243,6 @@ is pushed to the stack'), def _get_pixbuf_from_camera(self): ''' Regardless of how we get it, we want to return a pixbuf ''' - if self._video_capture_device is not None: - self._video_capture_device.close() - self._camera.save_camera_input_to_file() - self._camera.stop_camera_input() - return gtk.gdk.pixbuf_new_from_file(self._imagepath) - else: - return None + self._parent.lc.pixbuf = None + if self._status: + self.camera.start_camera_input() diff --git a/plugins/camera_sensor/tacamera.py b/plugins/camera_sensor/tacamera.py index 15824a1..5a6f506 100644 --- a/plugins/camera_sensor/tacamera.py +++ b/plugins/camera_sensor/tacamera.py @@ -21,33 +21,41 @@ #THE SOFTWARE. import gst, time +import gobject + +from TurtleArt.tautils import debug_output + +GST_PIPE = ['v4l2src', 'ffmpegcolorspace', 'gdkpixbufsink'] -GST_PIPE = ['v4l2src', 'ffmpegcolorspace', 'pngenc'] -# GST_PIPE = ['v4l2src', 'ffmpegcolorspace', 'gdkpixbufsink'] class Camera(): - """ A class for representing the video camera """ + ''' Sets up a pipe from the camera to a pixbuf and emits a signal + when the image is ready. ''' - def __init__(self, imagepath): - # self.imagepath = imagepath - GST_PIPE.append('filesink location=%s' % imagepath) - self.pipe = gst.parse_launch('!'.join(GST_PIPE)) - self.bus = self.pipe.get_bus() - # self.bus.add_signal_watch() - # self.bus.connect('message', self._on_message) + def __init__(self): + ''' Prepare camera pipeline to pixbuf and signal watch ''' + self.pipe = gst.parse_launch('!'.join(GST_PIPE)) + self.bus = self.pipe.get_bus() + self.bus.add_signal_watch() + self.bus.connect('message', self._on_message) def _on_message(self, bus, message): ''' We get a message if a pixbuf is available ''' if message.structure is not None: - print message.structure.get_name() + # debug_output(message.structure.get_name(), True) if message.structure.get_name() == 'pixbuf': - message.structure['pixbuf'].save(self.imagepath, 'png') + self.pixbuf = message.structure['pixbuf'] + self.image_ready = True - def save_camera_input_to_file(self): - """ Grab a frame from the camera """ + def start_camera_input(self): + ''' Start grabbing ''' + self.pixbuf = None + self.image_ready = False self.pipe.set_state(gst.STATE_PLAYING) - self.bus.poll(gst.MESSAGE_EOS, -1) + while not self.image_ready: + self.bus.poll(gst.MESSAGE_ANY, -1) + # self.stop_camera_input() def stop_camera_input(self): + ''' Stop grabbing ''' self.pipe.set_state(gst.STATE_NULL) - diff --git a/plugins/turtle_blocks_extras/turtle_blocks_extras.py b/plugins/turtle_blocks_extras/turtle_blocks_extras.py index e5473e6..1406407 100644 --- a/plugins/turtle_blocks_extras/turtle_blocks_extras.py +++ b/plugins/turtle_blocks_extras/turtle_blocks_extras.py @@ -287,16 +287,16 @@ amplitude, and duration (in seconds)')) colors=["#FF6060", "#A06060"], help_string=_('Palette of sensor blocks')) - primitive_dictionary['mouseclick'] = self._prim_mouse_click - palette.add_block('mouseclick', + primitive_dictionary['mousebutton'] = self._prim_mouse_button + palette.add_block('mousebutton', style='box-style', - label=_('click'), - prim_name='mouseclick', + label=_('button down'), + prim_name='mousebutton', value_block=True, - help_string=_('returns 1 if mouse button has been \ -clicked')) - self.tw.lc.def_prim('mouseclick', 0, - lambda self: primitive_dictionary['mouseclick']()) + help_string=_('returns 1 if mouse button is \ +pressed')) + self.tw.lc.def_prim('mousebutton', 0, + lambda self: primitive_dictionary['mousebutton']()) palette.add_block('mousex', style='box-style', @@ -1156,10 +1156,9 @@ bullets')) csd.write("\n</CsoundSynthesizer>") csd.close() - def _prim_mouse_click(self): - """ Return 1 if mouse button has been pressed """ + def _prim_mouse_button(self): + """ Return 1 if mouse button is pressed """ if self.tw.mouse_flag == 1: - self.tw.mouse_flag = 0 return 1 else: return 0 @@ -1186,6 +1185,7 @@ bullets')) pass elif string[0:6] in ['media_', 'descr_', 'audio_', 'video_']: self.tw.lc.filepath = None + self.tw.lc.pixbuf = None # Camera writes directly to pixbuf self.tw.lc.dsobject = None if string[6:].lower() in media_blocks_dictionary: media_blocks_dictionary[string[6:].lower()]() @@ -1200,7 +1200,9 @@ bullets')) string[6:]), self.tw.running_sugar) if self.tw.lc.dsobject is not None: self.tw.lc.filepath = self.tw.lc.dsobject.file_path - if self.tw.lc.filepath == None: + if self.tw.lc.pixbuf is not None: + self.tw.lc.insert_image(center=center, pixbuf=True) + elif self.tw.lc.filepath is None: if self.tw.lc.dsobject is not None: self.tw.showlabel('nojournal', self.tw.lc.dsobject.metadata['title']) @@ -1209,7 +1211,7 @@ bullets')) debug_output("Couldn't open %s" % (string[6:]), self.tw.running_sugar) elif string[0:6] == 'media_': - self.tw.lc.insert_image(center) + self.tw.lc.insert_image(center=center) elif string[0:6] == 'descr_': mimetype = None if self.tw.lc.dsobject is not None and \ |