SyB3R - Synthetic Benchmark for 3D Reconstruction
FloatImage.h
1 /*
2  * Syb3r - A framework for the creation and use of synthetic benchmark datasets for SfM/MVS with Blender and Cycles.
3  * Copyright (C) 2016 Andreas Ley <mail@andreas-ley.com>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 
21 #ifndef FLOATIMAGE_H
22 #define FLOATIMAGE_H
23 
24 #include <Eigen/Dense>
25 #include <vector>
26 
27 namespace syb3r {
28 namespace tools {
29 
34 template<typename Type>
36 {
37  public:
40  void resize(unsigned w, unsigned h) {
41  m_width = w;
42  m_height = h;
43  m_data.resize(m_width * m_height);
44  }
45 
47  unsigned getHeight() const { return m_height; }
49  unsigned getWidth() const { return m_width; }
50 
52  Type &operator[](unsigned idx) { return m_data[idx]; }
54  const Type &operator[](unsigned idx) const { return m_data[idx]; }
55 
57  Type &operator()(unsigned x, unsigned y) { return m_data[x + y * m_width]; }
59  const Type &operator()(unsigned x, unsigned y) const { return m_data[x + y * m_width]; }
60 
62  template<typename OtherType, class BinaryOp>
63  const FloatImage<Type>& performBinaryOp(const FloatImage<OtherType> &rhs, BinaryOp op) {
64  assert(rhs.getWidth() == m_width);
65  assert(rhs.getHeight() == m_height);
66  for (unsigned i = 0; i < m_width*m_height; i++)
67  m_data[i] = op(m_data[i], rhs.m_data[i]);
68  return *this;
69  }
70 
72  template<class UnaryOp>
73  const FloatImage<Type>& performUnaryOp(UnaryOp op) {
74  for (unsigned i = 0; i < m_width*m_height; i++)
75  m_data[i] = op(m_data[i]);
76  return *this;
77  }
78 
79  template<typename OtherType>
80  const FloatImage<Type>& operator-=(const FloatImage<OtherType> &rhs) {
81  return performBinaryOp(rhs, [](const Type &a, const OtherType &b)->Type { return a-b; });
82  }
83 
84  template<typename OtherType>
85  const FloatImage<Type>& operator+=(const FloatImage<OtherType> &rhs) {
86  return performBinaryOp(rhs, [](const Type &a, const OtherType &b)->Type { return a+b; });
87  }
88 
89  template<typename OtherType>
90  const FloatImage<Type>& operator*=(const FloatImage<OtherType> &rhs) {
91  return performBinaryOp(rhs, [](const Type &a, const OtherType &b)->Type { return a*b; });
92  }
93 
94  template<typename OtherType>
95  const FloatImage<Type>& operator/=(const FloatImage<OtherType> &rhs) {
96  return performBinaryOp(rhs, [](const Type &a, const OtherType &b)->Type { return a/b; });
97  }
98 
99  template<typename OtherType>
100  const FloatImage<Type>& operator*=(const OtherType &factor) {
101  return performUnaryOp([&factor](const Type &a)->Type { return a*factor; });
102  }
103 
104  template<typename OtherType>
105  const FloatImage<Type>& operator+=(const OtherType &factor) {
106  return performUnaryOp([&factor](const Type &a)->Type { return a+factor; });
107  }
108 
111  void subsample(const FloatImage<Type> &other, unsigned stride) {
112  resize(other.getWidth() / stride, other.getHeight() / stride);
113  for (unsigned y = 0; y < m_height; y++)
114  for (unsigned x = 0; x < m_width; x++)
115  m_data[x + y * m_width] = other(x*stride, y*stride);
116  }
117 
120  Type sampleLinear(float x, float y) const {
121  x = std::min(std::max(x - 0.5f, 0.0f), m_width - 1.001f);
122  y = std::min(std::max(y - 0.5f, 0.0f), m_height - 1.001f);
123 
124  int ix = x;
125  float fracX = x-ix;
126  int iy = y;
127  float fracY = y-iy;
128 
129  const Type &v00 = (*this)(ix+0, iy+0);
130  const Type &v01 = (*this)(ix+0, iy+1);
131  const Type &v10 = (*this)(ix+1, iy+0);
132  const Type &v11 = (*this)(ix+1, iy+1);
133 
134  return (v00 * (1.0f - fracX) + v10 * fracX) * (1.0f - fracY) +
135  (v01 * (1.0f - fracX) + v11 * fracX) * fracY;
136  }
137 
140  template <typename scalarType>
141  scalarType sampleLinearChannel(float x, float y, unsigned channel) const {
142  x = std::min(std::max(x - 0.5f, 0.0f), m_width - 1.001f);
143  y = std::min(std::max(y - 0.5f, 0.0f), m_height - 1.001f);
144 
145  int ix = x;
146  float fracX = x-ix;
147  int iy = y;
148  float fracY = y-iy;
149 
150  const scalarType &v00 = (*this)(ix+0, iy+0)[channel];
151  const scalarType &v01 = (*this)(ix+0, iy+1)[channel];
152  const scalarType &v10 = (*this)(ix+1, iy+0)[channel];
153  const scalarType &v11 = (*this)(ix+1, iy+1)[channel];
154 
155  return (v00 * (1.0f - fracX) + v10 * fracX) * (1.0f - fracY) +
156  (v01 * (1.0f - fracX) + v11 * fracX) * fracY;
157  }
158 
159  void swap(FloatImage<Type> &other) {
160  std::swap(m_width, other.m_width);
161  std::swap(m_height, other.m_height);
162  std::swap(m_data, other.m_data);
163  }
164  protected:
165  unsigned m_width = 0;
166  unsigned m_height = 0;
167  std::vector<Type> m_data;
168 };
169 
171 template<typename Type>
172 Type computeAverage(const FloatImage<Type> &img)
173 {
174  Type totalSum = Type(0);
175  for (unsigned y = 0; y < img.getHeight(); y++) {
176  Type rowSum = Type(0);
177  for (unsigned x = 0; x < img.getWidth(); x++)
178  rowSum += img(x, y);
179  totalSum += rowSum;
180  }
181  return totalSum / (img.getWidth() * img.getHeight());
182 }
183 
186 template<typename Type, typename KernelType>
187 void blurHorizontal(FloatImage<Type> &dst, const FloatImage<Type> &src, const std::vector<KernelType> &kernel)
188 {
189  dst.resize(src.getWidth(), src.getHeight());
190  for (unsigned y = 0; y < src.getHeight(); y++) {
191  for (unsigned x = 0; x < src.getWidth(); x++) {
192  Type sum = src(x, y) * kernel[0];
193  for (unsigned i = 1; i < kernel.size(); i++) {
194  int x0 = std::max<int>(0, (int)x - (int)i);
195  int x1 = std::min<int>(src.getWidth()-1, (int)x + (int)i);
196 
197  sum += (src(x0, y) + src(x1, y)) * kernel[i];
198  }
199  dst(x, y) = sum;
200  }
201  }
202 }
203 
206 template<typename Type, typename KernelType>
207 void blurVertical(FloatImage<Type> &dst, const FloatImage<Type> &src, const std::vector<KernelType> &kernel)
208 {
209  dst.resize(src.getWidth(), src.getHeight());
210  for (unsigned y = 0; y < src.getHeight(); y++) {
211  for (unsigned x = 0; x < src.getWidth(); x++) {
212  Type sum = src(x, y) * kernel[0];
213  for (unsigned i = 1; i < kernel.size(); i++) {
214  int y0 = std::max<int>(0, (int)y - (int)i);
215  int y1 = std::min<int>(src.getHeight()-1, (int)y + (int)i);
216 
217  sum += (src(x, y0) + src(x, y1)) * kernel[i];
218  }
219  dst(x, y) = sum;
220  }
221  }
222 }
223 
224 
226 void normalizeFilterKernel(std::vector<float> &kernel);
228 void normalizeFilterKernelEnergy(std::vector<float> &kernel);
229 
230 
231 
232 extern template class FloatImage<Eigen::Vector3f>;
233 extern template class FloatImage<float>;
234 
235 }
236 }
237 
238 #endif // FLOATIMAGE_H
Definition: CameraPathEvaluation.cpp:10
void subsample(const FloatImage< Type > &other, unsigned stride)
Copys every n-th row and every n-th column.
Definition: FloatImage.h:111
unsigned getHeight() const
Returns number or rows in the image.
Definition: FloatImage.h:47
unsigned getWidth() const
Returns number of columns in the image.
Definition: FloatImage.h:49
Type sampleLinear(float x, float y) const
Samples from a float coordinate, using bilinear interpolation.
Definition: FloatImage.h:120
scalarType sampleLinearChannel(float x, float y, unsigned channel) const
Samples a single channel from a float coordinate, using bilinear interpolation.
Definition: FloatImage.h:141
Type & operator()(unsigned x, unsigned y)
Access to a single pixel.
Definition: FloatImage.h:57
void resize(unsigned w, unsigned h)
Allocate memory for w times h pixels.
Definition: FloatImage.h:40
const Type & operator[](unsigned idx) const
Direct access to the row major data.
Definition: FloatImage.h:54
const FloatImage< Type > & performUnaryOp(UnaryOp op)
Helper function for unary operations.
Definition: FloatImage.h:73
const Type & operator()(unsigned x, unsigned y) const
Access to a single pixel.
Definition: FloatImage.h:59
Stores an image with arbitrary, usually float based, pixel values.
Definition: FloatImage.h:35
Type & operator[](unsigned idx)
Direct access to the row major data.
Definition: FloatImage.h:52
const FloatImage< Type > & performBinaryOp(const FloatImage< OtherType > &rhs, BinaryOp op)
Helper function for binary operations.
Definition: FloatImage.h:63