34 #include "VLFeat/imopv.h"
40 float GetPixelConstantBorder(
const float*
data,
const int rows,
const int cols,
41 const int row,
const int col) {
42 if (row >= 0 && col >= 0 && row < rows && col < cols) {
43 return data[row * cols + col];
52 const Camera& target_camera,
54 CHECK_EQ(source_camera.
Width(), source_image.
Width());
56 CHECK_NOTNULL(target_image);
58 target_image->
Allocate(
static_cast<int>(source_camera.
Width()),
59 static_cast<int>(source_camera.
Height()),
60 source_image.
IsRGB());
64 Camera scaled_target_camera = target_camera;
65 if (target_camera.
Width() != source_camera.
Width() ||
70 Eigen::Vector2d image_point;
71 for (
int y = 0;
y < target_image->
Height(); ++
y) {
72 image_point.y() =
y + 0.5;
73 for (
int x = 0;
x < target_image->
Width(); ++
x) {
74 image_point.x() =
x + 0.5;
77 const Eigen::Vector2d world_point =
79 const Eigen::Vector2d source_point =
84 source_point.y() - 0.5, &
color)) {
92 if (target_camera.
Width() != source_camera.
Width() ||
100 CHECK_NOTNULL(target_image);
101 CHECK_GT(target_image->
Width(), 0);
102 CHECK_GT(target_image->
Height(), 0);
103 CHECK_EQ(source_image.
IsRGB(), target_image->
IsRGB());
105 Eigen::Vector3d target_pixel(0, 0, 1);
106 for (
int y = 0;
y < target_image->
Height(); ++
y) {
107 target_pixel.y() =
y + 0.5;
108 for (
int x = 0;
x < target_image->
Width(); ++
x) {
109 target_pixel.x() =
x + 0.5;
111 const Eigen::Vector2d source_pixel = (H * target_pixel).hnormalized();
115 source_pixel.y() - 0.5, &
color)) {
125 const Camera& source_camera,
126 const Camera& target_camera,
127 const Bitmap& source_image,
129 CHECK_EQ(source_camera.
Width(), source_image.
Width());
130 CHECK_EQ(source_camera.
Height(), source_image.
Height());
131 CHECK_NOTNULL(target_image);
133 target_image->
Allocate(
static_cast<int>(source_camera.
Width()),
134 static_cast<int>(source_camera.
Height()),
135 source_image.
IsRGB());
139 Camera scaled_target_camera = target_camera;
140 if (target_camera.
Width() != source_camera.
Width() ||
145 Eigen::Vector3d image_point(0, 0, 1);
146 for (
int y = 0;
y < target_image->
Height(); ++
y) {
147 image_point.y() =
y + 0.5;
148 for (
int x = 0;
x < target_image->
Width(); ++
x) {
149 image_point.x() =
x + 0.5;
152 const Eigen::Vector3d warped_point = H * image_point;
153 const Eigen::Vector2d world_point =
155 const Eigen::Vector2d source_point =
160 source_point.y() - 0.5, &
color)) {
168 if (target_camera.
Width() != source_camera.
Width() ||
175 const int new_rows,
const int new_cols,
178 CHECK_NOTNULL(resampled);
181 CHECK_GT(new_rows, 0);
182 CHECK_GT(new_cols, 0);
184 const float scale_r =
static_cast<float>(rows) /
static_cast<float>(new_rows);
185 const float scale_c =
static_cast<float>(cols) /
static_cast<float>(new_cols);
187 for (
int r = 0; r < new_rows; ++r) {
188 const float r_i = (r + 0.5f) * scale_r - 0.5f;
190 const int r_i_max = r_i_min + 1;
191 const float d_r_min = r_i - r_i_min;
192 const float d_r_max = r_i_max - r_i;
194 for (
int c = 0; c < new_cols; ++c) {
195 const float c_i = (c + 0.5f) * scale_c - 0.5f;
197 const int c_i_max = c_i_min + 1;
198 const float d_c_min = c_i - c_i_min;
199 const float d_c_max = c_i_max - c_i;
203 d_c_max * GetPixelConstantBorder(
data, rows, cols, r_i_min, c_i_min) +
204 d_c_min * GetPixelConstantBorder(
data, rows, cols, r_i_min, c_i_max);
206 d_c_max * GetPixelConstantBorder(
data, rows, cols, r_i_max, c_i_min) +
207 d_c_min * GetPixelConstantBorder(
data, rows, cols, r_i_max, c_i_max);
210 resampled[r * new_cols + c] = d_r_max * value1 + d_r_min * value2;
216 const float sigma_r,
const float sigma_c,
float* smoothed) {
218 CHECK_NOTNULL(smoothed);
221 CHECK_GT(sigma_r, 0);
222 CHECK_GT(sigma_c, 0);
223 vl_imsmooth_f(smoothed, cols,
data, cols, rows, cols, sigma_c, sigma_r);
227 const int new_rows,
const int new_cols,
228 float* downsampled) {
230 CHECK_NOTNULL(downsampled);
231 CHECK_LE(new_rows, rows);
232 CHECK_LE(new_cols, cols);
235 CHECK_GT(new_rows, 0);
236 CHECK_GT(new_cols, 0);
238 const float scale_c =
static_cast<float>(cols) /
static_cast<float>(new_cols);
239 const float scale_r =
static_cast<float>(rows) /
static_cast<float>(new_rows);
241 const float kSigmaScale = 0.5f;
242 const float sigma_c = std::max(std::numeric_limits<float>::epsilon(),
243 kSigmaScale * (scale_c - 1));
244 const float sigma_r = std::max(std::numeric_limits<float>::epsilon(),
245 kSigmaScale * (scale_r - 1));
247 std::vector<float> smoothed(rows * cols);
bool SetPixel(const int x, const int y, const BitmapColor< uint8_t > &color)
bool Allocate(const int width, const int height, const bool as_rgb)
void Rescale(const int new_width, const int new_height, const FREE_IMAGE_FILTER filter=FILTER_BILINEAR)
bool InterpolateBilinear(const double x, const double y, BitmapColor< float > *color) const
Eigen::Vector2d ImageToWorld(const Eigen::Vector2d &image_point) const
void Rescale(const double scale)
Eigen::Vector2d WorldToImage(const Eigen::Vector2d &world_point) const
MiniVec< float, N > floor(const MiniVec< float, N > &a)
void WarpImageBetweenCameras(const Camera &source_camera, const Camera &target_camera, const Bitmap &source_image, Bitmap *target_image)
void ResampleImageBilinear(const float *data, const int rows, const int cols, const int new_rows, const int new_cols, float *resampled)
void SmoothImage(const float *data, const int rows, const int cols, const float sigma_r, const float sigma_c, float *smoothed)
void WarpImageWithHomography(const Eigen::Matrix3d &H, const Bitmap &source_image, Bitmap *target_image)
void WarpImageWithHomographyBetweenCameras(const Eigen::Matrix3d &H, const Camera &source_camera, const Camera &target_camera, const Bitmap &source_image, Bitmap *target_image)
void DownsampleImage(const float *data, const int rows, const int cols, const int new_rows, const int new_cols, float *downsampled)