floodfill_segmentation_alg_node.cpp
Go to the documentation of this file.
00001 #include "floodfill_segmentation_alg_node.h"
00002 
00003 using namespace cv;
00004 
00005 FloodfillSegmentationAlgNode::FloodfillSegmentationAlgNode(void) :
00006   algorithm_base::IriBaseAlgorithm<FloodfillSegmentationAlgorithm>()
00007 {
00008         //init class attributes if necessary
00009         //this->loop_rate_ = 2;//in [Hz]
00010 
00011         // [init publishers]
00012         this->image_out_publisher_ = this->public_node_handle_.advertise<sensor_msgs::Image>("image_out", 1);
00013         
00014         // [init subscribers]
00015         this->image_in_subscriber_ = this->public_node_handle_.subscribe("image_in", 1, &FloodfillSegmentationAlgNode::image_in_callback, this);
00016         
00017         // [init services]
00018         
00019         // [init clients]
00020         
00021         // [init action servers]
00022         
00023         // [init action clients]
00024         
00025 }
00026 
00027 FloodfillSegmentationAlgNode::~FloodfillSegmentationAlgNode(void)
00028 {
00029         // [free dynamic memory]
00030 }
00031 
00032 void FloodfillSegmentationAlgNode::mainNodeThread(void)
00033 {
00034         // [fill msg structures]
00035         //this->Image_msg_.data = my_var;
00036         
00037         // [fill srv structure and make request to the server]
00038         
00039         // [fill action structure and make request to the action server]
00040         
00041         // [publish messages]
00042         //this->image_out_publisher_.publish(this->Image_msg_);
00043 }
00044 
00045 /*  [subscriber callbacks] */
00046 void FloodfillSegmentationAlgNode::image_in_callback(const sensor_msgs::Image::ConstPtr& msg) 
00047 { 
00048         cv_bridge::CvImagePtr cv_ptr;
00049         
00050         try
00051         {
00052                 cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
00053         }
00054         catch (cv_bridge::Exception& e)
00055         {
00056                 ROS_ERROR("cv_bridge exception: %s", e.what());
00057                 return;
00058         }
00059         
00060         cv_ptr->image = floodfillRemoval(cv_ptr->image);
00061         
00062         ROS_DEBUG_STREAM("Publishing floodfill");
00063         
00064         this->image_out_publisher_.publish(cv_ptr->toImageMsg());
00065         
00066         //use appropiate mutex to shared variables if necessary 
00067         //this->alg_.lock(); 
00068         //this->image_in_mutex_.enter(); 
00069 
00070         //std::cout << msg->data << std::endl; 
00071 
00072         //unlock previously blocked shared variables 
00073         //this->alg_.unlock(); 
00074         //this->image_in_mutex_.exit(); 
00075 }
00076 
00077 /*  [service callbacks] */
00078 
00079 /*  [action callbacks] */
00080 
00081 /*  [action requests] */
00082 
00083 /* Other */ 
00084 cv::Mat FloodfillSegmentationAlgNode::floodfillRemoval(cv::Mat image)
00085 {
00086         // WARNING Mask is bigger than image!!!!!!
00087         Mat dst, newMask, image_lab;
00088         int connectivity = 4;
00089         int newMaskVal = 0;
00090         int flags = connectivity + (newMaskVal << 8);
00091         Rect ccomp;
00092         int area = 0;
00093         int areaThreshold = floodfill_min_area;
00094         int x, y;
00095         int maxSeedSearchTries = 20;
00096         Vec3b ignoredColor;
00097         Scalar newVal;
00098         Scalar ffthresh;
00099         
00100         Point seed;
00101         //mask.create(image.rows+2, image.cols+2, CV_8UC1);
00102         
00103         if (colorspace_lab) {
00104                 cvtColor(image, image, CV_BGR2Lab);
00105                 ffthresh = Scalar(floodfill_threshold*3, floodfill_threshold, floodfill_threshold);
00106                 ignoredColor = Vec3b(0,128,128); // black in l*a*b*
00107                 newVal = Scalar(0,128,128); // black in l*a*b*
00108         }
00109         else { // BGR8
00110                 ffthresh = Scalar(floodfill_threshold, floodfill_threshold, floodfill_threshold);
00111                 ignoredColor = Vec3b(0,0,0); // black in BGR
00112                 newVal = Scalar(0,0,0); // black in BGR
00113         }
00114         
00115         Vec3b color;
00116         for (int i = 0; i < floodfill_seed_num; i++) {
00117                 // Find a non-black seed
00118                 int iter_num = 0;
00119                 do {
00120                         x = floor(theRNG().next() % image.rows);
00121                         y = floor(theRNG().next() % image.cols);
00122                         seed = Point(y,x);
00123                         color = image.at<cv::Vec3b>(x,y);
00124                 } while ((image.at<cv::Vec3b>(x,y) == ignoredColor) && (iter_num++ < maxSeedSearchTries));
00125                 
00126                 if (image.at<cv::Vec3b>(x,y) != ignoredColor) { // if found a non-black seed
00127                         newMask = Scalar::all(0);
00128                         dst = image.clone();
00129                         area = floodFill(dst, newMask, seed, newVal, 0, ffthresh, ffthresh, flags);
00130                         ROS_DEBUG_STREAM("Area removed "<<area);
00131                         if (area > areaThreshold)
00132                                 image = dst;
00133                 }
00134         }
00135         
00136         if (colorspace_lab)
00137                 cvtColor(image, image, CV_Lab2BGR);
00138         
00139         threshold( image, image, 10, 255, THRESH_BINARY );
00140         return image;
00141 }
00142 
00143 void FloodfillSegmentationAlgNode::node_config_update(Config &config, uint32_t level)
00144 {
00145         this->alg_.lock();
00146         
00147         this->floodfill_threshold = config.floodfill_threshold;
00148         this->floodfill_min_area  = config.floodfill_min_area;
00149         this->floodfill_seed_num  = config.floodfill_seed_num;
00150         this->colorspace_lab      = config.colorspace_lab;
00151         
00152         // save the current configuration
00153         this->alg_.config_=config;
00154         
00155         this->alg_.unlock();
00156 }
00157 
00158 void FloodfillSegmentationAlgNode::addNodeDiagnostics(void)
00159 {
00160 }
00161 
00162 /* main function */
00163 int main(int argc,char *argv[])
00164 {
00165         return algorithm_base::main<FloodfillSegmentationAlgNode>(argc, argv, "floodfill_segmentation_alg_node");
00166 }


iri_opencv_filters
Author(s): David Martinez
autogenerated on Fri Dec 6 2013 22:43:25