ColorBlendingFilter.cpp
Go to the documentation of this file.
00001 /*
00002  * ColorBlendingFilter.cpp
00003  *
00004  *  Created on: Sep 14, 2017
00005  *      Author: Peter Fankhauser
00006  *   Institute: ETH Zurich, Robotic Systems Lab
00007  */
00008 
00009 #include <grid_map_filters/ColorBlendingFilter.hpp>
00010 
00011 #include <grid_map_core/grid_map_core.hpp>
00012 #include <pluginlib/class_list_macros.h>
00013 
00014 #include <Eigen/Dense>
00015 #include <math.h>
00016 
00017 using namespace filters;
00018 
00019 namespace grid_map {
00020 
00021 template<typename T>
00022 ColorBlendingFilter<T>::ColorBlendingFilter()
00023     : opacity_(1.0),
00024       blendMode_(BlendModes::Normal)
00025 {
00026 }
00027 
00028 template<typename T>
00029 ColorBlendingFilter<T>::~ColorBlendingFilter()
00030 {
00031 }
00032 
00033 template<typename T>
00034 bool ColorBlendingFilter<T>::configure()
00035 {
00036   if (!FilterBase < T > ::getParam(std::string("background_layer"), backgroundLayer_)) {
00037     ROS_ERROR("Color blending filter did not find parameter `background_layer`.");
00038     return false;
00039   }
00040   ROS_DEBUG("Color blending filter background layer is = %s.", backgroundLayer_.c_str());
00041 
00042   if (!FilterBase < T > ::getParam(std::string("foreground_layer"), foregroundLayer_)) {
00043     ROS_ERROR("Color blending filter did not find parameter `foreground_layer`.");
00044     return false;
00045   }
00046   ROS_DEBUG("Color blending filter foreground layer is = %s.", foregroundLayer_.c_str());
00047 
00048   std::string blendMode;
00049   if (!FilterBase < T > ::getParam(std::string("blend_mode"), blendMode)) {
00050     blendMode = "normal";
00051   }
00052   ROS_DEBUG("Color blending filter blend mode is = %s.", blendMode.c_str());
00053   if (blendMode == "normal") blendMode_ = BlendModes::Normal;
00054   else if (blendMode == "hard_light") blendMode_ = BlendModes::HardLight;
00055   else if (blendMode == "soft_light") blendMode_ = BlendModes::SoftLight;
00056   else {
00057     ROS_ERROR("Color blending filter blend mode `%s` does not exist.", blendMode.c_str());
00058     return false;
00059   }
00060 
00061   if (!FilterBase < T > ::getParam(std::string("opacity"), opacity_)) {
00062     ROS_ERROR("Color blending filter did not find parameter `opacity`.");
00063     return false;
00064   }
00065   ROS_DEBUG("Color blending filter opacity is = %f.", opacity_);
00066 
00067   if (!FilterBase < T > ::getParam(std::string("output_layer"), outputLayer_)) {
00068     ROS_ERROR("Color blending filter did not find parameter `output_layer`.");
00069     return false;
00070   }
00071   ROS_DEBUG("Color blending filter output_layer = %s.", outputLayer_.c_str());
00072   return true;
00073 }
00074 
00075 template<typename T>
00076 bool ColorBlendingFilter<T>::update(const T& mapIn, T& mapOut)
00077 {
00078   const auto& background = mapIn[backgroundLayer_];
00079   const auto& foreground = mapIn[foregroundLayer_];
00080 
00081   mapOut = mapIn;
00082   mapOut.add(outputLayer_);
00083   auto& output = mapOut[outputLayer_];
00084 
00085   // For each cell in map.
00086   for (size_t i = 0; i < output.size(); ++i) {
00087     if (std::isnan(background(i))) {
00088       output(i) = foreground(i);
00089     } else if (std::isnan(foreground(i))) {
00090       output(i) = background(i);
00091     } else {
00092       Eigen::Array3f backgroundColor, foregroundColor, outputColor;
00093       Eigen::Vector3f color;
00094       colorValueToVector(background(i), color);
00095       backgroundColor = color.array();
00096       colorValueToVector(foreground(i), color);
00097       foregroundColor = color.array();
00098 
00099       switch (blendMode_) {
00100         case BlendModes::Normal:
00101           outputColor = (1.0 - opacity_) * backgroundColor + opacity_ * foregroundColor;
00102           break;
00103         case BlendModes::HardLight:
00104         {
00105           Eigen::Array3f blendedColor;
00106           if (foregroundColor.mean() < 0.5) {
00107             blendedColor = 2.0 * backgroundColor * foregroundColor;
00108           } else {
00109             blendedColor = 1.0 - 2.0 * (1.0 - backgroundColor) * (1.0 - foregroundColor);
00110           }
00111           if (opacity_ == 1.0) {
00112             outputColor = blendedColor;
00113           } else {
00114             outputColor = (1.0 - opacity_) * backgroundColor + opacity_ * blendedColor;
00115           }
00116 
00117           break;
00118         }
00119         case BlendModes::SoftLight:
00120         {
00121           Eigen::Array3f blendedColor;
00122           // Photoshop.
00123 //          if (foregroundColor.mean() < 0.5) {
00124 //            blendedColor = 2.0 * backgroundColor * foregroundColor + backgroundColor.square() * (1.0 - 2.0 * foregroundColor);
00125 //          } else {
00126 //            blendedColor = 2.0 * backgroundColor * (1.0 - foregroundColor) + backgroundColor.sqrt() * (2.0 * foregroundColor - 1.0);
00127 //          }
00128           // Pegtop.
00129           blendedColor = ((1.0 - 2.0 * foregroundColor) * backgroundColor.square() + 2.0 * backgroundColor * foregroundColor);
00130           if (opacity_ == 1.0) {
00131             outputColor = blendedColor;
00132           } else {
00133             outputColor = (1.0 - opacity_) * backgroundColor + opacity_ * blendedColor;
00134           }
00135 
00136           break;
00137         }
00138       }
00139 
00140       colorVectorToValue(Eigen::Vector3f(outputColor), output(i));
00141     }
00142   }
00143 
00144   return true;
00145 }
00146 
00147 } /* namespace */
00148 
00149 PLUGINLIB_EXPORT_CLASS(grid_map::ColorBlendingFilter<grid_map::GridMap>, filters::FilterBase<grid_map::GridMap>)


grid_map_filters
Author(s): Péter Fankhauser , Martin Wermelinger
autogenerated on Mon Oct 9 2017 03:09:30