00001 #include "floodfill_segmentation_alg_node.h"
00002
00003 using namespace cv;
00004
00005 FloodfillSegmentationAlgNode::FloodfillSegmentationAlgNode(void) :
00006 algorithm_base::IriBaseAlgorithm<FloodfillSegmentationAlgorithm>()
00007 {
00008
00009
00010
00011
00012 this->image_out_publisher_ = this->public_node_handle_.advertise<sensor_msgs::Image>("image_out", 1);
00013
00014
00015 this->image_in_subscriber_ = this->public_node_handle_.subscribe("image_in", 1, &FloodfillSegmentationAlgNode::image_in_callback, this);
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 }
00026
00027 FloodfillSegmentationAlgNode::~FloodfillSegmentationAlgNode(void)
00028 {
00029
00030 }
00031
00032 void FloodfillSegmentationAlgNode::mainNodeThread(void)
00033 {
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 }
00044
00045
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
00067
00068
00069
00070
00071
00072
00073
00074
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084 cv::Mat FloodfillSegmentationAlgNode::floodfillRemoval(cv::Mat image)
00085 {
00086
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
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);
00107 newVal = Scalar(0,128,128);
00108 }
00109 else {
00110 ffthresh = Scalar(floodfill_threshold, floodfill_threshold, floodfill_threshold);
00111 ignoredColor = Vec3b(0,0,0);
00112 newVal = Scalar(0,0,0);
00113 }
00114
00115 Vec3b color;
00116 for (int i = 0; i < floodfill_seed_num; i++) {
00117
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) {
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
00153 this->alg_.config_=config;
00154
00155 this->alg_.unlock();
00156 }
00157
00158 void FloodfillSegmentationAlgNode::addNodeDiagnostics(void)
00159 {
00160 }
00161
00162
00163 int main(int argc,char *argv[])
00164 {
00165 return algorithm_base::main<FloodfillSegmentationAlgNode>(argc, argv, "floodfill_segmentation_alg_node");
00166 }