Index: VisionLib.cpp =================================================================== --- VisionLib.cpp (.../trunk/ocl/vision) (revision 0) +++ VisionLib.cpp (.../branches/ocl-pma/vision) (revision 29988) @@ -0,0 +1,47 @@ +/*************************************************************************** + + VisionLib.hpp - description + ------------------------- + + begin : Febr 2008 + copyright : (C) 2008 Francois Cauwe + email : francois@cauwe.org + + *************************************************************************** + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307 USA * + * * + ***************************************************************************/ + +#ifndef __VISIONLIB__ +#define __VISIONLIB__ + +#include + +#include "RegionFeature.hpp" +#include "DisplayImageComponent.hpp" +#include "LoadImage.hpp" +#include "LoadVideo.hpp" +#include "WriteImage.hpp" + +// Make this component deployable +ORO_CREATE_COMPONENT_TYPE( ) +ORO_LIST_COMPONENT_TYPE( OCL::RegionFeature ) +ORO_LIST_COMPONENT_TYPE( OCL::DisplayImageComponent ) +ORO_LIST_COMPONENT_TYPE( OCL::LoadImage ) +ORO_LIST_COMPONENT_TYPE( OCL::LoadVideo ) +ORO_LIST_COMPONENT_TYPE( OCL::WriteImage ) + +#endif Index: RegionFeature.cpp =================================================================== --- RegionFeature.cpp (.../trunk/ocl/vision) (revision 0) +++ RegionFeature.cpp (.../branches/ocl-pma/vision) (revision 29988) @@ -0,0 +1,340 @@ +// Copyright (C) 2008 Francois Cauwe +// +// 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. +// + +#include "RegionFeature.hpp" +#include +#include + +using namespace RTT; +using namespace std; + +namespace OCL +{ + + RegionFeature::RegionFeature(string name) + :TaskContext(name, PreOperational), + _image("RawImage"), + _image_debug("DebugImage"), + _feature_pos("position"), + _iterations("Number of iterations to converge"), + _buildHistogramObject("buildObjectHistogram",&RegionFeature::buildHistogramObject,&RegionFeature::buildHistogramObjectFinished, this), + _buildHistogramNotObject("buildEnviromentHistogram",&RegionFeature::buildHistogramNotObject,&RegionFeature::buildHistogramNotObjectFinished, this), + _region_width("region_width","Size of the region",50), + _region_height("region_height","Size of the region",50), + _region_start_x("region_start_x","Starting position",100), + _region_start_y("region_start_y","Starting position",100), + _visualize("visualize","Visualize results",false), + _localpos(2,0) + { + + // Adding ports + //============= + this->ports()->addPort(&_image); + this->ports()->addPort(&_image_debug); + this->ports()->addPort(&_feature_pos); + this->ports()->addPort(&_iterations); + + + //Adding Properties + //================= + this->properties()->addProperty( &_region_width ); + this->properties()->addProperty( &_region_height ); + this->properties()->addProperty( &_region_start_x ); + this->properties()->addProperty( &_region_start_y ); + this->properties()->addProperty( &_visualize ); + + //Adding command + //============== + + this->commands()->addCommand( &_buildHistogramObject,"Build up the histogram of the object."); + this->commands()->addCommand( &_buildHistogramNotObject,"Build up the histogram of the envirnoment."); + + } + + RegionFeature::~RegionFeature() + { + // nothing to do + } + + + bool RegionFeature::configureHook() + { + + // Set histogram flag + _histogram_made = false; + _histogram_object_made = false; + _histogram_notobject_made = false; + + // Get image + _rgb_frame = _image.Get(); + _frame = _rgb_frame.getPtr(); + // Set debug image + _image_debug.Set(_rgb_frame); + + // Initialize memory + _frame_r = cvCreateImage( cvGetSize(_frame),IPL_DEPTH_8U, 1 ); + _frame_b = cvCreateImage( cvGetSize(_frame),IPL_DEPTH_8U, 1 ); + _frame_g = cvCreateImage( cvGetSize(_frame),IPL_DEPTH_8U, 1 ); + + _frame_probability = cvCreateImage( cvGetSize(_frame),IPL_DEPTH_8U, 1 ); + _frame_array[0] = _frame_r; + _frame_array[1] = _frame_g; + _frame_array[2] = _frame_b; + + int histogramBins [] = {32, 32, 32}; + _histogram = cvCreateHist( 3, histogramBins, CV_HIST_ARRAY); + _histogram_object = cvCreateHist( 3, histogramBins, CV_HIST_ARRAY); + _histogram_notobject = cvCreateHist( 3, histogramBins, CV_HIST_ARRAY); + _frame_mask = cvCreateImage( cvGetSize(_frame),IPL_DEPTH_8U, 1); + + _localpos[0] = _region_start_x.value(); + _localpos[1] = _region_start_y.value(); + _feature_pos.Set(_localpos); + + return true; + } + + bool RegionFeature::startHook() + { + + //Initialize capturing + //===================== + + log(Info) << "(" << this->getName() << ") Tracking started..." << endlog(); + return true; + } + + void RegionFeature::cleanupHook() + { + // Release memory + cvReleaseImage(&_frame_r); + cvReleaseImage(&_frame_g); + cvReleaseImage(&_frame_b); + cvReleaseImage(&_frame_probability); + cvReleaseImage(&_frame_mask); + + cvReleaseHist(&_histogram); + cvReleaseHist(&_histogram_notobject); + cvReleaseHist(&_histogram_object); + _histogram_made=false; + _histogram_object_made=false; + _histogram_notobject_made=false; + + log(Info) << "(" << this->getName() << ") stopping tracking..." << endlog(); + } + + void RegionFeature::updateHook() + { + _update = false; + _rgb_frame = _image.Get(); + _frame = _rgb_frame.getPtr(); + + + // Track feature + if(_histogram_made){ + + // Initialize + int iterations = 0; + CvConnectedComp comp; + CvRect searchwindow; + + _localpos[0] = _feature_pos.Get()[0]; + _localpos[1] = _feature_pos.Get()[1]; + + searchwindow.x = (int)_localpos[0] - _region_width.value()/2; + searchwindow.y = (int)_localpos[1] - _region_height.value()/2; + + searchwindow.x = searchwindow.x<0?0:searchwindow.x; + searchwindow.y = searchwindow.y<0?0:searchwindow.y; + + searchwindow.width = _region_width.value(); + searchwindow.height = _region_height.value(); + + // split the image in RGB + cvCvtPixToPlane(_frame, _frame_b, _frame_g, _frame_r, NULL); + + // Probability + cvCalcBackProject(_frame_array, _frame_probability, _histogram); + + // do the tracking + iterations = cvMeanShift(_frame_probability, searchwindow, cvTermCriteria(CV_TERMCRIT_ITER, 10, 0.1), &comp); + + searchwindow.x = comp.rect.x; + searchwindow.y = comp.rect.y; + + _localpos[0] = (double)(searchwindow.x + _region_width.value()/2); + _localpos[1] = (double)(searchwindow.y + _region_height.value()/2); + _feature_pos.Set(_localpos); + _iterations.Set(iterations); + + // Visualise + if(_visualize.value()){ + // draw a rectangle + int box_x1 = searchwindow.x; + int box_y1 = searchwindow.y; + int box_x2 = searchwindow.x+searchwindow.width; + int box_y2 = searchwindow.y+searchwindow.height; + + box_x1 = box_x1<3?3:box_x1; + box_y1 = box_y1<3?3:box_y1; + + cvRectangle( _frame, + cvPoint(box_x1,box_y1), + cvPoint(box_x2,box_y2), + cvScalar(200, 0, 0), 2 ); + + cvRectangle( _frame, + cvPoint(searchwindow.x+searchwindow.width/2-2, searchwindow.y+searchwindow.height/2-2), + cvPoint(searchwindow.x+searchwindow.width/2+2, searchwindow.y+searchwindow.height/2+2), + cvScalar(0, 200, 0), 1 ); + + _image_debug.Set(_rgb_frame); + } + }else{ + + if(_visualize.value()){ + cvRectangle( _frame, + cvPoint(_region_start_x.value()-_region_width.value()/2,_region_start_y.value()-_region_height.value()/2), + cvPoint(_region_start_x.value()+_region_width.value()/2,_region_start_y.value()+_region_height.value()/2), + cvScalar(0,0,255), 2); + + _image_debug.Set(_rgb_frame); + } + } + + _update = true; + } + + bool RegionFeature::buildHistogramObject() + { + _histogram_made = false; + _histogram_object_made = false; + + // grab a frame + _rgb_frame = _image.Get(); + _frame = _rgb_frame.getPtr(); + + // split the image in RGB + cvCvtPixToPlane(_frame, _frame_b, _frame_g, _frame_r, 0); + + // make mask + cvSetZero(_frame_mask); + cvRectangle( _frame_mask, + cvPoint(_region_start_x.value()-_region_width.value()/2,_region_start_y.value()-_region_height.value()/2), + cvPoint(_region_start_x.value()+_region_width.value()/2,_region_start_y.value()+_region_height.value()/2), + cvScalar(255), CV_FILLED); + + // calculate histogram + cvCalcHist( _frame_array, _histogram_object, 0, _frame_mask ); + cvNormalizeHist( _histogram_object , 1 ); + + _histogram_object_made = true; + + // update status + if(_histogram_object_made && _histogram_notobject_made){ + buildHistogramBayes(); + _histogram_made = true; + }else{ + _histogram_made = false; + } + return true; + } + + bool RegionFeature::buildHistogramObjectFinished()const + { + return _histogram_object_made; + } + + + bool RegionFeature::buildHistogramNotObject() + { + _histogram_made = false; + _histogram_notobject_made = false; + + // grab a frame + _rgb_frame = _image.Get(); + _frame = _rgb_frame.getPtr(); + + // split the image in RGB + cvCvtPixToPlane(_frame, _frame_b, _frame_g, _frame_r, 0); + + // calculate histogram + cvCalcHist( _frame_array, _histogram_notobject, 0); + cvNormalizeHist( _histogram_notobject , 1 ); + + _histogram_notobject_made = true; + + // update status + if(_histogram_object_made&&_histogram_notobject_made){ + buildHistogramBayes(); + _histogram_made = true; + }else{ + _histogram_made = false; + } + return true; + } + + bool RegionFeature::buildHistogramNotObjectFinished()const + { + return _histogram_notobject_made; + } + + void RegionFeature::buildHistogramBayes() + { + /// _histogram_object = Prob(color|isobject) + /// _histogram_notobject = Prob(color|isnotobject) + /// _histogram = Prob(isobject|color) + /// + /// P(isobject|color) * P(color) = P(color|isobject)*P(isobject) + /// + /// P(isobject|color) = P(color|isobject) / P(color) + /// + /// P(isobject|color) = P(color|isobject) * P(isobject) / (P(color|isobject)*P(isobject)+P(color|isnotobject)*P(isnotobject)) + /// + /// Assume that P(isobject) == P(isnotobject) + /// + /// P(isobject|color) = P(color|isobject) / (P(color|isobject) + P(color|isnotobject)) + /// + double objectProb; + double notObjectProb; + double bayesianProb; + + for(int i = 0; i < 32; i++) + for(int j = 0; j < 32; j++) + for(int k = 0; k < 32; k++){ + objectProb = cvQueryHistValue_3D(_histogram_object,i,j,k); + notObjectProb = cvQueryHistValue_3D(_histogram_object,i,j,k); + if((objectProb + notObjectProb)==0){ + bayesianProb = 0; + }else{ + bayesianProb = objectProb / (objectProb + notObjectProb); + } + cvSetReal3D((_histogram)->bins, i, j, k, bayesianProb); + } + + // make a histogram with max value = 255 + float max, norm_factor; + cvNormalizeHist( _histogram , 1 ); + cvGetMinMaxHistValue(_histogram,0,&max); + norm_factor = 255/max; + cvNormalizeHist( _histogram , norm_factor ); + + } + +}//namespace + + Index: DisplayImageComponent.hpp =================================================================== --- DisplayImageComponent.hpp (.../trunk/ocl/vision) (revision 29988) +++ DisplayImageComponent.hpp (.../branches/ocl-pma/vision) (revision 29988) @@ -1,8 +1,7 @@ /*************************************************************************** - ImageDisplayComponent.hpp - description + DisplayImageComponent.hpp - description ------------------------- - begin : Jan 2008 copyright : (C) 2008 Francois Cauwe based on : ReporterComponent.cpp made by Peter Soetens @@ -26,8 +25,8 @@ * * ***************************************************************************/ -#ifndef __IMAGEDISPLAYCOMPONENT__ -#define __IMAGEDISPLAYCOMPONENT__ +#ifndef __DISPLAYIMAGECOMPONENT__ +#define __DISPLAYIMAGECOMPONENT__ // RTT includes #include @@ -42,7 +41,7 @@ #include -#include "Vision.hpp" +#include "VisionToolkit.hpp" namespace OCL { @@ -50,14 +49,10 @@ * @brief A component for periodically displaying IplImages * of other components. * - * WARNING: You should only use one ImageDisplayComponent, and - * OpenCV's mainloop (waitkey()) should not be called by an other - * component. - * * @par Configuration - * The ImageDisplayComponent (and its decendants) take two configuration + * The DisplayImageComponent (and its decendants) take two configuration * files. The first is the 'classical' XML '.cpf' file which contains - * the property values of the ImageDisplayComponent. The second XML file + * the property values of the DisplayImageComponent. The second XML file * is in the same format, but describes which ports and peer components * need to be monitored. It has the following format: * @code @@ -76,15 +71,15 @@ * is listed in the 'Configuration' property. */ - class ImageDisplayComponent : public RTT::TaskContext + class DisplayImageComponent : public RTT::TaskContext { public: /** * Set up a component for displaying. */ - ImageDisplayComponent(std::string name); + DisplayImageComponent(std::string name); - virtual ~ImageDisplayComponent(); + virtual ~DisplayImageComponent(); /** * Implementation of TaskCore::configureHook(). @@ -122,7 +117,7 @@ typedef std::vector Reports; Reports root; - virtual bool addDisplayPort(std::string& cname, std::string& pname); + virtual bool addDisplayPort(const std::string& cname, const std::string& pname); bool addDisplaySource(std::string tag, std::string type, RTT::DataSourceBase::shared_ptr orig); @@ -131,4 +126,4 @@ }; } -#endif // IMAGEDISPLAYCOMPONENT +#endif // DISPLAYIMAGECOMPONENT Index: LoadImage.cpp =================================================================== --- LoadImage.cpp (.../trunk/ocl/vision) (revision 0) +++ LoadImage.cpp (.../branches/ocl-pma/vision) (revision 29988) @@ -0,0 +1,111 @@ +// Copyright (C) 2008 Francois Cauwe +// +// 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. +// + +#include "LoadImage.hpp" +#include +#include + + +namespace OCL +{ + + using namespace RTT; + using namespace std; + + LoadImage::LoadImage(string name): + TaskContext(name, PreOperational), + _image("RawImage"), + _updateImage("getImage",&LoadImage::updateImage,&LoadImage::updateImageFinished, this), + _filename("filename","Name of the file that should be loaded","test.jpg"), + _update_image(false) + { + + //Adding dataports + //================ + this->ports()->addPort(&_image); + + //Adding Properties + //================= + this->properties()->addProperty( &_filename ); + + //Adding command + //============== + this->commands()->addCommand( &_updateImage,"Read image and store in DataPort"); + + } + + LoadImage::~LoadImage() + { + //nothing to do + } + + + bool LoadImage::configureHook() + { + return updateImage(); + } + + + bool LoadImage::startHook() + { + return true; + } + + void LoadImage::cleanupHook() + { + // Release frame + cvReleaseImage( &_frame ); + } + + // Update image + bool LoadImage::updateImage() + { + _update_image=false; + // Release memory if used + if(!_frame) + cvReleaseImage(&_frame); + + // Load image + _frame=cvLoadImage(_filename.value().data()); + if(!_frame){ + log(Error) << "Could not load image '" << _filename.value() << "'." << endlog(); + return false; + } + + log(Info) << "Loaded image '" << _filename.value() << "'." << endlog(); + + _RgbFrame.Set(_frame); + _image.Set(_RgbFrame); + + _update_image=true; + return true; + } + + bool LoadImage::updateImageFinished()const + { + return _update_image; + } + + void LoadImage::updateHook() + { + + } + + +}//namespace + + Index: VisionToolkit.hpp =================================================================== --- VisionToolkit.hpp (.../trunk/ocl/vision) (revision 29988) +++ VisionToolkit.hpp (.../branches/ocl-pma/vision) (revision 29988) @@ -38,12 +38,95 @@ namespace OCL { + + // A orocos safe implementation of IPlImage + + template class Image + { + private: + IplImage* imgp; + public: + + Image(IplImage* img=0){ + if(img){ + imgp=cvCloneImage(img); + }else{ + imgp=0; + } + } + /// Copy constructor + Image(const Image &imgIn){ + if(imgIn.imgp){ + imgp=cvCloneImage(imgIn.imgp); + }else{ + imgp=0; + } + } + /// Destructor + ~Image(){ + if(imgp){ + cvReleaseImage(&imgp); + } + } + + void operator=(IplImage* imgIpl) { + this->Set(imgIpl); + } + + void operator=(const Image &imgIn) { + if(imgIn.imgp){ + this->Set(imgIn.imgp); + }else{ + if(imgp){ + cvReleaseImage(&imgp); + imgp=0; + } + } + } + IplImage * getPtr(){ + return imgp; + } + void Set(IplImage* imgIpl){ + // If there is no image saved, just copy the image + if(!imgp){ + imgp=cvCloneImage(imgIpl); + } + // There is already an image in the component + else{ + // If the size is the same, copy the data fast + if((imgIpl->height==imgp->height)&&(imgIpl->width==imgp->width)&&(imgIpl->nChannels==imgp->nChannels)&&(imgIpl->depth==imgp->depth)){ + cvCopyImage(imgIpl,imgp); + } + // The size is different, release memory and clone image + else{ + cvReleaseImage(&imgp); + imgp = cvCloneImage(imgIpl); + } + } + } + + inline T* operator[](const int rowIndx) { + return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));} + }; + + typedef struct{ + unsigned char b,g,r; + } RgbPixel; + + typedef struct{ + unsigned char g; + } GrayPixel; + + typedef Image RgbImage; + typedef Image GrayImage; + + // Define the image type - struct IplImageTypeInfo - : public RTT::TemplateTypeInfo + struct RgbImageTypeInfo + : public RTT::TemplateTypeInfo { - IplImageTypeInfo() - : RTT::TemplateTypeInfo("IplImage") + RgbImageTypeInfo() + : RTT::TemplateTypeInfo("RgbImage") {} }; Index: WriteImage.hpp =================================================================== --- WriteImage.hpp (.../trunk/ocl/vision) (revision 0) +++ WriteImage.hpp (.../branches/ocl-pma/vision) (revision 29988) @@ -0,0 +1,88 @@ +// Copyright (C) 2008 Thomas Van Dijck +// +// 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. +// + +#ifndef __WRITEIMAGE_HPP__ +#define __WRITEIMAGE_HPP__ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "VisionToolkit.hpp" +#include + +namespace OCL +{ + + /** + * This class implements a TaskContext that writes + * images from a port to a file using OpenCV. The writing of the files + * has to be executed as a command. Files will be named sequentially frame%010d + * where %010d is a ten-digit number with leading zero's. Files will be stored in a + * photos/ directory that will be created in executing directory of program. + */ + + class WriteImage : public RTT::TaskContext + { + + public: + /** + * Creates an unconfigured WriteImage component. + * + * @param name Name of the component + * + * @return + */ + WriteImage(std::string name); + virtual ~WriteImage(); + virtual bool configureHook(); + virtual bool startHook(); + virtual void updateHook(); + virtual void cleanupHook(); + + virtual bool updateImage(); + virtual bool updateImageFinished()const; + + protected: + /// Dataport which contains the grabbed image + RTT::ReadDataPort _image; + /// Command to write the grabbed frame + RTT::Command _updateImage; + + private: + + IplImage* _frame; + RgbImage _RgbFrame; + bool _update_image; + int _frame_index; + char filename[25]; + bool _portChanged; + + }; +}//namespace + +#endif // WRITEIMAGE_HPP Index: RegionFeature.hpp =================================================================== --- RegionFeature.hpp (.../trunk/ocl/vision) (revision 0) +++ RegionFeature.hpp (.../branches/ocl-pma/vision) (revision 29988) @@ -0,0 +1,126 @@ +// Copyright (C) 2008 Francois Cauwe +// +// 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. +// + +#ifndef __REGIONFEATURE_HPP__ +#define __REGIONFEATURE_HPP__ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include "VisionToolkit.hpp" + +namespace OCL +{ + + /** + * This class implements a TaskContext that grabs + * images from a firewire-camera using OpenCV. The component + * can be executed a periodic as well as by a non-periodic + * activity. + * + */ + + class RegionFeature : public RTT::TaskContext + { + + public: + /** + * Creates an unconfigured CaptureCamera component. + * + * @param name Name of the component + * + * @return + */ + + RegionFeature(std::string name); + virtual ~RegionFeature(); + virtual bool configureHook(); + virtual bool startHook(); + virtual void updateHook(); + virtual void cleanupHook(); + + protected: + /// Dataport which contains grabbed image + RTT::ReadDataPort _image; + /// Dataport which contains a image fof debugging proposes + RTT::WriteDataPort _image_debug; + /// position of feature + RTT::DataPort > _feature_pos; + // RTT::DataPort _feature_pos_y; + RTT::WriteDataPort _iterations; + + /// Command to build up the color histogram + RTT::Command _buildHistogramObject; + RTT::Command _buildHistogramNotObject; + + /// Region width + RTT::Property _region_width; + /// Region height + RTT::Property _region_height; + /// start x + RTT::Property _region_start_x; + /// start y + RTT::Property _region_start_y; + /// visualisation (for debugging only!) + RTT::Property _visualize; + + + private: + virtual bool buildHistogramObject(); + virtual bool buildHistogramObjectFinished()const; + virtual bool buildHistogramNotObject(); + virtual bool buildHistogramNotObjectFinished()const; + virtual void buildHistogramBayes(); + + RgbImage _rgb_frame; + IplImage * _frame; + IplImage * _frame_array[3]; + IplImage * _frame_r; + IplImage * _frame_g; + IplImage * _frame_b; + + IplImage * _frame_probability; + + IplImage * _frame_mask; + + CvHistogram * _histogram_object; + CvHistogram * _histogram_notobject; + CvHistogram * _histogram; + + std::vector _localpos; + + bool _update; + bool _histogram_object_made; + bool _histogram_notobject_made; + bool _histogram_made; + }; +}//namespace + +#endif // REGIONFEATURE_HPP + Index: LoadVideo.cpp =================================================================== --- LoadVideo.cpp (.../trunk/ocl/vision) (revision 0) +++ LoadVideo.cpp (.../branches/ocl-pma/vision) (revision 29988) @@ -0,0 +1,172 @@ +// Copyright (C) 2008 Dominick Vanthienen first.last@student.kuleuven.be +// Thomas Van Dijck +// +// 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. +// + +#include "LoadVideo.hpp" +#include +#include + + +namespace OCL +{ + + using namespace RTT; + using namespace std; + + LoadVideo::LoadVideo(string name): + TaskContext(name, PreOperational), + _image("RawImage"), + _capture_time("CaptureTimestamp"), + _filename("filename","Name of the video file to load","appelfilmpjes/MVI_3440.AVI"), + _show_time("show_time","True if i have to log capture times (WARNING: only for debugging)",false), + _show_image("show_image","True if i have to show captured image (WARNING: only for debugging)",false), + _update(false) + { + + //Adding dataports + //================ + this->ports()->addPort(&_image); + this->ports()->addPort(&_capture_time); + + //Adding Properties + //================= + this->properties()->addProperty( &_filename ); + this->properties()->addProperty( &_show_time ); + this->properties()->addProperty( &_show_image ); + + } + + LoadVideo::~LoadVideo() + { + //nothing to do + } + + + bool LoadVideo::configureHook() + { + Logger::In in(this->getName().data()); + + //Initialize capturing + //==================== + _capture = cvCaptureFromFile(_filename.value().data()); + //TODO dit is invullen _filename.value().data() + + if( !_capture ){ + // Either the video didn't exist OR it uses a codec OpenCV doesn't support. + log(Error) << "Could not initialize capturing..." << endlog(); + return false; + } + + // Set properties + //=============== + //this->setProperties(); + + // Grab one frame + //=============== + _frame=cvQueryFrame(_capture); + _RgbFrame.Set(_frame); + _image.Set(_RgbFrame); + if(_show_image.value()){ + cvNamedWindow(this->getName().c_str(),CV_WINDOW_AUTOSIZE); + cvWaitKey(3);//wait 3 ms for main loop of graphical server + cvShowImage(this->getName().c_str(),_frame); + cvWaitKey(3);//wait 3 ms for main loop of graphical server + } + + log(Info) << "Capturing initialized..." << endlog(); + return true; + } + + + + bool LoadVideo::startHook() + { + //Start capturing + //=============== + _capture_time.Set(TimeService::Instance()->ticksGet()); + + return true; + } + + void LoadVideo::cleanupHook() + { + Logger::In in(this->getName().data()); + + // Close window + if(_show_image.value()){ + cvDestroyWindow(this->getName().c_str()); + cvWaitKey(3);//wait 3 ms for main loop of graphical server + } + + // Release capture device + cvReleaseCapture( &_capture ); + } + void LoadVideo::updateHook() + { + Logger::In in(this->getName().data()); + + _update = false; + + // Show time since last capture + if(_show_time.value()){ + _elapsed = TimeService::Instance()->secondsSince( _timestamp ); + log(Info) << "time since last capture: "<< _elapsed << endlog(); + _timestamp = TimeService::Instance()->ticksGet(); + } + + // Capture new frame + _capture_time.Set(TimeService::Instance()->ticksGet()); + + if(!cvGrabFrame(_capture)){ + log(Error) << "Failed to grab a new frame." << endlog(); + this->error(); + } + _frame = cvRetrieveFrame(_capture); + _RgbFrame.Set(_frame); + _image.Set(_RgbFrame); + + // Show image + if(_show_image.value()){ + cvShowImage(this->getName().c_str(),_frame); + cvWaitKey(3);//wait 3 ms for main loop of graphical server + } + + // Show time used for capturing + if(_show_time.value()){ + _elapsed = TimeService::Instance()->secondsSince( _timestamp ); + log(Info) << "time used for capturing: "<< _elapsed << endlog(); + _timestamp = TimeService::Instance()->ticksGet(); + } + + _update = true; + } + + /* bool LoadVideo::setFilename() + { + Logger::In in(this->getName().data()); + //TODO alles stopzetten: zie clean up hook, erna nieuwe file inladen; kwe ni of da ga gaan mss methode maken? + _update_filename=false; + + _update_filename = true; + return true; + } + + bool LoadVideo::setFilenameFinished()const + { + return _update_filename; + }*/ +}//namespace Index: LoadImage.hpp =================================================================== --- LoadImage.hpp (.../trunk/ocl/vision) (revision 0) +++ LoadImage.hpp (.../branches/ocl-pma/vision) (revision 29988) @@ -0,0 +1,89 @@ +// Copyright (C) 2006 Francois Cauwe +// +// 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. +// + +#ifndef __LOADIMAGE_HPP__ +#define __LOADIMAGE_HPP__ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "VisionToolkit.hpp" + + +namespace OCL +{ + + /** + * This class implements a TaskContext that grabs + * images from a file using OpenCV. The component + * can be executed a periodic as well as by a non-periodic + * activity. + * + */ + + class LoadImage : public RTT::TaskContext + { + + public: + /** + * Creates an unconfigured LoadImage component. + * + * @param name Name of the component + * + * @return + */ + LoadImage(std::string name); + virtual ~LoadImage(); + virtual bool configureHook(); + virtual bool startHook(); + virtual void updateHook(); + virtual void cleanupHook(); + + protected: + /// Dataport which contains grabbed image + RTT::WriteDataPort _image; + /// Command to update the camera properties + RTT::Command _updateImage; + + /// filename + RTT::Property _filename; + /// capturing mode, check dc1394 for values (firewire) + + private: + virtual bool updateImage(); + virtual bool updateImageFinished()const; + + IplImage* _frame; + RgbImage _RgbFrame; + bool _update_image; + + }; +}//namespace + +#endif // LoadImage_HPP + Index: DisplayImageComponent.cpp =================================================================== --- DisplayImageComponent.cpp (.../trunk/ocl/vision) (revision 29988) +++ DisplayImageComponent.cpp (.../branches/ocl-pma/vision) (revision 29988) @@ -1,10 +1,11 @@ /*************************************************************************** - ImageDisplayComponent.cxx - description + DisplayImageComponent.cxx - description ------------------------- begin : Jan 2008 copyright : (C) 2008 Francois Cauwe + (C) 2008 Ruben Smits based on : ReporterComponent.cpp made by Peter Soetens email : francois@cauwe.org @@ -26,35 +27,37 @@ * * ***************************************************************************/ -#include "ImageDisplayComponent.hpp" +#include "DisplayImageComponent.hpp" #include +#include + namespace OCL{ using namespace RTT; - using namespace std; - - - ImageDisplayComponent::ImageDisplayComponent(std::string name): - TaskContext(name), - config("Configuration","The name of the property file which lists which image dataports to be displayed.", - "cpf/imagedisplay.cpf") + using namespace std; + + DisplayImageComponent::DisplayImageComponent(std::string name): + TaskContext(name, PreOperational), + config("Configuration","The name of the property file which lists which image dataports to be displayed.", + "cpf/imagedisplay.cpf") { // add properties properties()->addProperty(&config); // Tell Orocos to load the Vision toolkit - RTT::TypeInfoRepository::Instance()->addType( new IplImageTypeInfo() ); + RTT::TypeInfoRepository::Instance()->addType( new RgbImageTypeInfo() ); + methods()->addMethod( method("displayPort",&DisplayImageComponent::addDisplayPort , this), + "Add a Components port for visualisation. Only works if the component is connected.", + "Component","Name of the component", + "Port","Name of the port"); + } - - bool ImageDisplayComponent::configureHook(){ - Logger::In in("ImageDisplayComponent"); - - // Load config file - if ( this->marshalling()->readProperties( this->getName() + ".cpf" ) == false) - return false; - + + bool DisplayImageComponent::configureHook(){ + Logger::In in("DisplayImageComponent"); + log(Info) << "Loading Ports to display from file." <addDisplayPort(cname, pname); } else { - log(Error) << "Expected \"Component\", \"Port\" or \"Data\", got " + log(Error) << "Expected \"ImagePort\", got " << compName->getName() << endlog(); ok = false; } @@ -85,34 +88,29 @@ deleteProperties( bag ); // Create window for every dataport + cvStartWindowThread(); for(Reports::iterator it = root.begin(); it != root.end(); ++it ) { // Update the dataport (it->get<2>())->execute(); // Get the base dataport DataSourceBase::shared_ptr source = it->get<3>(); - // Convert to Dataport - DataSource::shared_ptr clone = AdaptDataSource()( source.get() ); - IplImage localImage = clone->get(); + // Convert to Dataport + DataSource::shared_ptr clone = AdaptDataSource()( source.get() ); + RgbImage localImage = clone->get(); string dataportName = it->get<0>(); cvNamedWindow(dataportName.data(),CV_WINDOW_AUTOSIZE); - cvShowImage(dataportName.data(),&localImage); + cvShowImage(dataportName.data(),localImage.getPtr()); } - // Enter main loop of the window, and update the window if needed - int key; - key = cvWaitKey(3); - // Magic number 3 - - return ok; } // Exactly the same as th reportPort from the Reporter component - bool ImageDisplayComponent::addDisplayPort(std::string& component, std::string& port) + bool DisplayImageComponent::addDisplayPort(const std::string& component, const std::string& port) { - Logger::In in("ImageDisplayComponent"); + Logger::In in("DisplayImageComponent"); TaskContext* comp = this->getPeer(component); if ( !comp ) { log(Error) << "Could not display Component " << component <<" : no such peer."<connected() ) { this->addDisplaySource( component + "." + port, "Port", porti->connection()->getDataSource() ); - log(Info) << "Reporting port " << port <<" : ok."<antiClone(); assert(ourport); - ConnectionInterface::shared_ptr ci = porti->createConnection( ourport ); - if ( !ci ) - ci = ourport->createConnection( porti ); - if ( !ci ) + if (porti->connectTo(ourport) == false){ + delete ourport; return false; - ci->connect(); - + } + delete ourport; - this->addDisplaySource( component + "." + porti->getName(), "Port", ci->getDataSource() ); + this->addDisplaySource( component + "." + porti->getName(), "Port", porti->connection()->getDataSource() ); log(Info) << "Created connection for port " << porti->getName()<<" : ok."<getTypeName()!="IplImage"){ - log(Error) << "Could not display '"<< tag <<"': This is not a IplImage type, it the Vision tookkit loaded?" << endlog(); + // Check if the type is RgbImage, if this fail + if(orig->getTypeName()!="RgbImage"){ + log(Error) << "Could not display '"<< tag <<"': This is not a RgbImage type, it the Vision Tool Kit loaded?" << endlog(); return false; } DataSourceBase::shared_ptr clone = orig->getTypeInfo()->buildValue(); @@ -179,14 +174,13 @@ return true; } - - bool ImageDisplayComponent::startHook() + bool DisplayImageComponent::startHook() { // Do nothing return true; } - void ImageDisplayComponent::updateHook() + void DisplayImageComponent::updateHook() { // For every dataport for(Reports::iterator it = root.begin(); it != root.end(); ++it ) { @@ -194,40 +188,34 @@ (it->get<2>())->execute(); // Get the base dataport DataSourceBase::shared_ptr source = it->get<3>(); - // Convert to Dataport - DataSource::shared_ptr clone = AdaptDataSource()( source.get() ); - IplImage localImage = clone->get(); + // Convert to Dataport + DataSource::shared_ptr clone = AdaptDataSource()( source.get() ); + RgbImage localImage = clone->get(); string dataportName = it->get<0>(); - cvShowImage(dataportName.data(),&localImage); + cvShowImage(dataportName.data(),localImage.getPtr()); } - // Enter main loop of the window, and update the window if needed - int key; - key = cvWaitKey(3); - // Magic number 3 } - void ImageDisplayComponent::stopHook() + void DisplayImageComponent::stopHook() { // Do nothing } - void ImageDisplayComponent::cleanupHook() + void DisplayImageComponent::cleanupHook() { // Rmove all windows for(Reports::iterator it = root.begin(); it != root.end(); ++it ) { string dataportName = it->get<0>(); cvDestroyWindow(dataportName.data()); - int key; - key = cvWaitKey(3); } // delete all datasource port objects root.clear(); } - ImageDisplayComponent::~ImageDisplayComponent() + DisplayImageComponent::~DisplayImageComponent() { // Do nothing } Index: LoadVideo.hpp =================================================================== --- LoadVideo.hpp (.../trunk/ocl/vision) (revision 0) +++ LoadVideo.hpp (.../branches/ocl-pma/vision) (revision 29988) @@ -0,0 +1,98 @@ +// Copyright (C) 2008 Dominick Vanthienen first.last@student.kuleuven.be +// Thomas Van Dijck +//based on CaptureCamera.cpp made by:Ruben Smits and Francois Cauwe +// +// 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. +// + +#ifndef __LOADVIDEO_HPP__ +#define __LOADVIDEO_HPP__ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "VisionToolkit.hpp" + + +namespace OCL +{ + + /** + * This class implements a TaskContext that grabs + * images from a video file using OpenCV. The component + * can be executed a periodic as well as by a non-periodic + * activity. + * + */ + + class LoadVideo : public RTT::TaskContext + { + + public: + /** + * Creates an unconfigured LoadVideo component. + * + * @param name Name of the component + * + * @return + */ + LoadVideo(std::string name); + virtual ~LoadVideo(); + virtual bool configureHook(); + virtual bool startHook(); + virtual void updateHook(); + virtual void cleanupHook(); + + protected: + /// Dataport which contains grabbed image + RTT::WriteDataPort _image; + /// Dataport which contains grabbing timestamp + RTT::WriteDataPort _capture_time; + /// name of the file to open + RTT::Property _filename; + /// boolean whether to print capturing time information + RTT::Property _show_time; + /// boolean whether to show the captured image in a window + RTT::Property _show_image; + + private: + // virtual bool updateImage(); + // virtual bool updateImageFinished()const; + //virtual bool setFilename(); + //virtual bool setFilenameFinished()const; + + CvCapture* _capture; + RTT::TimeService::ticks _timestamp; + RTT::Seconds _elapsed; + + IplImage* _frame; + RgbImage _RgbFrame; + bool _update; + bool _update_filename; + }; +}//namespace + +#endif // LOADVIDEO_HPP Index: CMakeLists.txt =================================================================== --- CMakeLists.txt (.../trunk/ocl/vision) (revision 0) +++ CMakeLists.txt (.../branches/ocl-pma/vision) (revision 29988) @@ -0,0 +1,27 @@ +OPTION( BUILD_VISIONTOOLKIT "Build TaskBrowser" ON ) +#DEPENDENT_OPTION( BUILD_VISIONTOOLKIT "Build Camera Components" OFF "BUILD_VISIONTOOLKIT;OpenCV_FOUND" OFF) + + +IF ( BUILD_VISIONTOOLKIT ) + +# IF(NOT CURSES AND NOT READLINE) +# MESSAGE( FATAL_ERROR "Can not build TaskBrowser without the +# ncurses/readline library. Try 'sudo apt-get install libncurses5-dev libreadline5-dev' or +# disable the TaskBrowser" ) +# ELSE(NOT CURSES AND NOT READLINE) +# OROCOS_PKGCONFIG_LIBS("-lncurses -lreadline") + + # This gathers all the .cpp files into the variable 'SRCS' + FILE( GLOB HPPS [^.]*.hpp ) + FILE( GLOB SRCS [^.]*.cpp ) + + GLOBAL_ADD_COMPONENT( orocos-vision ${SRCS}) + GLOBAL_ADD_INCLUDE( ocl ${HPPS}) + + COMPONENT_ADD_LIBS( orocos-vision ncurses readline ${OpenCV_LIBRARIES}) + COMPONENT_ADD_DEPS( orocos-vision orocos-ocl-common ) + +# ADD_SUBDIRECTORY( tests ) +# ENDIF(NOT CURSES AND NOT READLINE) + +ENDIF ( BUILD_VISIONTOOLKIT ) Index: WriteImage.cpp =================================================================== --- WriteImage.cpp (.../trunk/ocl/vision) (revision 0) +++ WriteImage.cpp (.../branches/ocl-pma/vision) (revision 29988) @@ -0,0 +1,115 @@ +// Copyright (C) 2008 Thomas Van Dijck +// +// 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. +// + +#include "WriteImage.hpp" +#include + +namespace OCL +{ + using namespace RTT; + using namespace std; + WriteImage::WriteImage(string name): + TaskContext(name, PreOperational), + _image("GrayImage"), + _updateImage("getImage",&WriteImage::updateImage,&WriteImage::updateImageFinished, this), + _update_image(false) + + { + //Adding dataports + //================ + this->ports()->addPort(&_image); + //Adding command + //============== + this->commands()->addCommand( &_updateImage,"Write image from DataPort"); + } + + WriteImage::~WriteImage() + { + //nothing to do + } + + bool WriteImage::configureHook() + { + log(Info) << "(WriteImage) Entering ConfigureHook, testing command next" << endlog(); + _frame_index = 0; + bool configure_result = updateImage(); + log(Info) << "(WriteImage) updateImage succes?? " << configure_result << endlog(); + //_portChanged=_image.setName(_portname.rvalue()); + //configure_result = configure_result && _portChanged; + //log(Info) << "(WriteImage) ConfigureHook succes? " << configure_result << endlog(); + return configure_result; + } + + + bool WriteImage::startHook() + { + log(Info) << "(WriteImage) startHook entered" << endlog(); + return true; + } + + void WriteImage::cleanupHook() + { + // Release frame + cvReleaseImage( &_frame ); + } + + // Update image + bool WriteImage::updateImage() + { + + log(Info) << "(WriteImage) Imagewriter command entered" << endlog(); + _update_image=false; + // Release memory if used + // if(!_frame) + // { + // cvReleaseImage(&_frame); +// } + // write image + log(Info) << "(WriteImage) Grabbing image from port" << endlog(); + _RgbFrame = _image.Get(); + _frame = _RgbFrame.getPtr(); + if(!_frame){ + log(Info) << "(WriteImage) Grabbing image from port failed" << endlog(); + return false; + //cvReleaseImage(&_frame); + } + log(Info) << "(WriteImage) Constructing Filename" << endlog(); + sprintf(filename, "photos/frame%010d.jpg", _frame_index); + log(Info) << "(WriteImage) Saving File" << endlog(); + int write_succes = cvSaveImage(filename, _frame); + log(Info) << "(WriteImage) Saving successfull? " << write_succes <