Add functionality for IO images, and conversion for depth and semseg
This commit is contained in:
parent
23499b41bb
commit
2326345f9e
|
@ -8,7 +8,7 @@ Install the build tools and dependencies
|
|||
```
|
||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
|
||||
sudo apt-get update
|
||||
sudo apt-get install build-essential clang-5.0 lld-5.0 g++-7 ninja-build python python-pip python-dev tzdata sed curl wget unzip autoconf libtool
|
||||
sudo apt-get install build-essential clang-5.0 lld-5.0 g++-7 ninja-build python python-pip python-dev libpng-dev tzdata sed curl wget unzip autoconf libtool
|
||||
pip install --user setuptools nose2
|
||||
```
|
||||
|
||||
|
|
|
@ -33,6 +33,12 @@ file(GLOB libcarla_carla_geom_sources
|
|||
set(libcarla_sources "${libcarla_sources};${libcarla_carla_geom_sources}")
|
||||
install(FILES ${libcarla_carla_geom_sources} DESTINATION include/carla/geom)
|
||||
|
||||
file(GLOB libcarla_carla_image_sources
|
||||
"${libcarla_source_path}/carla/image/*.cpp"
|
||||
"${libcarla_source_path}/carla/image/*.h")
|
||||
set(libcarla_sources "${libcarla_sources};${libcarla_carla_image_sources}")
|
||||
install(FILES ${libcarla_carla_image_sources} DESTINATION include/carla/image)
|
||||
|
||||
file(GLOB libcarla_carla_opendrive_sources
|
||||
"${libcarla_source_path}/carla/opendrive/*.cpp"
|
||||
"${libcarla_source_path}/carla/opendrive/*.h")
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wc++11-narrowing"
|
||||
# pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
# pragma clang diagnostic ignored "-Wunused-local-typedef"
|
||||
#endif
|
||||
|
||||
#include <boost/gil/gil_all.hpp>
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace carla {
|
||||
namespace image {
|
||||
namespace detail {
|
||||
|
||||
static constexpr
|
||||
#if __cplusplus >= 201703L // C++17
|
||||
inline
|
||||
#endif
|
||||
uint8_t CITYSCAPES_PALETTE_MAP[][3u] = {
|
||||
{ 0u, 0u, 0u}, // unlabeled = 0u,
|
||||
{ 70u, 70u, 70u}, // building = 1u,
|
||||
{190u, 153u, 153u}, // fence = 2u,
|
||||
{250u, 170u, 160u}, // other = 3u,
|
||||
{220u, 20u, 60u}, // pedestrian = 4u,
|
||||
{153u, 153u, 153u}, // pole = 5u,
|
||||
{153u, 153u, 153u}, // road line = 6u,
|
||||
{128u, 64u, 128u}, // road = 7u,
|
||||
{244u, 35u, 232u}, // sidewalk = 8u,
|
||||
{107u, 142u, 35u}, // vegetation = 9u,
|
||||
{ 0u, 0u, 142u}, // car = 10u,
|
||||
{102u, 102u, 156u}, // wall = 11u,
|
||||
{220u, 220u, 0u}, // traffic sign = 12u,
|
||||
// { 0u, 0u, 70u}, // truck
|
||||
// { 0u, 0u, 90u}, // caravan
|
||||
// { 0u, 0u, 110u}, // trailer
|
||||
// { 0u, 0u, 142u}, // license plate
|
||||
// { 0u, 0u, 230u}, // motorcycle
|
||||
// { 0u, 60u, 100u}, // bus
|
||||
// { 0u, 80u, 100u}, // train
|
||||
// { 70u, 130u, 180u}, // sky
|
||||
// { 81u, 0u, 81u}, // ground
|
||||
// {111u, 74u, 0u}, // dynamic
|
||||
// {119u, 11u, 32u}, // bicycle
|
||||
// {150u, 100u, 100u}, // bridge
|
||||
// {150u, 120u, 90u}, // tunnel
|
||||
// {152u, 251u, 152u}, // terrain
|
||||
// {153u, 153u, 153u}, // polegroup
|
||||
// {180u, 165u, 180u}, // guard rail
|
||||
// {230u, 150u, 140u}, // rail track
|
||||
// {250u, 170u, 30u}, // traffic light
|
||||
// {250u, 170u, 160u}, // parking
|
||||
// {255u, 0u, 0u}, // rider
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class CityScapesPalette {
|
||||
public:
|
||||
|
||||
static constexpr auto GetNumberOfTags() {
|
||||
return sizeof(detail::CITYSCAPES_PALETTE_MAP) /
|
||||
sizeof(*detail::CITYSCAPES_PALETTE_MAP);
|
||||
}
|
||||
|
||||
/// Return an RGB uint8_t array.
|
||||
///
|
||||
/// @warning It overflows if @a tag is greater than GetNumberOfTags().
|
||||
static constexpr auto GetColor(uint8_t tag) {
|
||||
return detail::CITYSCAPES_PALETTE_MAP[tag % GetNumberOfTags()];
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace image
|
||||
} // namespace carla
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "carla/image/BoostGil.h"
|
||||
#include "carla/image/CityScapesPalette.h"
|
||||
|
||||
namespace carla {
|
||||
namespace image {
|
||||
|
||||
class ColorConverter {
|
||||
public:
|
||||
|
||||
struct LogarithmicLinear {
|
||||
template <typename DstPixelT>
|
||||
void operator()(const boost::gil::gray32fc_pixel_t &src, DstPixelT &dst) const {
|
||||
using namespace boost::gil;
|
||||
const float value = 1.0f + std::log(src[0u]) / 5.70378f;
|
||||
const float clamped = std::max(std::min(value, 1.0f), 0.0f);
|
||||
color_convert(gray32fc_pixel_t{clamped}, dst);
|
||||
}
|
||||
};
|
||||
|
||||
struct Depth {
|
||||
template <typename SrcPixelT, typename DstPixelT>
|
||||
void operator()(const SrcPixelT &src, DstPixelT &dst) const {
|
||||
using namespace boost::gil;
|
||||
static_assert(
|
||||
sizeof(typename color_space_type<SrcPixelT>::type) == sizeof(uint8_t),
|
||||
"Invalid pixel type.");
|
||||
const float depth =
|
||||
get_color(src, red_t()) +
|
||||
(get_color(src, green_t()) * 256) +
|
||||
(get_color(src, blue_t()) * 256 * 256);
|
||||
const float normalized = depth / static_cast<float>(256 * 256 * 256 - 1);
|
||||
color_convert(gray32fc_pixel_t{normalized}, dst);
|
||||
}
|
||||
};
|
||||
|
||||
struct LogarithmicDepth {};
|
||||
|
||||
struct CityScapesPalette {
|
||||
template <typename SrcPixelT, typename DstPixelT>
|
||||
void operator()(const SrcPixelT &src, DstPixelT &dst) const {
|
||||
using namespace boost::gil;
|
||||
static_assert(
|
||||
sizeof(typename color_space_type<SrcPixelT>::type) == sizeof(uint8_t),
|
||||
"Invalid pixel type.");
|
||||
const auto color = image::CityScapesPalette::GetColor(get_color(src, red_t()));
|
||||
color_convert(rgb8c_pixel_t{color[0u], color[1u], color[2u]}, dst);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace image
|
||||
} // namespace carla
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "carla/image/ImageView.h"
|
||||
|
||||
namespace carla {
|
||||
namespace image {
|
||||
|
||||
class ImageConverter {
|
||||
public:
|
||||
|
||||
template <typename SrcViewT, typename DstViewT>
|
||||
static void CopyPixels(const SrcViewT &src, DstViewT &dst) {
|
||||
boost::gil::copy_pixels(src, dst);
|
||||
}
|
||||
|
||||
template <typename ColorConverter, typename MutableImageView>
|
||||
static void ConvertInPlace(
|
||||
MutableImageView &image_view,
|
||||
ColorConverter converter = ColorConverter()) {
|
||||
using DstPixelT = typename MutableImageView::value_type;
|
||||
CopyPixels(
|
||||
ImageView::MakeColorConvertedView<MutableImageView, DstPixelT>(image_view, converter),
|
||||
image_view);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace image
|
||||
} // namespace carla
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "carla/image/ImageIOConfig.h"
|
||||
|
||||
namespace carla {
|
||||
namespace image {
|
||||
|
||||
class ImageIO {
|
||||
public:
|
||||
|
||||
using io_default = io::png;
|
||||
|
||||
static_assert(io_default::is_supported, "Default format not supported!");
|
||||
|
||||
template <typename Str, typename ImageT, typename IO = io_default>
|
||||
static void ReadImage(Str &&in_filename, ImageT &image, IO = IO()) {
|
||||
IO::read_image(std::forward<Str>(in_filename), image);
|
||||
}
|
||||
|
||||
template <typename Str, typename ViewT, typename IO = io_default>
|
||||
static void WriteView(Str &&out_filename, const ViewT &image_view, IO = IO()) {
|
||||
IO::write_view(std::forward<Str>(out_filename), image_view);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace image
|
||||
} // namespace carla
|
|
@ -0,0 +1,170 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "carla/image/BoostGil.h"
|
||||
|
||||
#ifndef LIBCARLA_IMAGE_WITH_PNG_SUPPORT
|
||||
# if defined(__has_include) && __has_include("png.h")
|
||||
# define LIBCARLA_IMAGE_WITH_PNG_SUPPORT true
|
||||
# else
|
||||
# define LIBCARLA_IMAGE_WITH_PNG_SUPPORT false
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef LIBCARLA_IMAGE_WITH_JPEG_SUPPORT
|
||||
# if defined(__has_include) && __has_include("jpeglib.h")
|
||||
# define LIBCARLA_IMAGE_WITH_JPEG_SUPPORT true
|
||||
# else
|
||||
# define LIBCARLA_IMAGE_WITH_JPEG_SUPPORT false
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef LIBCARLA_IMAGE_WITH_TIFF_SUPPORT
|
||||
# if defined(__has_include) && __has_include("tiffio.h")
|
||||
# define LIBCARLA_IMAGE_WITH_TIFF_SUPPORT true
|
||||
# else
|
||||
# define LIBCARLA_IMAGE_WITH_TIFF_SUPPORT false
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
#endif
|
||||
|
||||
#if LIBCARLA_IMAGE_WITH_PNG_SUPPORT == true
|
||||
# ifndef png_infopp_NULL
|
||||
# define png_infopp_NULL (png_infopp)NULL
|
||||
# endif // png_infopp_NULL
|
||||
# ifndef int_p_NULL
|
||||
# define int_p_NULL (int*)NULL
|
||||
# endif // int_p_NULL
|
||||
# include <boost/gil/extension/io/png_io.hpp>
|
||||
#endif
|
||||
|
||||
#if LIBCARLA_IMAGE_WITH_JPEG_SUPPORT == true
|
||||
# include <boost/gil/extension/io/jpeg_io.hpp>
|
||||
#endif
|
||||
|
||||
#if LIBCARLA_IMAGE_WITH_TIFF_SUPPORT == true
|
||||
# include <boost/gil/extension/io/tiff_io.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
namespace carla {
|
||||
namespace image {
|
||||
namespace io {
|
||||
|
||||
constexpr bool has_png_support() {
|
||||
return LIBCARLA_IMAGE_WITH_PNG_SUPPORT;
|
||||
}
|
||||
|
||||
constexpr bool has_jpeg_support() {
|
||||
return LIBCARLA_IMAGE_WITH_JPEG_SUPPORT;
|
||||
}
|
||||
|
||||
constexpr bool has_tiff_support() {
|
||||
return LIBCARLA_IMAGE_WITH_TIFF_SUPPORT;
|
||||
}
|
||||
|
||||
static_assert(has_png_support() || has_jpeg_support() || has_tiff_support(),
|
||||
"No image format supported, please compile with at least one of "
|
||||
"LIBCARLA_IMAGE_WITH_PNG_SUPPORT, LIBCARLA_IMAGE_WITH_JPEG_SUPPORT, "
|
||||
"or LIBCARLA_IMAGE_WITH_TIFF_SUPPORT");
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct jpeg_reader {
|
||||
#if LIBCARLA_IMAGE_WITH_JPEG_SUPPORT
|
||||
template <typename Str, typename IMAGE>
|
||||
static void read_image(Str &&in_filename, IMAGE &image) {
|
||||
static_assert(has_jpeg_support(), "JPEG not supported");
|
||||
boost::gil::jpeg_read_image(std::forward<Str>(in_filename), image);
|
||||
}
|
||||
#endif // LIBCARLA_IMAGE_WITH_JPEG_SUPPORT
|
||||
};
|
||||
|
||||
struct jpeg_writer {
|
||||
#if LIBCARLA_IMAGE_WITH_JPEG_SUPPORT
|
||||
template <typename Str, typename VIEW>
|
||||
static void write_view(Str &&out_filename, const VIEW &view) {
|
||||
static_assert(has_jpeg_support(), "JPEG not supported");
|
||||
boost::gil::jpeg_write_view(std::forward<Str>(out_filename), view);
|
||||
}
|
||||
#endif // LIBCARLA_IMAGE_WITH_JPEG_SUPPORT
|
||||
};
|
||||
|
||||
struct png_reader {
|
||||
#if LIBCARLA_IMAGE_WITH_PNG_SUPPORT
|
||||
template <typename Str, typename IMAGE>
|
||||
static void read_image(Str &&in_filename, IMAGE &image) {
|
||||
static_assert(has_png_support(), "PNG not supported");
|
||||
boost::gil::png_read_and_convert_image(std::forward<Str>(in_filename), image);
|
||||
}
|
||||
#endif // LIBCARLA_IMAGE_WITH_PNG_SUPPORT
|
||||
};
|
||||
|
||||
struct png_writer {
|
||||
#if LIBCARLA_IMAGE_WITH_PNG_SUPPORT
|
||||
template <typename Str, typename VIEW>
|
||||
static void write_view(Str &&out_filename, const VIEW &view) {
|
||||
static_assert(has_png_support(), "PNG not supported");
|
||||
boost::gil::png_write_view(std::forward<Str>(out_filename), view);
|
||||
}
|
||||
#endif // LIBCARLA_IMAGE_WITH_PNG_SUPPORT
|
||||
};
|
||||
|
||||
struct tiff_reader {
|
||||
#if LIBCARLA_IMAGE_WITH_TIFF_SUPPORT
|
||||
template <typename Str, typename IMAGE>
|
||||
static void read_image(Str &&in_filename, IMAGE &image) {
|
||||
static_assert(has_tiff_support(), "TIFF not supported");
|
||||
boost::gil::tiff_read_and_convert_image(std::forward<Str>(in_filename), image);
|
||||
}
|
||||
#endif // LIBCARLA_IMAGE_WITH_TIFF_SUPPORT
|
||||
};
|
||||
|
||||
struct tiff_writer {
|
||||
#if LIBCARLA_IMAGE_WITH_TIFF_SUPPORT
|
||||
template <typename Str, typename VIEW>
|
||||
static void write_view(Str &&out_filename, const VIEW &view) {
|
||||
static_assert(has_tiff_support(), "TIFF not supported");
|
||||
boost::gil::tiff_write_view(std::forward<Str>(out_filename), view);
|
||||
}
|
||||
#endif // LIBCARLA_IMAGE_WITH_TIFF_SUPPORT
|
||||
};
|
||||
|
||||
template <bool IS_SUPPORTED, typename READER, typename WRITER>
|
||||
struct image_io;
|
||||
|
||||
template <typename READER, typename WRITER>
|
||||
struct image_io<false, READER, WRITER> {
|
||||
constexpr static bool is_supported = false;
|
||||
};
|
||||
|
||||
template <typename READER, typename WRITER>
|
||||
struct image_io<true, READER, WRITER> {
|
||||
constexpr static bool is_supported = true;
|
||||
using reader_type = READER;
|
||||
using writer_type = WRITER;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
struct jpeg : public detail::image_io<has_jpeg_support(), detail::jpeg_reader, detail::jpeg_writer> {};
|
||||
|
||||
struct png : public detail::image_io<has_png_support(), detail::png_reader, detail::png_writer> {};
|
||||
|
||||
struct tiff : public detail::image_io<has_tiff_support(), detail::tiff_reader, detail::tiff_writer> {};
|
||||
|
||||
} // namespace io
|
||||
} // namespace image
|
||||
} // namespace carla
|
|
@ -0,0 +1,98 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "carla/image/BoostGil.h"
|
||||
#include "carla/image/ColorConverter.h"
|
||||
#include "carla/sensor/data/Color.h"
|
||||
#include "carla/sensor/data/ImageTmpl.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace carla {
|
||||
namespace image {
|
||||
|
||||
class ImageView {
|
||||
private:
|
||||
public:
|
||||
|
||||
template <typename SrcViewT>
|
||||
using GrayPixelLayout = boost::gil::pixel<typename boost::gil::channel_type<SrcViewT>::type, boost::gil::gray_layout_t>;
|
||||
|
||||
template <typename DstPixelT, typename ImageT>
|
||||
static auto MakeViewFromSensorImage(ImageT &image) {
|
||||
using namespace boost::gil;
|
||||
namespace sd = carla::sensor::data;
|
||||
static_assert(
|
||||
std::is_same<typename ImageT::pixel_type, sd::Color>::value,
|
||||
"Invalid pixel type");
|
||||
static_assert(
|
||||
sizeof(sd::Color) == sizeof(DstPixelT),
|
||||
"Invalid pixel size");
|
||||
return interleaved_view(
|
||||
image.GetWidth(),
|
||||
image.GetHeight(),
|
||||
reinterpret_cast<DstPixelT*>(image.data()),
|
||||
sizeof(sd::Color) * image.GetWidth()); // row length in bytes.
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
template <typename ImageT>
|
||||
static auto MakeView(ImageT &image) {
|
||||
return boost::gil::view(image);
|
||||
}
|
||||
|
||||
static auto MakeView(sensor::data::ImageTmpl<sensor::data::Color> &image) {
|
||||
return MakeViewFromSensorImage<boost::gil::bgra8_pixel_t>(image);
|
||||
}
|
||||
|
||||
static auto MakeView(const sensor::data::ImageTmpl<sensor::data::Color> &image) {
|
||||
return MakeViewFromSensorImage<boost::gil::bgra8c_pixel_t>(image);
|
||||
}
|
||||
|
||||
template <typename SrcViewT, typename DstPixelT, typename CC>
|
||||
static auto MakeColorConvertedView(const SrcViewT &src, CC cc) {
|
||||
return _MakeColorConvertedView<DstPixelT>(src, cc);
|
||||
}
|
||||
|
||||
template <typename SrcViewT, typename DstPixelT = GrayPixelLayout<SrcViewT>>
|
||||
static auto MakeColorConvertedView(const SrcViewT &src, ColorConverter::Depth cc) {
|
||||
return _MakeColorConvertedView<DstPixelT>(src, cc);
|
||||
}
|
||||
|
||||
template <typename SrcViewT, typename DstPixelT = GrayPixelLayout<SrcViewT>>
|
||||
static auto MakeColorConvertedView(const SrcViewT &src, ColorConverter::LogarithmicDepth) {
|
||||
auto intermediate_view = _MakeColorConvertedView<boost::gil::gray32f_pixel_t>(src, ColorConverter::Depth());
|
||||
return _MakeColorConvertedView<DstPixelT>(intermediate_view, ColorConverter::LogarithmicLinear());
|
||||
}
|
||||
|
||||
template <typename SrcViewT, typename DstPixelT = typename SrcViewT::value_type>
|
||||
static auto MakeColorConvertedView(const SrcViewT &src, ColorConverter::CityScapesPalette cc) {
|
||||
return _MakeColorConvertedView<DstPixelT>(src, cc);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template <typename SrcView, typename DstP, typename CC>
|
||||
struct color_converted_type {
|
||||
private:
|
||||
typedef boost::gil::color_convert_deref_fn<typename SrcView::const_t::reference, DstP, CC> deref_t;
|
||||
typedef typename SrcView::template add_deref<deref_t> add_ref_t;
|
||||
public:
|
||||
typedef typename add_ref_t::type type;
|
||||
static type make(const SrcView &sv, CC cc) { return add_ref_t::make(sv, deref_t(cc)); }
|
||||
};
|
||||
|
||||
template <typename DstPixelT, typename SrcViewT, typename CC>
|
||||
static auto _MakeColorConvertedView(const SrcViewT &src, CC cc) {
|
||||
return color_converted_type<SrcViewT, DstPixelT, CC>::make(src, cc);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace image
|
||||
} // namespace carla
|
|
@ -0,0 +1,186 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include <carla/image/ImageConverter.h>
|
||||
#include <carla/image/ImageIO.h>
|
||||
#include <carla/image/ImageView.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
template <typename ViewT, typename PixelT>
|
||||
struct TestImage {
|
||||
TestImage(TestImage &&) = default;
|
||||
using pixel_type = PixelT;
|
||||
std::unique_ptr<PixelT[]> data;
|
||||
ViewT view;
|
||||
};
|
||||
|
||||
template <typename PixelT>
|
||||
static auto MakeTestImage(size_t width, size_t height) {
|
||||
auto data = std::make_unique<PixelT[]>(sizeof(PixelT) * width * height);
|
||||
auto view = boost::gil::interleaved_view(
|
||||
width,
|
||||
height,
|
||||
reinterpret_cast<PixelT*>(data.get()),
|
||||
sizeof(PixelT) * width);
|
||||
return TestImage<decltype(view), PixelT>{std::move(data), view};
|
||||
}
|
||||
|
||||
TEST(image, support) {
|
||||
using namespace carla::image::io;
|
||||
carla::logging::log("PNG support =", has_png_support());
|
||||
carla::logging::log("JPEG support =", has_jpeg_support());
|
||||
carla::logging::log("TIFF support =", has_tiff_support());
|
||||
}
|
||||
|
||||
TEST(image, depth) {
|
||||
#ifndef NDEBUG
|
||||
carla::log_info("This test only happens in release (too slow).");
|
||||
#else
|
||||
using namespace boost::gil;
|
||||
using namespace carla::image;
|
||||
|
||||
constexpr auto width = 256 * 256 * 256;
|
||||
constexpr auto height = 1u;
|
||||
|
||||
auto img_bgra8 = MakeTestImage<bgra8_pixel_t>(width, height);
|
||||
auto img_gray8 = MakeTestImage<gray8_pixel_t>(width, height);
|
||||
|
||||
auto depth_view = ImageView::MakeColorConvertedView(
|
||||
img_bgra8.view,
|
||||
ColorConverter::Depth());
|
||||
auto ldepth_view = ImageView::MakeColorConvertedView(
|
||||
img_bgra8.view,
|
||||
ColorConverter::LogarithmicDepth());
|
||||
|
||||
auto p = *depth_view.begin();
|
||||
static_assert(std::is_same<decltype(p), gray8_pixel_t>::value, "Not the pixel I was looking for!");
|
||||
auto lp = *ldepth_view.begin();
|
||||
static_assert(std::is_same<decltype(lp), gray8_pixel_t>::value, "Not the pixel I was looking for!");
|
||||
|
||||
ASSERT_EQ(depth_view.size(), img_bgra8.view.size());
|
||||
ASSERT_EQ(ldepth_view.size(), img_bgra8.view.size());
|
||||
|
||||
{
|
||||
auto it_bgra8 = img_bgra8.view.begin();
|
||||
auto it_gray8 = img_gray8.view.begin();
|
||||
|
||||
for (auto r = 0u; r < 256u; ++r) {
|
||||
for (auto g = 0u; g < 256u; ++g) {
|
||||
for (auto b = 0u; b < 256u; ++b) {
|
||||
decltype(img_bgra8)::pixel_type &p_bgra8 = *it_bgra8;
|
||||
decltype(img_gray8)::pixel_type &p_gray8 = *it_gray8;
|
||||
get_color(p_bgra8, red_t()) = r;
|
||||
get_color(p_bgra8, green_t()) = g;
|
||||
get_color(p_bgra8, blue_t()) = b;
|
||||
const float depth = r + (g * 256) + (b * 256 * 256);
|
||||
const float normalized = depth / static_cast<float>(256 * 256 * 256 - 1);
|
||||
p_gray8[0] = static_cast<uint8_t>(255.0 * normalized);
|
||||
|
||||
++it_bgra8;
|
||||
++it_gray8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto img_copy = MakeTestImage<bgra8_pixel_t>(width, height);
|
||||
ImageConverter::CopyPixels(img_bgra8.view, img_copy.view);
|
||||
ImageConverter::ConvertInPlace(img_copy.view, ColorConverter::LogarithmicDepth());
|
||||
|
||||
{
|
||||
auto it_gray8 = img_gray8.view.begin();
|
||||
auto it_depth = depth_view.begin();
|
||||
auto it_ldepth = ldepth_view.begin();
|
||||
auto it_copy = img_copy.view.begin();
|
||||
|
||||
for (auto i = 0u; i < width; ++i) {
|
||||
auto p_gray8 = *it_gray8;
|
||||
auto p_depth = *it_depth;
|
||||
auto p_ldepth = *it_ldepth;
|
||||
auto p_copy = *it_copy;
|
||||
ASSERT_NEAR(int(p_depth[0]), int(p_gray8[0]), 1)
|
||||
<< "at XY(" << i << ",0)";
|
||||
decltype(p_copy) ld;
|
||||
color_convert(p_ldepth, ld);
|
||||
ASSERT_EQ(ld, p_copy)
|
||||
<< "at XY(" << i << ",0)";
|
||||
++it_gray8;
|
||||
++it_depth;
|
||||
++it_ldepth;
|
||||
++it_copy;
|
||||
}
|
||||
}
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
TEST(image, semantic_segmentation) {
|
||||
using namespace boost::gil;
|
||||
using namespace carla::image;
|
||||
|
||||
constexpr auto width = CityScapesPalette::GetNumberOfTags();
|
||||
constexpr auto height = 1u;
|
||||
|
||||
auto img_bgra8 = MakeTestImage<bgra8_pixel_t>(width, height);
|
||||
auto img_ss = MakeTestImage<rgb8_pixel_t>(width, height);
|
||||
|
||||
auto semseg_view = ImageView::MakeColorConvertedView(
|
||||
img_bgra8.view,
|
||||
ColorConverter::CityScapesPalette());
|
||||
|
||||
auto p = *semseg_view.begin();
|
||||
static_assert(std::is_same<decltype(p), bgra8_pixel_t>::value, "Not the pixel I was looking for!");
|
||||
|
||||
ASSERT_EQ(semseg_view.size(), img_bgra8.view.size());
|
||||
|
||||
{
|
||||
auto it_bgra8 = img_bgra8.view.begin();
|
||||
auto it_ss = img_ss.view.begin();
|
||||
|
||||
for (auto tag = 0u; tag < width; ++tag) {
|
||||
decltype(img_bgra8)::pixel_type &p_bgra8 = *it_bgra8;
|
||||
get_color(p_bgra8, red_t()) = tag;
|
||||
get_color(p_bgra8, green_t()) = 0u;
|
||||
get_color(p_bgra8, blue_t()) = 0u;
|
||||
decltype(img_ss)::pixel_type &p_ss = *it_ss;
|
||||
auto color = CityScapesPalette::GetColor(tag);
|
||||
get_color(p_ss, red_t()) = color[0u];
|
||||
get_color(p_ss, green_t()) = color[1u];
|
||||
get_color(p_ss, blue_t()) = color[2u];
|
||||
++it_bgra8;
|
||||
++it_ss;
|
||||
}
|
||||
}
|
||||
|
||||
auto img_copy = MakeTestImage<rgba8_pixel_t>(width, height);
|
||||
ImageConverter::CopyPixels(img_bgra8.view, img_copy.view);
|
||||
ImageConverter::ConvertInPlace(img_copy.view, ColorConverter::CityScapesPalette());
|
||||
|
||||
{
|
||||
auto it_ss = img_ss.view.begin();
|
||||
auto it_ssv = semseg_view.begin();
|
||||
auto it_copy = img_copy.view.begin();
|
||||
|
||||
for (auto i = 0u; i < width; ++i) {
|
||||
auto p_ssv = *it_ssv;
|
||||
auto p_copy = *it_copy;
|
||||
auto _p_ss = *it_ss;
|
||||
decltype(p_ssv) p_ss;
|
||||
color_convert(_p_ss, p_ss);
|
||||
ASSERT_EQ(p_ssv, p_ss)
|
||||
<< "at XY(" << i << ",0)";
|
||||
decltype(p_copy) css;
|
||||
color_convert(p_ssv, css);
|
||||
ASSERT_EQ(p_ssv, p_copy)
|
||||
<< "at XY(" << i << ",0)";
|
||||
++it_ss;
|
||||
++it_ssv;
|
||||
++it_copy;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -150,6 +150,7 @@ set CMAKE_INSTALLATION_DIR=%INSTALLATION_DIR:\=/%
|
|||
>>"%INSTALLATION_DIR%CMakeLists.txt.in" echo endif()
|
||||
>>"%INSTALLATION_DIR%CMakeLists.txt.in" echo.
|
||||
>>"%INSTALLATION_DIR%CMakeLists.txt.in" echo add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY)
|
||||
>>"%INSTALLATION_DIR%CMakeLists.txt.in" echo add_definitions(-DLIBCARLA_IMAGE_WITH_PNG_SUPPORT)
|
||||
>>"%INSTALLATION_DIR%CMakeLists.txt.in" echo.
|
||||
>>"%INSTALLATION_DIR%CMakeLists.txt.in" echo set(BOOST_INCLUDE_PATH "%CMAKE_INSTALLATION_DIR%boost-install/include")
|
||||
>>"%INSTALLATION_DIR%CMakeLists.txt.in" echo set(BOOST_LIB_PATH "%CMAKE_INSTALLATION_DIR%boost-install/lib")
|
||||
|
|
|
@ -255,6 +255,12 @@ cat >${CMAKE_CONFIG_FILE}.gen <<EOL
|
|||
set(CARLA_VERSION $(get_carla_version))
|
||||
|
||||
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY)
|
||||
add_definitions(-DLIBCARLA_IMAGE_WITH_PNG_SUPPORT)
|
||||
|
||||
# Uncomment to force support for other image formats (require their respective
|
||||
# libraries installed).
|
||||
# add_definitions(-DLIBCARLA_IMAGE_WITH_JPEG_SUPPORT)
|
||||
# add_definitions(-DLIBCARLA_IMAGE_WITH_TIFF_SUPPORT)
|
||||
|
||||
set(BOOST_INCLUDE_PATH "${BOOST_INCLUDE}")
|
||||
|
||||
|
|
Loading…
Reference in New Issue