update Camera core class to use EventDispatcher

+ add on_load and on_frame event
+ uniform the camera selection to a index, starting from 0
This commit is contained in:
Mathieu Virbel 2011-01-12 02:24:31 +01:00
parent 23de1b3ffb
commit 1697726fa0
5 changed files with 75 additions and 31 deletions

25
examples/kv/app_camera.kv Normal file
View File

@ -0,0 +1,25 @@
Camera:
canvas:
Color:
rgb: (1, 1, 1)
Rectangle:
texture: self.texture
size: (320, 240)
Color:
rgb: (.5, 0, 1)
Rectangle:
texture: self.texture
pos: (320, 0)
size: (320, 240)
Color:
rgb: (0, 1, 0)
Rectangle:
texture: self.texture
pos: (320, 240)
size: (320, 240)
Color:
rgb: (1, 0, 0)
Rectangle:
texture: self.texture
pos: (0, 240)
size: (320, 240)

View File

@ -8,16 +8,19 @@ Core class for acquiring the camera, and convert the input to a
__all__ = ('CameraBase', 'Camera')
from kivy.event import EventDispatcher
from kivy.logger import Logger
from kivy.core import core_select_lib
class CameraBase(object):
class CameraBase(EventDispatcher):
'''Abstract Camera Widget class.
Concrete camera classes must implement initialization and
frame capturing to buffer that can be uploaded to gpu.
:Parameters:
`index`: int
Source index of the camera.
`size` : tuple (int, int)
Size at which the image is drawn. If no size is specified,
it defaults to resolution of the camera image.
@ -26,23 +29,32 @@ class CameraBase(object):
Used in the gstreamer pipeline by forcing the appsink caps
to this resolution. If the camera doesnt support the resolution
a negotiation error might be thrown.
:Events:
`on_load`
Fired when the camera is loaded, and the texture became available
`on_frame`
Fired each time the camera texture is updated
'''
def __init__(self, **kwargs):
kwargs.setdefault('stopped', False)
kwargs.setdefault('resolution', (640, 480))
kwargs.setdefault('video_src', 0)
kwargs.setdefault('index', 0)
self.stopped = kwargs.get('stopped')
self._resolution = kwargs.get('resolution')
self._video_src = kwargs.get('video_src')
self._index = kwargs.get('index')
self._buffer = None
self._format = 'rgb'
self._texture = None
self.capture_device = None
kwargs.setdefault('size', self._resolution)
super(CameraBase, self).__init__(**kwargs)
super(CameraBase, self).__init__()
self.register_event_type('on_load')
self.register_event_type('on_frame')
self.init_camera()
@ -58,14 +70,16 @@ class CameraBase(object):
lambda self, x: self._set_resolution(x),
doc='Resolution of camera capture (width, height)')
def _set_video_src(self, src):
self._video_src = src
def _set_index(self, x):
if x == self._index:
return
self._index = x
self.init_camera()
def _get_video_src(self):
return self._video_src
video_src = property(lambda self: self._get_video_src(),
lambda self, x: self._set_video_src(x),
doc='Source of the camera')
def _get_index(self):
return self._x
index = property(lambda self: self._get_index(),
lambda self, x: self._set_index(x),
doc='Source index of the camera')
def _get_texture(self):
return self._texture
@ -95,6 +109,13 @@ class CameraBase(object):
return
self._texture.blit_buffer(self._buffer, fmt=self._format)
self._buffer = None
self.dispatch('on_frame')
def on_frame(self):
pass
def on_load(self):
pass
# Load the appropriate provider
Camera = core_select_lib('camera', (

View File

@ -4,7 +4,8 @@ GStreamer Camera: Implement CameraBase with GStreamer
__all__ = ('CameraGStreamer', )
import kivy
from kivy.graphics.texture import Texture
from . import CameraBase
try:
@ -33,11 +34,11 @@ class CameraGStreamer(CameraBase):
'''
def __init__(self, **kwargs):
kwargs.setdefault('video_src', 'v4l2src')
self._pipeline = None
self._camerasink = None
self._decodebin = None
self._texturesize = None
self._video_src = kwargs.get('video_src', 'v4l2src')
super(CameraGStreamer, self).__init__(**kwargs)
def init_camera(self):
@ -46,8 +47,16 @@ class CameraGStreamer(CameraBase):
if self._pipeline:
self._pipeline = None
video_src = self._video_src
if video_src == 'v4l2src':
video_src += ' device=/dev/video%d' % self._index
elif video_src == 'dc1394src':
video_src += ' camera-number=%d' % self._index
print video_src
GL_CAPS = 'video/x-raw-rgb,red_mask=(int)0xff0000,green_mask=(int)0x00ff00,blue_mask=(int)0x0000ff'
self._pipeline = gst.parse_launch('%s ! decodebin name=decoder ! ffmpegcolorspace ! appsink name=camerasink emit-signals=True caps=%s' % (self.video_src, GL_CAPS) )
self._pipeline = gst.parse_launch('%s ! decodebin name=decoder ! ffmpegcolorspace ! appsink name=camerasink emit-signals=True caps=%s' % (video_src, GL_CAPS) )
self._camerasink = self._pipeline.get_by_name('camerasink')
self._camerasink.connect('new-buffer', self._gst_new_buffer)
self._decodebin = self._pipeline.get_by_name('decoder')
@ -81,6 +90,7 @@ class CameraGStreamer(CameraBase):
return
self._copy_to_gpu()
if self._texture is None and self._texturesize is not None:
self._texture = kivy.Texture.create(
self._texture = Texture.create(
size=self._texturesize, fmt='rgb')
self._texture.flip_vertical()
self.dispatch('on_load')

View File

@ -20,23 +20,15 @@ except:
class CameraOpenCV(CameraBase):
'''Implementation of CameraBase using OpenCV
:Parameters:
`video_src` : int, default is 0
Index of OpenCV camera to use (0 mean default camera)
'''
def __init__(self, **kwargs):
# override the default source of video
kwargs.setdefault('video_src', 0)
self._device = None
super(CameraOpenCV, self).__init__(**kwargs)
def init_camera(self):
# create the device
self._device = hg.cvCreateCameraCapture(self.video_src)
self._device = hg.cvCreateCameraCapture(self._index)
try:
# try first to set resolution
@ -68,6 +60,7 @@ class CameraOpenCV(CameraBase):
# create texture !
self._texture = Texture.create(*self._resolution)
self._texture.flip_vertical()
self.dispatch('on_load')
if not self.stopped:
self.start()

View File

@ -18,22 +18,16 @@ except:
class CameraVideoCapture(CameraBase):
'''Implementation of CameraBase using VideoCapture
:Parameters:
`video_src` : int, default is 0
Index of VideoCapture camera to use (0 mean default camera)
'''
def __init__(self, **kwargs):
# override the default source of video
kwargs.setdefault('video_src', 0)
self._device = None
super(CameraVideoCapture, self).__init__(**kwargs)
self._format = 'rgb'
def init_camera(self):
# create the device
self._device = Device(devnum=self.video_src, showVideoWindow=0)
self._device = Device(devnum=self._index, showVideoWindow=0)
# set resolution
try:
self._device.setResolution(self.resolution[0], self.resolution[1])
@ -48,6 +42,7 @@ class CameraVideoCapture(CameraBase):
# and create texture
self._texture = kivy.Texture.create(
size=self.size, fmt='bgr')
self.dispatch('on_load')
# update buffer
self._buffer = data