⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simpleshape.cc

📁 机器人仿真软件
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* *  Player - One Hell of a Robot Server *  Copyright (C) 2000  Brian Gerkey et al *                      gerkey@usc.edu     * *  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 * *//////////////////////////////////////////////////////////////////////////////// Desc: Driver for detecting simple shapes in a camera image// Author: Andrew Howard// Date: 15 Feb 2004// CVS: $Id: simpleshape.cc,v 1.4.2.1 2006/06/07 16:12:39 gerkey Exp $//////////////////////////////////////////////////////////////////////////////** @ingroup drivers *//** @{ *//** @defgroup driver_simpleshape simpleshape * @brief Visual shape-detection@todo This driver is currently disabled because it needs to be updated tothe Player 2.0 API.The simpleshape driver looks for simple geometric shapes in a cameraimage.  The user must supply a @e model of the target shape, in theform of a binary image (such as the one shown below).@image html simpleshape_h.gif "Sample model for the simpleshape detector"@par Compile-time dependencies- OpenCV@par Requires- This driver acquires image data from a @ref interface_camera  interface.@par Provides- This driver provides detected shapes through a @ref  interface_blobfinder interface.- This driver also supplies processed image data through a @ref  interface_camera interface (this data is intended mostly for  debugging).  Note that the dimensions of the output image are twice  that of the input image: the output image is divided into four  parts, each showing one step in the detection process.  From  top-to-bottom and left-to-right, these are: original image  (monochrome), edge image, contour image, detected shapes.@image html simpleshape_output.gif "Output image (debugging)"@par Configuration requests- none@par Configuration file options- model (string)  - Default: NULL  - Filename of the model image file.  This should by a binary,    grayscale image.- canny_thresh (float tuple)   - Default: [40 20]  - Thresholds for the Canny edge detector.- match_thresh (float tuple)   - Default: [0.50 20.0 0.20]  - Match thresholds (?)@par Example@verbatimdriver(  name "simpleshape"  requires ["camera:0"]  provides ["blobfinder:1" "camera:1"]  model "simpleshape_h.pgm")@endverbatim@author Andrew Howard*//** @} */#include "../../base/imagebase.h"#include <opencv/cv.h>#include <opencv/highgui.h>// Invariant feature set for a contourclass FeatureSet{  // Contour moments  public: CvMoments moments;  // Compactness  public: double compact;  // Elliptical variance  public: double variance;  // Vertices  public: int vertexCount;  public: int vertexString[256];};// Info on potential shapes.class Shape {  // Id (-1) if undetermined.  public: int id;  // Shape bounding coords  public: int ax, ay, bx, by;};// Driver for detecting laser retro-reflectors.class SimpleShape : public ImageBase{  public:     // Constructor    SimpleShape( ConfigFile* cf, int section);    // Setup/shutdown routines.    virtual int Setup();    virtual int Shutdown();  // Load a shape model  private: int LoadModel();  // Process the image  private: int ProcessFrame();  // Having pre-processed the image, find some shapes  private: void FindShapes();  // Extract a feature set for the given contour  private: void ExtractFeatureSet(CvContour *contour, FeatureSet *feature);  // Compute similarity measure on features  private: int MatchFeatureSet(FeatureSet *a, FeatureSet *b);  // Write the outgoing blobfinder data  private: void WriteBlobfinderData();  // Model data (this is the shape to search for)  private: const char *modelFilename;  private: CvMemStorage *modelStorage;  private: CvSeq *modelContour;  private: FeatureSet modelFeatureSet;  // Images  private: IplImage *inpImage;  private: IplImage *outImage;  private: CvMat outSubImages[4];  private: IplImage *workImage;  // Parameters  private: double cannyThresh1, cannyThresh2;  private: double matchThresh[3];  // List of potential shapes  private: Shape shapes[256];  private: unsigned int shapeCount;};// Initialization functionDriver* SimpleShape_Init( ConfigFile* cf, int section){  return ((Driver*) (new SimpleShape( cf, section)));}// a driver registration functionvoid SimpleShape_Register(DriverTable* table){  table->AddDriver("simpleshape", SimpleShape_Init);}////////////////////////////////////////////////////////////////////////////////// ConstructorSimpleShape::SimpleShape( ConfigFile* cf, int section)	: ImageBase(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN, PLAYER_BLOBFINDER_CODE){  this->inpImage = NULL;  this->outImage = NULL;  this->workImage = NULL;  // Filename for the target shape image  this->modelFilename = cf->ReadFilename(section, "model", NULL);  // Parameters  this->cannyThresh1 = cf->ReadTupleFloat(section, "canny_thresh", 0, 40);  this->cannyThresh2 = cf->ReadTupleFloat(section, "canny_thresh", 1, 20);  this->matchThresh[0] = cf->ReadTupleFloat(section, "match_thresh", 0, 0.50);  this->matchThresh[1] = cf->ReadTupleFloat(section, "match_thresh", 1, 20.0);  this->matchThresh[2] = cf->ReadTupleFloat(section, "match_thresh", 2, 0.20);    this->shapeCount = 0;  return;}////////////////////////////////////////////////////////////////////////////////// Set up the device (called by server thread).int SimpleShape::Setup(){  // Load the shape model  if (this->LoadModel() != 0)    return -1;  return ImageBase::Setup();  return 0;}////////////////////////////////////////////////////////////////////////////////// Shutdown the device (called by server thread).int SimpleShape::Shutdown(){  ImageBase::Shutdown();    // Free images  if (this->inpImage)    cvReleaseImage(&(this->inpImage));  if (this->outImage)    cvReleaseImage(&(this->outImage));  return 0;}////////////////////////////////////////////////////////////////////////////////// Load a shape modelint SimpleShape::LoadModel(){  IplImage *img, *work;  CvSize size;  CvSeq *contour, *maxContour;  double area, maxArea;  // Load the image  img = cvLoadImage(this->modelFilename, 0);  if (img == NULL)  {    PLAYER_ERROR("failed to load model file");    return -1;  }  // Create work image  size = cvSize(img->width, img->height);  work = cvCreateImage(size, IPL_DEPTH_8U, 1);  // Find edges  cvCanny(img, work, this->cannyThresh1, this->cannyThresh2);  // Extract contours  this->modelStorage = cvCreateMemStorage(0);  cvFindContours(work, this->modelStorage, &contour, sizeof(CvContour),                  CV_RETR_LIST, CV_CHAIN_APPROX_NONE);    // Find the contour with the largest area (we will use the outer  // contour only)  maxArea = 0;  maxContour = NULL;  for (; contour != NULL; contour = contour->h_next)  {    area = fabs(cvContourArea(contour));    if (area > maxArea)    {      maxArea = area;      maxContour = contour;    }  }  if (maxContour == NULL)  {    PLAYER_ERROR("no usable contours in model image");    return -1;  }  this->modelContour = maxContour;  // Record some features of the contour; we will use these to  // recognise it later.  this->ExtractFeatureSet((CvContour*) this->modelContour, &this->modelFeatureSet);  // Free the image  cvReleaseImage(&work);  cvReleaseImage(&img);  return 0;}////////////////////////////////////////////////////////////////////////////////// Look for stuff in the image.int SimpleShape::ProcessFrame(){  CvSize size;  int width, height;    width = this->stored_data.width;  height = this->stored_data.height;  assert(width > 0 && height > 0);      // Create input and output image if it doesnt exist  size = cvSize(width, height);  if (this->inpImage == NULL)    this->inpImage = cvCreateImage(size, IPL_DEPTH_8U, 1);  size = cvSize(2 * width, 2 * height);  if (this->outImage == NULL)  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -