morphological_op_alg_node.cpp
Go to the documentation of this file.
00001 #include "morphological_op_alg_node.h"
00002 
00003 using namespace cv;
00004 
00005 MorphologicalOpAlgNode::MorphologicalOpAlgNode(void) :
00006   algorithm_base::IriBaseAlgorithm<MorphologicalOpAlgorithm>()
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, &MorphologicalOpAlgNode::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 MorphologicalOpAlgNode::~MorphologicalOpAlgNode(void)
00027 {
00028   // [free dynamic memory]
00029 }
00030 
00031 void MorphologicalOpAlgNode::mainNodeThread(void)
00032 {
00033   // [fill msg structures]
00034   //this->Image_msg_.data = my_var;
00035   
00036   // [fill srv structure and make request to the server]
00037   
00038   // [fill action structure and make request to the action server]
00039 
00040   // [publish messages]
00041   //this->image_out_publisher_.publish(this->Image_msg_);
00042 }
00043 
00044 /*  [subscriber callbacks] */
00045 void MorphologicalOpAlgNode::image_in_callback(const sensor_msgs::Image::ConstPtr& msg) 
00046 { 
00047         cv_bridge::CvImagePtr cv_ptr;
00048         
00049         try
00050         {
00051                 cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
00052         }
00053         catch (cv_bridge::Exception& e)
00054         {
00055                 ROS_ERROR("cv_bridge exception: %s", e.what());
00056                 return;
00057         }
00058         
00059         cv_ptr->image = processImage(cv_ptr->image);
00060         
00061         ROS_DEBUG("Publishing morphological operation");
00062         this->image_out_publisher_.publish(cv_ptr->toImageMsg());
00063 
00064   //use appropiate mutex to shared variables if necessary 
00065   //this->alg_.lock(); 
00066   //this->image_in_mutex_.enter(); 
00067 
00068   //std::cout << msg->data << std::endl; 
00069 
00070   //unlock previously blocked shared variables 
00071   //this->alg_.unlock(); 
00072   //this->image_in_mutex_.exit(); 
00073 }
00074 
00075 /*  [service callbacks] */
00076 
00077 /*  [action callbacks] */
00078 
00079 /*  [action requests] */
00080 
00081 /* Other */
00082 cv::Mat MorphologicalOpAlgNode::processImage(cv::Mat image)
00083 {
00084         cv::Mat dst;
00085         cv::Mat element;
00086         //cvtColor(image, image, CV_BGR2Lab);
00087         if (!structuring_element_shape.compare("ellipse"))
00088                 element = cv::getStructuringElement(MORPH_ELLIPSE, cv::Size(morph_element_size, morph_element_size));
00089         else if (!structuring_element_shape.compare("rect"))
00090                 element = cv::getStructuringElement(MORPH_RECT, cv::Size(morph_element_size, morph_element_size));
00091         else if (!structuring_element_shape.compare("cross"))
00092                 element = cv::getStructuringElement(MORPH_CROSS, cv::Size(morph_element_size, morph_element_size));
00093         else {
00094                 ROS_WARN("Morphological element shape not recognized");
00095                 return image;
00096         }
00097         
00098         if (!morph_operation.compare("open")) {
00099                 cv::morphologyEx(image, dst, cv::MORPH_OPEN, element);
00100         }
00101         else if (!morph_operation.compare("close")){
00102                 cv::morphologyEx(image, dst, cv::MORPH_CLOSE, element);
00103         }
00104         else if (!morph_operation.compare("gradient")) {
00105                 cv::morphologyEx(image, dst, cv::MORPH_GRADIENT, element, Point(-1,-1), 1);
00106         }
00107         else if (!morph_operation.compare("tophat")) {
00108                 cv::medianBlur(image, image, 5);
00109                 cv::morphologyEx(image, dst, cv::MORPH_TOPHAT, element);
00110         }
00111         else if (!morph_operation.compare("blackhat")) {
00112                 cv::morphologyEx(image, dst, cv::MORPH_BLACKHAT, element, Point(-1,-1), 1);
00113         }
00114         else if (!morph_operation.compare("addgradient")) {
00115                 dst = add_gradient_to_image(image, element);
00116         }
00117         else if (!morph_operation.compare("addblackhat")) {
00118                 cv::morphologyEx(image, dst, cv::MORPH_BLACKHAT, element);
00119                 //threshold(dst, dst, 13, 50, THRESH_BINARY);
00120                 subtract(dst, morph_val_reduction, dst);
00121                 subtract(image, dst, dst);
00122         }
00123         else if (!morph_operation.compare("dilate")) {
00124                 cv::dilate(image, dst, element);
00125         }
00126         else if (!morph_operation.compare("erode")) {
00127                 cv::erode(image, dst, element);
00128         }
00129         else {
00130                 ROS_WARN("Morphological operation not recognized");
00131                 return image;
00132         }
00133         
00134         //cvtColor(dst, dst, CV_Lab2BGR);
00135         return dst;
00136 }
00137 
00138 
00139 cv::Mat MorphologicalOpAlgNode::add_gradient_to_image(cv::Mat image, cv::Mat element)
00140 {
00141         Mat dst;
00142         Mat src_gray, threshold_output, drawing;
00143         vector<vector<Point> > contours;
00144         vector<Vec4i> hierarchy;
00145         int thresh = 10;
00146         
00147         cv::morphologyEx(image, dst, cv::MORPH_GRADIENT, element, Point(-1,-1), 1);
00148         
00152         cvtColor( dst, src_gray, CV_BGR2GRAY );
00153         blur( src_gray, src_gray, Size(3,3) );
00154         
00156         threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
00157 
00159         findContours( threshold_output, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
00160 
00162         vector<vector<Point> >hull( contours.size() );
00163         for( size_t i = 0; i < contours.size(); i++ ) {
00164                 convexHull( Mat(contours[i]), hull[i], false );
00165         }
00166         
00168         drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
00169         for( size_t i = 0; i< contours.size(); i++ )
00170         { 
00171                 Scalar color = Scalar( 255, 255, 255 );
00172                 drawContours( drawing, hull, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
00173         }
00174         dilate(drawing, drawing, Mat::ones(morph_element_size * 2 + 1, morph_element_size * 2 + 1, 1));
00175         subtract(dst, drawing, dst);
00176         
00181         //threshold(dst, dst, morph_val_reduction, 50, THRESH_BINARY);
00182         subtract(dst, morph_val_reduction, dst);
00183         
00184         subtract(image, dst, dst);
00185         
00186         return dst;
00187 }
00188 
00189 
00190 void MorphologicalOpAlgNode::node_config_update(Config &config, uint32_t level)
00191 {
00192   this->alg_.lock();
00193   
00194   this->morph_element_size = config.morph_element_size;
00195   this->morph_operation = config.morph_operation;
00196   this->morph_val_reduction = config.morph_val_reduction;
00197   this->structuring_element_shape = config.structuring_element_shape;
00198 
00199   // save the current configuration
00200   //this->alg_.config_=config;
00201 
00202   this->alg_.unlock();
00203 }
00204 
00205 void MorphologicalOpAlgNode::addNodeDiagnostics(void)
00206 {
00207 }
00208 
00209 /* main function */
00210 int main(int argc,char *argv[])
00211 {
00212   return algorithm_base::main<MorphologicalOpAlgNode>(argc, argv, "morphological_op_alg_node");
00213 }


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