Go to the documentation of this file.00001
00002
00003
00004
00005
00006
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
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
00123
00124
00125
00126
00127
00128
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 }
00148
00149 PLUGINLIB_EXPORT_CLASS(grid_map::ColorBlendingFilter<grid_map::GridMap>, filters::FilterBase<grid_map::GridMap>)