eos 1.4.0
Loading...
Searching...
No Matches
resize.hpp
1/*
2 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
3 *
4 * File: include/eos/core/image/resize.hpp
5 *
6 * Copyright 2018-2019 Patrik Huber
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20#pragma once
21
22#ifndef EOS_IMAGE_RESIZE_HPP
23#define EOS_IMAGE_RESIZE_HPP
24
25#include "eos/core/Image.hpp"
26
27#include "Eigen/Dense"
28
29#include <cstdint>
30#include <cmath>
31
32namespace eos {
33namespace core {
34namespace image {
35
49inline eos::core::Image3u resize(const eos::core::Image3u& image, int width, int height)
50{
51 using Eigen::Vector3i;
52 using std::ceil;
53 using std::floor;
54 using std::round;
55 using std::uint8_t;
56
57 const float scaling_width = static_cast<float>(width) / image.width();
58 const float scaling_height = static_cast<float>(height) / image.height();
59
60 eos::core::Image3u resized_image(height, width);
61 for (int w = 0; w < width; ++w)
62 {
63 for (int h = 0; h < height; ++h)
64 {
65 const float left = (static_cast<float>(w)) / scaling_width;
66 const float right = (static_cast<float>(w) + 1.0f) / scaling_width;
67 const float bottom = (static_cast<float>(h)) / scaling_height;
68 const float top = (static_cast<float>(h) + 1.0f) / scaling_height;
69
70 Vector3i color = Vector3i::Zero(); // std::uint8_t actually.
71 int num_texels = 0;
72 // loop over square in which quadrangle out of the four corners of pixel is
73 for (int a = ceil(left); a <= floor(right); ++a)
74 {
75 for (int b = ceil(bottom); b <= floor(top); ++b)
76 {
77 // check if texel is in image
78 if (a < image.width() && b < image.height())
79 {
80 num_texels++;
81 color += Vector3i(image(b, a)[0], image(b, a)[1], image(b, a)[2]);
82 }
83 }
84 }
85 if (num_texels > 0)
86 color = color / num_texels;
87 else
88 { // if no corresponding texel found, nearest neighbour interpolation
89 // calculate corresponding position of dst_coord pixel center in image (src)
90 const int source_x = round(static_cast<float>(w) / scaling_width);
91 const int source_y = round(static_cast<float>(h) / scaling_height);
92
93 if (source_y < image.height() && source_x < image.width())
94 {
95 color = Vector3i(image(source_y, source_x)[0], image(source_y, source_x)[1],
96 image(source_y, source_x)[2]);
97 }
98 }
99
100 resized_image(h, w) = {static_cast<std::uint8_t>(round(color[0])),
101 static_cast<std::uint8_t>(round(color[1])),
102 static_cast<std::uint8_t>(round(color[2]))};
103 }
104 }
105
106 return resized_image;
107};
108
122inline eos::core::Image4u resize(const eos::core::Image4u& image, int width, int height)
123{
124 using Eigen::Vector4i;
125 using std::ceil;
126 using std::floor;
127 using std::round;
128 using std::uint8_t;
129
130 const float scaling_width = static_cast<float>(width) / image.width();
131 const float scaling_height = static_cast<float>(height) / image.height();
132
133 eos::core::Image4u resized_image(height, width);
134 for (int w = 0; w < width; ++w)
135 {
136 for (int h = 0; h < height; ++h)
137 {
138 const float left = (static_cast<float>(w)) / scaling_width;
139 const float right = (static_cast<float>(w) + 1.0f) / scaling_width;
140 const float bottom = (static_cast<float>(h)) / scaling_height;
141 const float top = (static_cast<float>(h) + 1.0f) / scaling_height;
142
143 Vector4i color = Vector4i::Zero(); // std::uint8_t actually.
144 int num_texels = 0;
145 // loop over square in which quadrangle out of the four corners of pixel is
146 for (int a = ceil(left); a <= floor(right); ++a)
147 {
148 for (int b = ceil(bottom); b <= floor(top); ++b)
149 {
150 // check if texel is in image
151 if (a < image.width() && b < image.height())
152 {
153 num_texels++;
154 color += Vector4i(image(b, a)[0], image(b, a)[1], image(b, a)[2], image(b, a)[3]);
155 }
156 }
157 }
158 if (num_texels > 0)
159 color = color / num_texels;
160 else
161 { // if no corresponding texel found, nearest neighbour interpolation
162 // calculate corresponding position of dst_coord pixel center in image (src)
163 const int source_x = round(static_cast<float>(w) / scaling_width);
164 const int source_y = round(static_cast<float>(h) / scaling_height);
165
166 if (source_y < image.height() && source_x < image.width())
167 {
168 color = Vector4i(image(source_y, source_x)[0], image(source_y, source_x)[1],
169 image(source_y, source_x)[2], image(source_y, source_x)[3]);
170 }
171 }
172
173 resized_image(h, w) = {
174 static_cast<std::uint8_t>(round(color[0])), static_cast<std::uint8_t>(round(color[1])),
175 static_cast<std::uint8_t>(round(color[2])), static_cast<std::uint8_t>(round(color[3]))};
176 }
177 }
178
179 return resized_image;
180};
181
182} // namespace image
183} // namespace core
184} // namespace eos
185
186#endif /* EOS_IMAGE_RESIZE_HPP */
Class to represent images.
Definition: Image.hpp:44
Namespace containing all of eos's 3D model fitting functionality.