From 285923e83e6c1c9ff930e2f033c5ca853dc7a6f0 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 20 Oct 2010 20:34:18 +0000 Subject: [PATCH] WebcamVideoOpenCV --- panda/src/vision/Sources.pp | 4 + panda/src/vision/config_vision.cxx | 5 + panda/src/vision/openCVTexture.cxx | 2 +- panda/src/vision/vision_composite1.cxx | 2 + panda/src/vision/webcamVideo.cxx | 5 + panda/src/vision/webcamVideoCursorOpenCV.cxx | 177 +++++++++++++++++++ panda/src/vision/webcamVideoCursorOpenCV.h | 64 +++++++ panda/src/vision/webcamVideoOpenCV.cxx | 70 ++++++++ panda/src/vision/webcamVideoOpenCV.h | 64 +++++++ 9 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 panda/src/vision/webcamVideoCursorOpenCV.cxx create mode 100644 panda/src/vision/webcamVideoCursorOpenCV.h create mode 100644 panda/src/vision/webcamVideoOpenCV.cxx create mode 100644 panda/src/vision/webcamVideoOpenCV.h diff --git a/panda/src/vision/Sources.pp b/panda/src/vision/Sources.pp index 45f683eea6..5eadfc05aa 100644 --- a/panda/src/vision/Sources.pp +++ b/panda/src/vision/Sources.pp @@ -17,6 +17,7 @@ config_vision.h \ openCVTexture.I openCVTexture.h \ webcamVideo.h webcamVideo.I \ + webcamVideoCursorOpenCV.h webcamVideoOpenCV.h \ webcamVideoCursorV4L.h webcamVideoV4L.h #define INCLUDED_SOURCES \ @@ -25,6 +26,8 @@ openCVTexture.cxx \ webcamVideo.cxx \ webcamVideoDS.cxx \ + webcamVideoCursorOpenCV.cxx \ + webcamVideoOpenCV.cxx \ webcamVideoCursorV4L.cxx \ webcamVideoV4L.cxx @@ -32,6 +35,7 @@ arToolKit.I arToolKit.h \ openCVTexture.I openCVTexture.h \ webcamVideo.h webcamVideo.I \ + webcamVideoCursorOpenCV.h webcamVideoOpenCV.h \ webcamVideoCursorV4L.h webcamVideoV4L.h #define IGATESCAN all diff --git a/panda/src/vision/config_vision.cxx b/panda/src/vision/config_vision.cxx index dd0978e0fb..77a51bb28e 100644 --- a/panda/src/vision/config_vision.cxx +++ b/panda/src/vision/config_vision.cxx @@ -15,6 +15,8 @@ #include "config_vision.h" #include "openCVTexture.h" #include "webcamVideo.h" +#include "webcamVideoCursorOpenCV.h" +#include "webcamVideoOpenCV.h" #include "webcamVideoCursorV4L.h" #include "webcamVideoV4L.h" @@ -52,6 +54,9 @@ init_libvision() { #endif #ifdef HAVE_OPENCV + WebcamVideoCursorOpenCV::init_type(); + WebcamVideoOpenCV::init_type(); + OpenCVTexture::init_type(); OpenCVTexture::register_with_read_factory(); diff --git a/panda/src/vision/openCVTexture.cxx b/panda/src/vision/openCVTexture.cxx index d301021383..c448380021 100644 --- a/panda/src/vision/openCVTexture.cxx +++ b/panda/src/vision/openCVTexture.cxx @@ -617,7 +617,7 @@ get_frame_data(int frame, y_pitch = -y_pitch; } - return (const unsigned char *)image->imageData; + return true; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/vision/vision_composite1.cxx b/panda/src/vision/vision_composite1.cxx index abbfe49d6b..9a7d2b12fc 100644 --- a/panda/src/vision/vision_composite1.cxx +++ b/panda/src/vision/vision_composite1.cxx @@ -2,7 +2,9 @@ #include "config_vision.cxx" #include "openCVTexture.cxx" #include "webcamVideo.cxx" +#include "webcamVideoCursorOpenCV.cxx" #include "webcamVideoCursorV4L.cxx" #include "webcamVideoDS.cxx" +#include "webcamVideoOpenCV.cxx" #include "webcamVideoV4L.cxx" diff --git a/panda/src/vision/webcamVideo.cxx b/panda/src/vision/webcamVideo.cxx index fe4d113515..a0bafd6f34 100644 --- a/panda/src/vision/webcamVideo.cxx +++ b/panda/src/vision/webcamVideo.cxx @@ -59,6 +59,11 @@ find_all_webcams() { extern void find_all_webcams_v4l(); find_all_webcams_v4l(); #endif + +#ifdef HAVE_OPENCV + extern void find_all_webcams_opencv(); + find_all_webcams_opencv(); +#endif } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/vision/webcamVideoCursorOpenCV.cxx b/panda/src/vision/webcamVideoCursorOpenCV.cxx new file mode 100644 index 0000000000..eca17e604e --- /dev/null +++ b/panda/src/vision/webcamVideoCursorOpenCV.cxx @@ -0,0 +1,177 @@ +// Filename: webcamVideoCursorOpenCV.cxx +// Created by: drose (20Oct10) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "webcamVideoOpenCV.h" + +#ifdef HAVE_OPENCV + +#include "pStatTimer.h" + +TypeHandle WebcamVideoCursorOpenCV::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoCursorOpenCV::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +WebcamVideoCursorOpenCV:: +WebcamVideoCursorOpenCV(WebcamVideoOpenCV *src) : MovieVideoCursor(src) { + _size_x = src->_size_x; + _size_y = src->_size_y; + _num_components = 3; + _length = 1.0E10; + _can_seek = false; + _can_seek_fast = false; + _aborted = false; + _last_start = -1.0; + _next_start = 0.0; + _streaming = true; + _ready = false; + + _capture = cvCaptureFromCAM(src->_camera_index); + if (_capture != NULL) { + _size_x = (int)cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_WIDTH); + _size_y = (int)cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_HEIGHT); + _ready = true; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoCursorOpenCV::Destructor +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +WebcamVideoCursorOpenCV:: +~WebcamVideoCursorOpenCV() { + if (_capture != NULL) { + cvReleaseCapture(&_capture); + _capture = NULL; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoCursorOpenCV::fetch_into_buffer +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void WebcamVideoCursorOpenCV:: +fetch_into_buffer(double time, unsigned char *block, bool bgra) { + if (!_ready) { + return; + } + + unsigned char *dest = block; + int num_components = bgra ? 4 : 3; + ssize_t dest_x_pitch = num_components; // Assume component_width == 1 + ssize_t dest_y_pitch = _size_x * dest_x_pitch; + + const unsigned char *r, *g, *b; + ssize_t x_pitch, y_pitch; + if (get_frame_data(r, g, b, x_pitch, y_pitch)) { + if (num_components == 3 && x_pitch == 3) { + // The easy case--copy the whole thing in, row by row. + ssize_t copy_bytes = _size_x * dest_x_pitch; + nassertv(copy_bytes <= dest_y_pitch && copy_bytes <= abs(y_pitch)); + + for (int y = 0; y < _size_y; ++y) { + memcpy(dest, r, copy_bytes); + dest += dest_y_pitch; + r += y_pitch; + } + + } else { + // The harder case--interleave in the color channels, pixel by + // pixel. + + for (int y = 0; y < _size_y; ++y) { + ssize_t dx = 0; + ssize_t sx = 0; + for (int x = 0; x < _size_x; ++x) { + dest[dx] = r[sx]; + dest[dx + 1] = g[sx]; + dest[dx + 2] = b[sx]; + dx += dest_x_pitch; + sx += x_pitch; + } + dest += dest_y_pitch; + r += y_pitch; + g += y_pitch; + b += y_pitch; + } + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoCursorOpenCV::get_frame_data +// Access: Private +// Description: Gets the data needed to traverse through the +// decompressed buffer. Returns true on success, false +// on failure. +// +// In the case of a success indication (true return +// value), the three pointers r, g, b are loaded with +// the addresses of the three components of the +// bottom-left pixel of the image. (They will be +// adjacent in memory in the case of an interleaved +// image, and separated in the case of a +// separate-channel image.) The x_pitch value is filled +// with the amount to add to each pointer to advance to +// the pixel to the right; and the y_pitch value is +// filled with the amount to add to each pointer to +// advance to the pixel above. Note that these values +// may be negative (particularly in the case of a +// top-down image). +//////////////////////////////////////////////////////////////////// +bool WebcamVideoCursorOpenCV:: +get_frame_data(const unsigned char *&r, + const unsigned char *&g, + const unsigned char *&b, + ssize_t &x_pitch, ssize_t &y_pitch) { + nassertr(ready(), false); + + IplImage *image = cvQueryFrame(_capture); + if (image == NULL) { + return false; + } + + r = (const unsigned char *)image->imageData; + g = r + 1; + b = g + 1; + x_pitch = 3; + y_pitch = image->widthStep; + + if (image->dataOrder == 1) { + // Separate channel images. That means a block of r, followed by + // a block of g, followed by a block of b. + x_pitch = 1; + g = r + image->height * y_pitch; + b = g + image->height * y_pitch; + } + + if (image->origin == 0) { + // The image data starts with the top row and ends with the bottom + // row--the opposite of Texture::_ram_data's storage convention. + // Therefore, we must increment the initial pointers to the last + // row, and count backwards. + r += (image->height - 1) * y_pitch; + g += (image->height - 1) * y_pitch; + b += (image->height - 1) * y_pitch; + y_pitch = -y_pitch; + } + + return true; +} + +#endif diff --git a/panda/src/vision/webcamVideoCursorOpenCV.h b/panda/src/vision/webcamVideoCursorOpenCV.h new file mode 100644 index 0000000000..538d02deca --- /dev/null +++ b/panda/src/vision/webcamVideoCursorOpenCV.h @@ -0,0 +1,64 @@ +// Filename: webcamVideoCursorOpenCV.h +// Created by: drose (20Oct10) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef WEBCAMVIDEOCURSOROPENCV_H +#define WEBCAMVIDEOCURSOROPENCV_H + +#include "pandabase.h" + +#ifdef HAVE_OPENCV + +#include "webcamVideo.h" + +class WebcamVideoOpenCV; + +//////////////////////////////////////////////////////////////////// +// Class : WebcamVideoCursorOpenCV +// Description : The Video4Linux implementation of webcams. +//////////////////////////////////////////////////////////////////// +class WebcamVideoCursorOpenCV : public MovieVideoCursor { +public: + WebcamVideoCursorOpenCV(WebcamVideoOpenCV *src); + virtual ~WebcamVideoCursorOpenCV(); + virtual void fetch_into_buffer(double time, unsigned char *block, bool rgba); + +private: + bool get_frame_data(const unsigned char *&r, + const unsigned char *&g, + const unsigned char *&b, + ssize_t &x_pitch, ssize_t &y_pitch); + + CvCapture *_capture; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + MovieVideoCursor::init_type(); + register_type(_type_handle, "WebcamVideoCursorOpenCV", + MovieVideoCursor::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#endif // HAVE_OPENCV + +#endif diff --git a/panda/src/vision/webcamVideoOpenCV.cxx b/panda/src/vision/webcamVideoOpenCV.cxx new file mode 100644 index 0000000000..ae1dfc3f03 --- /dev/null +++ b/panda/src/vision/webcamVideoOpenCV.cxx @@ -0,0 +1,70 @@ +// Filename: webcamVideoOpenCV.cxx +// Created by: drose (20Oct10) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "webcamVideoOpenCV.h" + +#ifdef HAVE_OPENCV + +#include "webcamVideoCursorOpenCV.h" +#include "configVariableInt.h" + +TypeHandle WebcamVideoOpenCV::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: find_all_webcams_opencv +// Access: Public, Static +// Description: Finds all OpenCV webcams and adds them to the global +// list _all_webcams. +//////////////////////////////////////////////////////////////////// +void +find_all_webcams_opencv() { + // OpenCV doesn't really provide a way to enumerate cameras. We ask + // the user to do this via a config variable. + static ConfigVariableInt wemcam_opencv_camera_index + ("webcam-opencv-camera-index", "0", + PRC_DESC("Specify the space-separated list of integer camera index " + "numbers that are assumed to be available via OpenCV to the " + "WebcamVideo interface. The default camera index is 0. " + "Specify empty string if there are no available cameras.")); + for (int i = 0; i < wemcam_opencv_camera_index.get_num_words(); ++i) { + PT(WebcamVideo) wc = new WebcamVideoOpenCV(wemcam_opencv_camera_index[i]); + WebcamVideoOpenCV::_all_webcams.push_back(wc); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoOpenCV::Constructor +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +WebcamVideoOpenCV:: +WebcamVideoOpenCV(int camera_index) : + _camera_index(camera_index) +{ + ostringstream strm; + strm << "OpenCV webcam " << _camera_index; + set_name(strm.str()); +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoOpenCV::open +// Access: Published, Virtual +// Description: Open this video, returning a MovieVideoCursor. +//////////////////////////////////////////////////////////////////// +PT(MovieVideoCursor) WebcamVideoOpenCV:: +open() { + return new WebcamVideoCursorOpenCV(this); +} + +#endif diff --git a/panda/src/vision/webcamVideoOpenCV.h b/panda/src/vision/webcamVideoOpenCV.h new file mode 100644 index 0000000000..d22b6f9cb2 --- /dev/null +++ b/panda/src/vision/webcamVideoOpenCV.h @@ -0,0 +1,64 @@ +// Filename: webcamVideoOpenCV.h +// Created by: drose (20Oct10) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef WEBCAMVIDEOOPENCV_H +#define WEBCAMVIDEOOPENCV_H + +#include "pandabase.h" + +#ifdef HAVE_OPENCV + +#include "webcamVideo.h" + +class WebcamVideoCursorOpenCV; + +//////////////////////////////////////////////////////////////////// +// Class : WebcamVideoOpenCV +// Description : The OpenCV implementation of webcams. Probably won't +// be needed once we have a native webcam implementation +// for each Panda3D-supported platform. (So far, we're +// 2 for 3.) +//////////////////////////////////////////////////////////////////// +class WebcamVideoOpenCV : public WebcamVideo { +private: + WebcamVideoOpenCV(int camera_index); + virtual PT(MovieVideoCursor) open(); + +private: + int _camera_index; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + WebcamVideo::init_type(); + register_type(_type_handle, "WebcamVideoOpenCV", + WebcamVideo::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; + + friend class WebcamVideoCursorOpenCV; + friend void find_all_webcams_opencv(); +}; + +#endif // HAVE_OPENCV + +#endif