diff --git a/common/include/pcl/common/colors.h b/common/include/pcl/common/colors.h index 0cff5752b9c..419bd97805b 100644 --- a/common/include/pcl/common/colors.h +++ b/common/include/pcl/common/colors.h @@ -39,19 +39,28 @@ #define PCL_COMMON_COLORS_H #include +#include namespace pcl { - struct RGB; - PCL_EXPORTS RGB getRandomColor (double min = 0.2, double max = 2.8); - /** Color lookup table consisting of 256 colors structured in a maximally - * discontinuous manner. Generated using the method of Glasbey et al. - * (see https://github.com/taketwo/glasbey) */ - class PCL_EXPORTS GlasbeyLUT + enum ColorLUTName + { + /** Color lookup table consisting of 256 colors structured in a maximally + * discontinuous manner. Generated using the method of Glasbey et al. + * (see https://github.com/taketwo/glasbey) */ + LUT_GLASBEY, + /** A perceptually uniform colormap created by Stéfan van der Walt and + * Nathaniel Smith for the Python matplotlib library. + * (see https://youtu.be/xAoljeRJ3lU for background and overview) */ + LUT_VIRIDIS, + }; + + template + class ColorLUT { public: @@ -72,6 +81,9 @@ namespace pcl }; + typedef ColorLUT GlasbeyLUT; + typedef ColorLUT ViridisLUT; + } #endif /* PCL_COMMON_COLORS_H */ diff --git a/common/src/colors.cpp b/common/src/colors.cpp index 345b483d2d3..1033bd199ad 100644 --- a/common/src/colors.cpp +++ b/common/src/colors.cpp @@ -38,7 +38,7 @@ #include #include -/// Lookup table +/// Glasbey lookup table static const unsigned char GLASBEY_LUT[] = { 77 , 175, 74 , @@ -299,30 +299,297 @@ static const unsigned char GLASBEY_LUT[] = 117, 143, 207, }; +/// Viridis lookup table +static const unsigned char VIRIDIS_LUT[] = +{ + 68 , 1 , 84 , + 68 , 2 , 85 , + 69 , 3 , 87 , + 69 , 5 , 88 , + 69 , 6 , 90 , + 70 , 8 , 91 , + 70 , 9 , 93 , + 70 , 11 , 94 , + 70 , 12 , 96 , + 71 , 14 , 97 , + 71 , 15 , 98 , + 71 , 17 , 100, + 71 , 18 , 101, + 71 , 20 , 102, + 72 , 21 , 104, + 72 , 22 , 105, + 72 , 24 , 106, + 72 , 25 , 108, + 72 , 26 , 109, + 72 , 28 , 110, + 72 , 29 , 111, + 72 , 30 , 112, + 72 , 32 , 113, + 72 , 33 , 115, + 72 , 34 , 116, + 72 , 36 , 117, + 72 , 37 , 118, + 72 , 38 , 119, + 72 , 39 , 120, + 71 , 41 , 121, + 71 , 42 , 121, + 71 , 43 , 122, + 71 , 44 , 123, + 71 , 46 , 124, + 70 , 47 , 125, + 70 , 48 , 126, + 70 , 49 , 126, + 70 , 51 , 127, + 69 , 52 , 128, + 69 , 53 , 129, + 69 , 54 , 129, + 68 , 56 , 130, + 68 , 57 , 131, + 68 , 58 , 131, + 67 , 59 , 132, + 67 , 60 , 132, + 67 , 62 , 133, + 66 , 63 , 133, + 66 , 64 , 134, + 65 , 65 , 134, + 65 , 66 , 135, + 65 , 67 , 135, + 64 , 69 , 136, + 64 , 70 , 136, + 63 , 71 , 136, + 63 , 72 , 137, + 62 , 73 , 137, + 62 , 74 , 137, + 61 , 75 , 138, + 61 , 77 , 138, + 60 , 78 , 138, + 60 , 79 , 138, + 59 , 80 , 139, + 59 , 81 , 139, + 58 , 82 , 139, + 58 , 83 , 139, + 57 , 84 , 140, + 57 , 85 , 140, + 56 , 86 , 140, + 56 , 87 , 140, + 55 , 88 , 140, + 55 , 89 , 140, + 54 , 91 , 141, + 54 , 92 , 141, + 53 , 93 , 141, + 53 , 94 , 141, + 52 , 95 , 141, + 52 , 96 , 141, + 51 , 97 , 141, + 51 , 98 , 141, + 51 , 99 , 141, + 50 , 100, 142, + 50 , 101, 142, + 49 , 102, 142, + 49 , 103, 142, + 48 , 104, 142, + 48 , 105, 142, + 47 , 106, 142, + 47 , 107, 142, + 47 , 108, 142, + 46 , 109, 142, + 46 , 110, 142, + 45 , 111, 142, + 45 , 112, 142, + 45 , 112, 142, + 44 , 113, 142, + 44 , 114, 142, + 43 , 115, 142, + 43 , 116, 142, + 43 , 117, 142, + 42 , 118, 142, + 42 , 119, 142, + 41 , 120, 142, + 41 , 121, 142, + 41 , 122, 142, + 40 , 123, 142, + 40 , 124, 142, + 40 , 125, 142, + 39 , 126, 142, + 39 , 127, 142, + 38 , 128, 142, + 38 , 129, 142, + 38 , 130, 142, + 37 , 131, 142, + 37 , 131, 142, + 37 , 132, 142, + 36 , 133, 142, + 36 , 134, 142, + 35 , 135, 142, + 35 , 136, 142, + 35 , 137, 142, + 34 , 138, 141, + 34 , 139, 141, + 34 , 140, 141, + 33 , 141, 141, + 33 , 142, 141, + 33 , 143, 141, + 32 , 144, 141, + 32 , 145, 140, + 32 , 146, 140, + 32 , 147, 140, + 31 , 147, 140, + 31 , 148, 140, + 31 , 149, 139, + 31 , 150, 139, + 31 , 151, 139, + 30 , 152, 139, + 30 , 153, 138, + 30 , 154, 138, + 30 , 155, 138, + 30 , 156, 137, + 30 , 157, 137, + 30 , 158, 137, + 30 , 159, 136, + 30 , 160, 136, + 31 , 161, 136, + 31 , 162, 135, + 31 , 163, 135, + 31 , 163, 134, + 32 , 164, 134, + 32 , 165, 134, + 33 , 166, 133, + 33 , 167, 133, + 34 , 168, 132, + 35 , 169, 131, + 35 , 170, 131, + 36 , 171, 130, + 37 , 172, 130, + 38 , 173, 129, + 39 , 174, 129, + 40 , 175, 128, + 41 , 175, 127, + 42 , 176, 127, + 43 , 177, 126, + 44 , 178, 125, + 46 , 179, 124, + 47 , 180, 124, + 48 , 181, 123, + 50 , 182, 122, + 51 , 183, 121, + 53 , 183, 121, + 54 , 184, 120, + 56 , 185, 119, + 57 , 186, 118, + 59 , 187, 117, + 61 , 188, 116, + 62 , 189, 115, + 64 , 190, 114, + 66 , 190, 113, + 68 , 191, 112, + 70 , 192, 111, + 72 , 193, 110, + 73 , 194, 109, + 75 , 194, 108, + 77 , 195, 107, + 79 , 196, 106, + 81 , 197, 105, + 83 , 198, 104, + 85 , 198, 102, + 88 , 199, 101, + 90 , 200, 100, + 92 , 201, 99 , + 94 , 201, 98 , + 96 , 202, 96 , + 98 , 203, 95 , + 101, 204, 94 , + 103, 204, 92 , + 105, 205, 91 , + 108, 206, 90 , + 110, 206, 88 , + 112, 207, 87 , + 115, 208, 85 , + 117, 208, 84 , + 119, 209, 82 , + 122, 210, 81 , + 124, 210, 79 , + 127, 211, 78 , + 129, 212, 76 , + 132, 212, 75 , + 134, 213, 73 , + 137, 213, 72 , + 139, 214, 70 , + 142, 215, 68 , + 144, 215, 67 , + 147, 216, 65 , + 149, 216, 63 , + 152, 217, 62 , + 155, 217, 60 , + 157, 218, 58 , + 160, 218, 57 , + 163, 219, 55 , + 165, 219, 53 , + 168, 220, 51 , + 171, 220, 50 , + 173, 221, 48 , + 176, 221, 46 , + 179, 221, 45 , + 181, 222, 43 , + 184, 222, 41 , + 187, 223, 39 , + 189, 223, 38 , + 192, 223, 36 , + 195, 224, 35 , + 197, 224, 33 , + 200, 225, 32 , + 203, 225, 30 , + 205, 225, 29 , + 208, 226, 28 , + 211, 226, 27 , + 213, 226, 26 , + 216, 227, 25 , + 219, 227, 24 , + 221, 227, 24 , + 224, 228, 24 , + 226, 228, 24 , + 229, 228, 24 , + 232, 229, 25 , + 234, 229, 25 , + 237, 229, 26 , + 239, 230, 27 , + 242, 230, 28 , + 244, 230, 30 , + 247, 230, 31 , + 249, 231, 33 , + 251, 231, 35 , + 254, 231, 36 , +}; + /// Number of colors in Glasbey lookup table static const size_t GLASBEY_LUT_SIZE = sizeof (GLASBEY_LUT) / (sizeof (GLASBEY_LUT[0]) * 3); -pcl::RGB -pcl::GlasbeyLUT::at (size_t color_id) +/// Number of colors in Viridis lookup table +static const size_t VIRIDIS_LUT_SIZE = sizeof (VIRIDIS_LUT) / (sizeof (VIRIDIS_LUT[0]) * 3); + +static const unsigned char* LUTS[] = { GLASBEY_LUT, VIRIDIS_LUT }; +static const size_t LUT_SIZES[] = { GLASBEY_LUT_SIZE, VIRIDIS_LUT_SIZE }; + +template pcl::RGB +pcl::ColorLUT::at (size_t color_id) { - assert (color_id < GLASBEY_LUT_SIZE); + assert (color_id < LUT_SIZES[T]); pcl::RGB color; - color.r = GLASBEY_LUT[color_id * 3 + 0]; - color.g = GLASBEY_LUT[color_id * 3 + 1]; - color.b = GLASBEY_LUT[color_id * 3 + 2]; + color.r = LUTS[T][color_id * 3 + 0]; + color.g = LUTS[T][color_id * 3 + 1]; + color.b = LUTS[T][color_id * 3 + 2]; return (color); } -size_t -pcl::GlasbeyLUT::size () +template size_t +pcl::ColorLUT::size () { - return GLASBEY_LUT_SIZE; + return LUT_SIZES[T]; } -const unsigned char* -pcl::GlasbeyLUT::data () +template const unsigned char* +pcl::ColorLUT::data () { - return GLASBEY_LUT; + return LUTS[T]; } pcl::RGB @@ -346,3 +613,6 @@ pcl::getRandomColor (double min, double max) color.b = uint8_t (b * 255.0); return (color); } + +template class PCL_EXPORTS pcl::ColorLUT; +template class PCL_EXPORTS pcl::ColorLUT; diff --git a/test/common/CMakeLists.txt b/test/common/CMakeLists.txt index 92862e49dff..ade224d4b9b 100644 --- a/test/common/CMakeLists.txt +++ b/test/common/CMakeLists.txt @@ -31,6 +31,7 @@ if (build) PCL_ADD_TEST(common_bearing_angle_image test_bearing_angle_image FILES test_bearing_angle_image.cpp LINK_WITH pcl_gtest pcl_common) PCL_ADD_TEST(common_point_type_conversion test_common_point_type_conversion FILES test_point_type_conversion.cpp LINK_WITH pcl_gtest pcl_common) + PCL_ADD_TEST(common_colors test_colors FILES test_colors.cpp LINK_WITH pcl_gtest pcl_common) if(BUILD_io) PCL_ADD_TEST(common_centroid test_centroid diff --git a/test/common/test_colors.cpp b/test/common/test_colors.cpp new file mode 100644 index 00000000000..e21d89d2fdd --- /dev/null +++ b/test/common/test_colors.cpp @@ -0,0 +1,61 @@ +/* + * Software License Agreement (BSD License) + * + * Point Cloud Library (PCL) - www.pointclouds.org + * Copyright (c) 2018-, Open Perception, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the copyright holder(s) nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include +#include + +TEST (ColorLUT, Glasbey) +{ + ASSERT_EQ (pcl::GlasbeyLUT::size (), 256); + ASSERT_RGB_EQ (pcl::GlasbeyLUT::at (0), pcl::RGB (77, 175, 74)); + ASSERT_RGB_EQ (pcl::GlasbeyLUT::at (255), pcl::RGB (117, 143, 207)); +} + +TEST (ColorLUT, Viridis) +{ + ASSERT_EQ (pcl::ViridisLUT::size (), 256); + ASSERT_RGB_EQ (pcl::ViridisLUT::at (0), pcl::RGB (68, 1, 84)); + ASSERT_RGB_EQ (pcl::ViridisLUT::at (255), pcl::RGB (254, 231, 36)); +} + +int +main (int argc, char** argv) +{ + testing::InitGoogleTest (&argc, argv); + return (RUN_ALL_TESTS ()); +} + diff --git a/visualization/include/pcl/visualization/common/common.h b/visualization/include/pcl/visualization/common/common.h index 0b1a8efda1f..6c69e95322a 100644 --- a/visualization/include/pcl/visualization/common/common.h +++ b/visualization/include/pcl/visualization/common/common.h @@ -131,7 +131,8 @@ namespace pcl PCL_VISUALIZER_LUT_HSV_INVERSE, /**< Inverse HSV colormap */ PCL_VISUALIZER_LUT_GREY, /**< Grey colormap (black to white) */ PCL_VISUALIZER_LUT_BLUE2RED, /**< Blue to red colormap (blue to white to red) */ - PCL_VISUALIZER_LUT_RANGE_AUTO /**< Set LUT range to min and max values of the data */ + PCL_VISUALIZER_LUT_RANGE_AUTO, /**< Set LUT range to min and max values of the data */ + PCL_VISUALIZER_LUT_VIRIDIS /**< Viridis colormap */ }; /** \brief Generate a lookup table for a colormap. diff --git a/visualization/src/common/common.cpp b/visualization/src/common/common.cpp index 556ebd0c8c2..0ef6bd29a58 100644 --- a/visualization/src/common/common.cpp +++ b/visualization/src/common/common.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include ////////////////////////////////////////////////////////////////////////////////////////////// @@ -434,7 +435,23 @@ pcl::visualization::getColormapLUT (LookUpTableRepresentationProperties colormap red[2] * weight + white[2] * (1 - weight) ); } break; - } + } + + case PCL_VISUALIZER_LUT_VIRIDIS: + { + table->SetSaturationRange (1, 1); + table->SetAlphaRange (1, 1); + table->SetNumberOfTableValues (pcl::ViridisLUT::size ()); + for (size_t i = 0; i < pcl::ViridisLUT::size (); i++) + { + pcl::RGB c = pcl::ViridisLUT::at (i); + table->SetTableValue (i, static_cast (c.r) / 255.0, + static_cast (c.g) / 255.0, + static_cast (c.b) / 255.0); + } + break; + } + default: PCL_WARN ("[pcl::visualization::getColormapLUT] Requested colormap type does not exist!\n"); return false;