20#include <lagrange/Logger.h>
21#include <lagrange/scene/internal/shared_utils.h>
22#include <lagrange/texproc/TextureRasterizer.h>
23#include <lagrange/utils/fmt/format.h>
25#include <tbb/parallel_for.h>
27namespace lagrange::texproc {
28using scene::internal::Array3Df;
29using scene::internal::ConstView3Df;
30using scene::internal::View3Df;
46template <
typename Scalar,
typename Index>
47std::vector<std::pair<Array3Df, Array3Df>> rasterize_textures_from_renders(
48 const SurfaceMesh<Scalar, Index>& mesh,
49 std::optional<Array3Df> base_texture,
50 const std::vector<CameraTransforms>& cameras,
51 const std::vector<ConstView3Df>& renders,
52 const std::optional<size_t> tex_width,
53 const std::optional<size_t> tex_height,
54 const float low_confidence_ratio,
55 const std::optional<float> base_confidence)
58 for (
const auto& render : renders) {
59 size_t img_width = render.extent(0);
60 size_t img_height = render.extent(1);
61 size_t img_channels = render.extent(2);
62 la_runtime_assert(img_width == renders.front().extent(0),
"Render width must all be equal");
64 img_height == renders.front().extent(1),
65 "Render height must all be equal");
67 img_channels == renders.front().extent(2),
68 "Render num channels must all be equal");
71 renders.size() == cameras.size(),
72 "Number of renders must match number of cameras");
74 std::vector<std::pair<Array3Df, Array3Df>> textures_and_weights;
77 if (base_confidence.has_value() && base_confidence.value() == 0) {
78 if (base_texture.has_value()) {
79 lagrange::logger().warn(
"Base confidence is 0, ignoring provided base texture.");
82 if (base_texture.has_value()) {
83 const float default_confidence = base_confidence.value_or(0.3f);
85 "Using base texture with uniform confidence: {}",
87 const auto base_image = base_texture.value();
92 for (
size_t i = 0; i < base_weights.extent(0); ++i) {
93 for (
size_t j = 0; j < base_weights.extent(1); ++j) {
94 base_weights(i, j, 0) = default_confidence;
97 textures_and_weights.emplace_back(base_image, std::move(base_weights));
99 if (base_confidence.has_value()) {
101 "No base texture was provided. Ignoring user-provided base confidence: {}",
102 base_confidence.value());
109 if (textures_and_weights.empty()) {
110 rasterizer_options.width = tex_width.value_or(1024);
111 rasterizer_options.height = tex_height.value_or(1024);
113 "No base texture found. Using rasterization size: {}x{}",
114 rasterizer_options.width,
115 rasterizer_options.height);
117 const auto& base_image = textures_and_weights.front().first;
118 la_runtime_assert(!tex_width.has_value() || base_image.extent(0) == tex_width.value());
119 la_runtime_assert(!tex_height.has_value() || base_image.extent(1) == tex_height.value());
120 rasterizer_options.width = base_image.extent(0);
121 rasterizer_options.height = base_image.extent(1);
123 renders.front().extent(2) == base_image.extent(2),
125 "Input render image num channels (={}) must match base texture num channels "
127 renders.front().extent(2),
128 base_image.extent(2)));
130 "Using base texture size for rasterization: {}x{}",
131 rasterizer_options.width,
132 rasterizer_options.height);
136 size_t offset = textures_and_weights.size();
137 textures_and_weights.resize(offset + cameras.size());
139 lagrange::logger().info(
"Computing confidence maps for {} cameras", cameras.size());
140 tbb::parallel_for(
size_t(0), cameras.size(), [&](
size_t i) {
141 textures_and_weights[offset + i] =
142 rasterizer.weighted_texture_from_render(renders[i], cameras[i]);
147 "Filtering low confidence values using ratio threshold: {}",
148 low_confidence_ratio);
151 return textures_and_weights;
159template <
typename Scalar,
typename Index>
160std::vector<std::pair<Array3Df, Array3Df>> rasterize_textures_from_renders(
161 const lagrange::scene::Scene<Scalar, Index>& scene,
162 std::optional<Array3Df> base_texture_override,
163 const std::vector<ConstView3Df>& renders,
164 const std::optional<size_t> tex_width,
165 const std::optional<size_t> tex_height,
166 const float low_confidence_ratio,
167 const std::optional<float> base_confidence)
169 auto [mesh, base_texture] = scene::internal::single_mesh_from_scene(scene);
170 auto cameras = scene::internal::camera_transforms_from_scene(scene);
171 lagrange::logger().info(
"Found {} cameras in the input scene", cameras.size());
173 if (base_texture_override.has_value()) {
174 if (base_texture.has_value()) {
176 "Input scene already contains a base texture. Overriding with user-provided "
179 base_texture = std::move(base_texture_override);
182 return rasterize_textures_from_renders(
184 std::move(base_texture),
189 low_confidence_ratio,
Given a mesh with UVs, unproject rendered images into a UV texture and confidence map.
Definition TextureRasterizer.h:56
LA_CORE_API spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:40
#define la_runtime_assert(...)
Runtime assertion check.
Definition assert.h:175
Array3D< T > create_image(size_t width, size_t height, size_t num_channels)
Create an image with the given dimensions and number of channels.
Definition Array3D.h:46
void filter_low_confidences(span< std::pair< image::experimental::Array3D< float >, image::experimental::Array3D< float > > > textures_and_weights, float low_ratio_threshold)
Discard low-confidence values.
Options for computing the texture map and confidence from a rendering.
Definition TextureRasterizer.h:28