Revision: 7964
          http://playerstage.svn.sourceforge.net/playerstage/?rev=7964&view=rev
Author:   gbiggs
Date:     2009-07-10 00:15:06 +0000 (Fri, 10 Jul 2009)

Log Message:
-----------
Applied patch #2818239

Modified Paths:
--------------
    code/player/trunk/server/drivers/camera/CMakeLists.txt

Added Paths:
-----------
    code/player/trunk/server/drivers/camera/videocanny/
    code/player/trunk/server/drivers/camera/videocanny/CMakeLists.txt
    code/player/trunk/server/drivers/camera/videocanny/videocanny.cc

Modified: code/player/trunk/server/drivers/camera/CMakeLists.txt
===================================================================
--- code/player/trunk/server/drivers/camera/CMakeLists.txt      2009-07-09 
14:43:15 UTC (rev 7963)
+++ code/player/trunk/server/drivers/camera/CMakeLists.txt      2009-07-10 
00:15:06 UTC (rev 7964)
@@ -8,3 +8,4 @@
 ADD_SUBDIRECTORY (uvc)
 ADD_SUBDIRECTORY (yarp)
 ADD_SUBDIRECTORY (unicap)
+ADD_SUBDIRECTORY (videocanny)

Added: code/player/trunk/server/drivers/camera/videocanny/CMakeLists.txt
===================================================================
--- code/player/trunk/server/drivers/camera/videocanny/CMakeLists.txt           
                (rev 0)
+++ code/player/trunk/server/drivers/camera/videocanny/CMakeLists.txt   
2009-07-10 00:15:06 UTC (rev 7964)
@@ -0,0 +1,7 @@
+PLAYERDRIVER_OPTION (videocanny build_videocanny ON)
+PLAYERDRIVER_REQUIRE_PKG (videocanny build_videocanny opencv
+    videocanny_includeDirs videocanny_libDirs videocanny_linkLibs 
videocanny_linkFlags videocanny_cFlags)
+PLAYERDRIVER_ADD_DRIVER (videocanny build_videocanny
+    INCLUDEDIRS "${videocanny_includeDirs}" LIBDIRS "${videocanny_libDirs}" 
LINKLIBS "${videocanny_linkLibs}"
+    LINKFLAGS "${videocanny_linkFlags}" CFLAGS "${videocanny_cFlags}"
+    SOURCES videocanny.cc)

Added: code/player/trunk/server/drivers/camera/videocanny/videocanny.cc
===================================================================
--- code/player/trunk/server/drivers/camera/videocanny/videocanny.cc            
                (rev 0)
+++ code/player/trunk/server/drivers/camera/videocanny/videocanny.cc    
2009-07-10 00:15:06 UTC (rev 7964)
@@ -0,0 +1,459 @@
+/*
+ *  Player - One Hell of a Robot Server
+ *  Copyright (C) 2004  Brian Gerkey [email protected]
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*
+ *
+ * OpenCV-based edge detection.
+ */
+
+/** @ingroup drivers */
+/** @{ */
+/** @defgroup driver_VideoCanny VideoCanny
+ * @brief OpenCV-based edge detection.
+
+...@par Provides
+
+- @ref interface_camera
+
+...@par Requires
+
+- @ref interface_camera
+
+...@par Configuration requests
+
+- None
+
+...@par Configuration file options
+
+- function (string)
+  - Default: "canny"
+  - One of: "canny", "laplace", "sobel"
+
+- canny_threshold_1 (integer)
+  - Default: 50
+
+- canny_threshold_2 (integer)
+  - Default: 90
+
+- sobel_xorder (integer)
+  - Default: 2
+
+- sobel_yorder (integer)
+  - Default: 1
+
+- apsize (integer)
+  - Default: 3
+
+...@par Example
+
+...@verbatim
+driver
+(
+    name "videocanny"
+    function "sobel"
+    apsize 7
+    requires ["camera:0"]
+    provides ["camera:1"]
+)
+...@endverbatim
+
+...@author Piotr A. Dutt, Paul Osmialowski
+
+*/
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <pthread.h>
+#include <libplayercore/playercore.h>
+#include <libplayerjpeg/playerjpeg.h>
+
+#include <cv.h>
+#include <highgui.h>
+
+typedef enum { canny = 0, sobel, laplace } func_t;
+
+//---------------------------------
+
+class VideoCanny : public ThreadedDriver
+{
+  public: VideoCanny(ConfigFile * cf, int section);
+  public: virtual ~VideoCanny();
+
+  public: virtual int MainSetup();
+  public: virtual void MainQuit();
+
+  // This method will be invoked on each incoming message
+  public: virtual int ProcessMessage(QueuePointer & resp_queue,
+                                     player_msghdr * hdr,
+                                    void * data);
+
+  private: virtual void Main();
+  
+  // Input camera device
+  private: player_devaddr_t camera_id;
+  private: Device * camera;
+
+  // Output camera data
+  private: player_camera_data_t data;
+
+  private: unsigned char * buffer;
+  private: size_t bufsize;
+  private: unsigned char * decompress_buffer;
+  private: size_t decompress_bufsize;
+  private: IplImage * img8;
+  private: IplImage * img16;
+
+  // cvCanny Thresholds
+  private: int canny_threshold_1;
+  private: int canny_threshold_2;
+
+  // cvSobel settings
+  private: int sobel_xorder;
+  private: int sobel_yorder;
+
+  private: int apsize;
+  private: func_t function;
+};
+
+Driver * VideoCanny_Init(ConfigFile * cf, int section)
+{      
+  return reinterpret_cast<Driver *>(new VideoCanny(cf, section));
+}
+
+void videocanny_Register(DriverTable * table)
+{
+  table->AddDriver("videocanny", VideoCanny_Init);
+}
+
+VideoCanny::VideoCanny( ConfigFile *cf, int section)
+  : ThreadedDriver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN, 
PLAYER_CAMERA_CODE)
+{
+  const char * func;
+
+  memset(&(this->camera_id), 0, sizeof(player_devaddr_t));
+  memset(&(this->data), 0, sizeof this->data);
+  this->data.image = NULL;
+  this->camera = NULL;
+  this->buffer = NULL;
+  this->bufsize = 0;
+  this->decompress_buffer = NULL;
+  this->decompress_bufsize = 0;
+  this->img8 = NULL;
+  this->img16 = NULL;
+  if (cf->ReadDeviceAddr(&this->camera_id, section, "requires", 
PLAYER_CAMERA_CODE, -1, NULL) != 0)
+    { this->SetError(-1); return; }
+  if ((this->canny_threshold_1 = cf->ReadInt(section,"canny_threshold_1", 50)) 
< 0)
+  {   
+    PLAYER_WARN("Invalid value for canny_threshold_1 in .cfg file, using 50");
+    this->canny_threshold_1 = 50;
+  }
+  if ((this->canny_threshold_2 = cf->ReadInt(section,"canny_threshold_2", 90)) 
< 0)
+  {
+    PLAYER_WARN("Invalid value for canny_threshold_2 in .cfg file, using 90");
+    this->canny_threshold_2 = 90;
+  }
+  if ((this->sobel_xorder = cf->ReadInt(section,"sobel_xorder", 2)) < 0)
+  {
+    PLAYER_WARN("Invalid value for sobel_xorder in .cfg file, using 2");
+    this->sobel_xorder = 2;
+  }
+  if ((this->sobel_yorder = cf->ReadInt(section,"sobel_yorder", 1)) < 0)
+  {
+    PLAYER_WARN("Invalid value for sobel_yorder in .cfg file, using 1");
+    this->sobel_yorder = 1;
+  }
+  if ((this->apsize = cf->ReadInt(section,"apsize", 3)) < 0)
+  {
+    PLAYER_WARN("Invalid value for apsize using 3");
+    this->apsize = 3;
+  }
+  func = cf->ReadString(section, "function", "canny");
+  if (!func)
+  {
+    PLAYER_ERROR("error");
+    this->SetError(-1);
+    return;
+  }
+  if (!strcmp(func, "canny")) this->function = canny;
+  else if (!strcmp(func, "sobel")) this->function = sobel;
+  else if (!strcmp(func, "laplace")) this->function = laplace;
+  else
+  {
+    PLAYER_ERROR("unknown function name given");
+    this->SetError(-1);
+    return;
+  }
+}
+
+VideoCanny::~VideoCanny()
+{
+  if (this->data.image) free(this->data.image);
+  if (this->decompress_buffer) free(this->decompress_buffer);
+  if (this->buffer) free(this->buffer);
+  if (this->img8) cvReleaseImage(&(this->img8));
+  if (this->img16) cvReleaseImage(&(this->img16));
+}
+
+int VideoCanny::MainSetup()
+{
+  if (Device::MatchDeviceAddress(this->camera_id, this->device_addr))
+  {
+    PLAYER_ERROR("attempt to subscribe to self");
+    return -1;
+  }
+  this->camera = deviceTable->GetDevice(this->camera_id);  
+  if (!this->camera)
+  {
+    PLAYER_ERROR("unable to locate suitable camera device");
+    return -1;
+  }
+  if (this->camera->Subscribe(this->InQueue) != 0)
+  {
+    PLAYER_ERROR("unable to subscribe to camera device");
+    return -1;
+  }
+  return 0;
+}
+
+void VideoCanny::MainQuit()
+{
+  if (this->camera) this->camera->Unsubscribe(this->InQueue);
+  this->camera = NULL;
+}
+
+void VideoCanny::Main()
+{
+  for (;;)
+  {
+    this->InQueue->Wait();
+    pthread_testcancel();
+    this->ProcessMessages();
+    pthread_testcancel();
+  }
+}
+
+int VideoCanny::ProcessMessage(QueuePointer & resp_queue, player_msghdr * hdr, 
void * data)
+{
+  int i, j;
+  size_t new_size;
+  unsigned char * raw, * ptr, * ptr1;
+  player_camera_data_t * rawdata;
+  int bpp;
+
+  assert(hdr);
+  assert(data);
+  if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA, 
PLAYER_CAMERA_DATA_STATE, this->camera_id))
+  {
+    rawdata = reinterpret_cast<player_camera_data_t *>(data);
+    if ((rawdata->width <= 0) || (rawdata->height <= 0))
+    {
+      if (!(this->data.image)) return -1;
+    } else
+    {
+      switch(rawdata->compression)
+      {
+      case PLAYER_CAMERA_COMPRESS_RAW:
+        raw = reinterpret_cast<unsigned char *>(rawdata->image);
+       bpp = rawdata->bpp;
+        break;
+      case PLAYER_CAMERA_COMPRESS_JPEG:
+        new_size = rawdata->width * rawdata->height * 3;
+        if (this->decompress_bufsize != new_size)
+       {
+         if (this->decompress_buffer) free(this->decompress_buffer);
+         this->decompress_buffer = NULL;
+         this->decompress_bufsize = 0;
+       }
+       if (!(this->decompress_buffer))
+       {
+         this->decompress_bufsize = 0;
+         this->decompress_buffer = reinterpret_cast<unsigned char 
*>(malloc(new_size));
+         if (!(this->decompress_buffer))
+         {
+           PLAYER_ERROR("Out of memory");
+           return -1;
+         }
+         this->decompress_bufsize = new_size;
+       }
+       jpeg_decompress(this->decompress_buffer, this->decompress_bufsize, 
rawdata->image, rawdata->image_count);
+       raw = this->decompress_buffer;
+       bpp = 24;
+        break;
+      default:
+        PLAYER_WARN("unsupported compression scheme (not good)");
+        return -1;
+      }
+      new_size = rawdata->width * rawdata->height * 1;
+      ptr = NULL;
+      switch (bpp)
+      {
+      case 8:
+        ptr = raw;
+       break;
+      case 24:
+        if (this->bufsize != new_size)
+       {
+         if (this->buffer) free(this->buffer);
+         this->buffer = NULL;
+         this->bufsize = 0;
+       }
+       if (!(this->buffer))
+       {
+         this->bufsize = 0;
+         this->buffer = reinterpret_cast<unsigned char *>(malloc(new_size));
+         if (!(this->buffer))
+         {
+           PLAYER_ERROR("Out of memory");
+           return -1;
+         }
+         this->bufsize = new_size;
+       }
+       ptr = this->buffer;
+       ptr1 = raw;
+       for (i = 0; i < static_cast<int>(rawdata->height); i++)
+       {
+         for (j = 0; j < static_cast<int>(rawdata->width); j++)
+         {
+           *ptr = static_cast<unsigned char>(static_cast<int>(0.299 * 
static_cast<double>(ptr1[0]) + 0.587 * static_cast<double>(ptr1[1]) + 0.114 * 
static_cast<double>(ptr1[2])));
+           ptr++; ptr1 += 3;
+         }
+       }
+       ptr = this->buffer;
+       break;
+      case 32:
+        if (this->bufsize != new_size)
+       {
+         if (this->buffer) free(this->buffer);
+         this->buffer = NULL;
+         this->bufsize = 0;
+       }
+       if (!(this->buffer))
+       {
+         this->bufsize = 0;
+         this->buffer = reinterpret_cast<unsigned char *>(malloc(new_size));
+         if (!(this->buffer))
+         {
+           PLAYER_ERROR("Out of memory");
+           return -1;
+         }
+         this->bufsize = new_size;
+       }
+       ptr = this->buffer;
+       ptr1 = raw;
+       for (i = 0; i < static_cast<int>(rawdata->height); i++)
+       {
+         for (j = 0; j < static_cast<int>(rawdata->width); j++)
+         {
+           *ptr = static_cast<unsigned char>(static_cast<int>(0.299 * 
static_cast<double>(ptr1[0]) + 0.587 * static_cast<double>(ptr1[1]) + 0.114 * 
static_cast<double>(ptr1[2])));
+           ptr++; ptr1 += 4;
+         }
+       }
+       ptr = this->buffer;
+       break;
+      default:
+        PLAYER_WARN("unsupported image depth (not good)");
+        return -1;
+      }
+      assert(ptr);
+      if (this->img8)
+      {
+        if ((this->img8->width != static_cast<int>(rawdata->width)) || 
(this->img8->height != static_cast<int>(rawdata->height)))
+        {
+          if (this->img8) cvReleaseImage(&(this->img8));
+         this->img8 = NULL;
+        }
+      }
+      if (!(this->img8))
+      {
+        this->img8 = cvCreateImage(cvSize(rawdata->width, rawdata->height), 
IPL_DEPTH_8U, 1);
+       if (!(this->img8))
+       {
+         PLAYER_ERROR("Cannot create cvImage");
+         return -1;
+       }
+      }
+      memcpy(this->img8->imageData, ptr, new_size);
+      switch (this->function)
+      {
+      case canny:
+        cvCanny(this->img8, this->img8, this->canny_threshold_1, 
this->canny_threshold_2, this->apsize);
+       break;
+      case sobel:
+        cvSobel(this->img8, this->img8, this->sobel_xorder, 
this->sobel_yorder, this->apsize);
+        break;
+      case laplace:
+        if (this->img16)
+        {
+          if ((this->img16->width != static_cast<int>(rawdata->width)) || 
(this->img16->height != static_cast<int>(rawdata->height)))
+          {
+            if (this->img16) cvReleaseImage(&(this->img16));
+           this->img16 = NULL;
+          }
+        }
+        if (!(this->img16))
+        {
+          this->img16 = cvCreateImage(cvSize(rawdata->width, rawdata->height), 
IPL_DEPTH_16S, 1);
+         if (!(this->img16))
+         {
+           PLAYER_ERROR("Cannot create cvImage");
+           return -1;
+         }
+        }
+        cvLaplace(this->img8, this->img16, this->apsize);
+       cvConvertScaleAbs(this->img16, this->img8);
+        break;
+      default:
+        PLAYER_ERROR("Internal error!");
+       return -1;
+      }
+      new_size = this->img8->width * this->img8->height * 1;
+      if (this->data.image_count != new_size)
+      {
+        if (this->data.image) free(this->data.image);
+       this->data.image = NULL;
+       this->data.image_count = 0;
+      }
+      if (!(this->data.image))
+      {
+        this->data.image_count = 0;
+        this->data.image = reinterpret_cast<unsigned char *>(malloc(new_size));
+       if (!(this->data.image))
+       {
+         PLAYER_ERROR("Out of memory");
+         return -1;
+       }
+       this->data.image_count = new_size;
+      }
+      memcpy(this->data.image, this->img8->imageData, this->data.image_count);
+      this->data.width = this->img8->width;
+      this->data.height = this->img8->height;
+      this->data.bpp = 8;
+      this->data.fdiv = 0;
+      this->data.format = PLAYER_CAMERA_FORMAT_MONO8;
+      this->data.compression = PLAYER_CAMERA_COMPRESS_RAW;
+    }
+    this->Publish(device_addr, PLAYER_MSGTYPE_DATA, PLAYER_CAMERA_DATA_STATE, 
reinterpret_cast<void *>(&(this->data)), 0, &(hdr->timestamp), true);
+    // don't delete anything here! this->data.image is required and is deleted 
somewhere else
+    return 0;
+  }
+  return -1;
+}


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to