SourceXtractorPlusPlus  0.11
Please provide a description of the project.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
WriteableImageInterfaceTraits.h
Go to the documentation of this file.
1 
17 /*
18  * WriteableImageInterfaceTraits.h
19  *
20  * Created on: Jan 15, 2019
21  * Author: Alejandro Alvarez Ayllon
22  */
23 
24 #ifndef _SEIMPLEMENTATION_IMAGE_WRITEABLEIMAGEINTERFACETRAITS_H_
25 #define _SEIMPLEMENTATION_IMAGE_WRITEABLEIMAGEINTERFACETRAITS_H_
26 
27 #include "ImageInterfaceTraits.h"
28 
29 namespace ModelFitting {
30 
33 
34 
40 template<>
42 
43  class WriteableIterator;
44 
45  class WriteableSetter {
46  private:
48  int m_x, m_y;
49 
50  friend class WriteableIterator;
51 
52  public:
53  WriteableSetter(WriteableInterfaceTypePtr &image, int x, int y) : m_image{image}, m_x{x}, m_y{y} {}
54 
56  m_image->setValue(m_x, m_y, v);
57  return v;
58  }
59 
61  v += m_image->getValue(m_x, m_y);
62  m_image->setValue(m_x, m_y, v);
63  return v;
64  }
65 
67  return m_image->getValue(m_x, m_y);
68  }
69  };
70 
71  class WriteableIterator : std::iterator<std::forward_iterator_tag, WriteableInterfaceType::PixelType> {
72  private:
74  int m_x, m_y;
75  const int m_width, m_height;
76  WriteableSetter m_setter;
77 
78  public:
79 
80  WriteableIterator(WriteableInterfaceTypePtr image) : m_image{image}, m_x{0}, m_y{0},
81  m_width{image->getWidth()},
82  m_height{image->getHeight()},
83  m_setter{image, 0, 0} {
84  }
85 
86  WriteableIterator(WriteableInterfaceTypePtr image, int) : WriteableIterator(image) {
87  m_y = m_height;
88  }
89 
90  bool operator!=(const WriteableIterator &b) const {
91  return m_x != b.m_x || m_y != b.m_y || m_width != b.m_width || m_height != b.m_height || m_image != b.m_image;
92  }
93 
94  WriteableIterator &operator++() {
95  if (m_y < m_height) {
96  ++m_x;
97  if (m_x >= m_width) {
98  m_x = 0;
99  ++m_y;
100  if (m_y >= m_height) {
101  m_y = m_height;
102  }
103  }
104  }
105  return *this;
106  }
107 
109  return m_image->getValue(m_x, m_y);
110  }
111 
112  WriteableSetter& operator*() {
113  m_setter.m_x = m_x;
114  m_setter.m_y = m_y;
115  return m_setter;
116  }
117  };
118 
119  using iterator = WriteableIterator;
120 
123  }
124 
126  return image->getWidth();
127  }
128 
130  return image->getHeight();
131  }
132 
133  static WriteableSetter at(WriteableInterfaceTypePtr &image, std::size_t x, std::size_t y) {
134  return WriteableSetter(image, x, y);
135  }
136 
138  return image->getValue(x, y);
139  }
140 
141  static iterator begin(const WriteableInterfaceTypePtr &image) {
142  return WriteableIterator{image};
143  }
144 
145  static iterator end(const WriteableInterfaceTypePtr &image) {
146  return WriteableIterator{image, 0};
147  }
148 
149  static void addImageToImage(WriteableInterfaceTypePtr &image1, const WriteableInterfaceTypePtr &image2,
150  double scale_factor, double x, double y);
151 
152  static double getClamped(const WriteableInterfaceTypePtr &image, int x, int y) {
153  return at(image, std::max(0, std::min(x, (int) width(image) - 1)),
154  std::max(0, std::min(y, (int) height(image) - 1)));
155  }
156 
157  static void
158  shiftResize(const WriteableInterfaceTypePtr &source, WriteableInterfaceTypePtr &window, double scale_factor,
159  double x_shift, double y_shift) {
160  int window_width = width(window);
161  int window_height = height(window);
162  for (int x_win = 0; x_win < window_width; x_win++) {
163  for (int y_win = 0; y_win < window_height; y_win++) {
164  double x = (x_win - 0.5 - x_shift) / scale_factor;
165  double y = (y_win - 0.5 - y_shift) / scale_factor;
166 
167  int xi = std::floor(x);
168  int yi = std::floor(y);
169 
170  double x_delta = x - xi;
171  double y_delta = y - yi;
172 
173  double v00 = getClamped(source, xi, yi);
174  double v01 = getClamped(source, xi, yi + 1);
175  double v10 = getClamped(source, xi + 1, yi);
176  double v11 = getClamped(source, xi + 1, yi + 1);
177 
178  window->setValue(x_win, y_win, (1.0 - y_delta) * ((1.0 - x_delta) * v00 + x_delta * v10) +
179  y_delta * ((1.0 - x_delta) * v01 + x_delta * v11));
180  }
181  }
182 
183  }
184 
185  static void
186  shiftResizeLancszos(const WriteableInterfaceTypePtr &source, WriteableInterfaceTypePtr &window, double scale_factor,
187  double x_shift, double y_shift) {
188  int window_width = width(window);
189  int window_height = height(window);
190  for (int x_win = 0; x_win < window_width; x_win++) {
191  for (int y_win = 0; y_win < window_height; y_win++) {
192  float x = (x_win - x_shift) / scale_factor;
193  float y = (y_win - y_shift) / scale_factor;
194 
195  // Work around the interface of interpolate_pix copying to memory the pixels surrounding
196  // the pixel to interpolate
197  float buffer[INTERP_MAXKERNELWIDTH * INTERP_MAXKERNELWIDTH] = {0.};
198  int ix = x, iy = y;
199 
200  for (int j = 0; j < INTERP_MAXKERNELWIDTH; ++j) {
201  for (int i = 0; i < INTERP_MAXKERNELWIDTH; ++i) {
202  int src_x = ix + i - INTERP_MAXKERNELWIDTH / 2;
203  int src_y = iy + j - INTERP_MAXKERNELWIDTH / 2;
204 
205  if (src_x >= 0 && src_y >= 0 && src_x < source->getWidth() && src_y < source->getHeight()) {
206  buffer[j * INTERP_MAXKERNELWIDTH + i] = source->getValue(src_x, src_y);
207  }
208  }
209  }
210 
211  window->setValue(x_win, y_win,
212  SourceXtractor::interpolate_pix(buffer, INTERP_MAXKERNELWIDTH / 2 + x - ix, INTERP_MAXKERNELWIDTH / 2 + y - iy,
214  }
215  }
216 
217  }
218 
219 
220 }; // end of class ImageTraits<WriteableInterfaceTypePtr>
221 
222 template<typename T>
225  0)) {
226  return v * static_cast<WriteableInterfaceType::PixelType>(setter);
227 }
228 
229 template<typename T>
232  return static_cast<WriteableInterfaceType::PixelType>(setter) * v;
233 }
234 
236  const WriteableInterfaceTypePtr &image2,
237  double scale_factor, double x, double y) {
238  // Calculate the size in pixels of the image2 after in the scale of image1
239  double scaled_width = width(image2) * scale_factor;
240  double scaled_height = height(image2) * scale_factor;
241  // Calculate the window of the image1 which is affected
242  int x_min = std::floor(x - scaled_width / 2.);
243  int x_max = std::ceil(x + scaled_width / 2.);
244  int window_width = x_max - x_min;
245  int y_min = std::floor(y - scaled_height / 2.);
246  int y_max = std::ceil(y + scaled_height / 2.);
247  int window_height = y_max - y_min;
248  // Calculate the shift of the image2 inside the window
249  double x_shift = x - scaled_width / 2. - x_min;
250  double y_shift = y - scaled_height / 2. - y_min;
251  // Create the scaled and shifted window
252  auto window = factory(window_width, window_height);
253 
254  //shiftResize(image2, window, scale_factor, x_shift, y_shift);
255  shiftResizeLancszos(image2, window, scale_factor, x_shift, y_shift);
256 
257  // We need to correct the window for the scaling, so it has the same integral
258  // with the image2
259  double corr_factor = 1. / (scale_factor * scale_factor);
260  // Add the window to the image1
261  for (int x_im = std::max(x_min, 0); x_im < std::min<int>(x_max, width(image1)); ++x_im) {
262  for (int y_im = std::max(y_min, 0); y_im < std::min<int>(y_max, height(image1)); ++y_im) {
263  int x_win = x_im - x_min;
264  int y_win = y_im - y_min;
265  at(image1, x_im, y_im) += corr_factor * at(window, x_win, y_win);
266  }
267  }
268 }
269 
270 } // end of namespace ModelFitting
271 
272 
273 #endif /* _SEIMPLEMENTATION_IMAGE_WRITEABLEIMAGEINTERFACETRAITS_H_ */
double getClamped(const ImageInterfaceTypePtr &image, int x, int y)
#define INTERP_MAXKERNELWIDTH
static ImageType factory(std::size_t width, std::size_t height)
static std::size_t height(const WriteableInterfaceTypePtr &image)
SourceXtractor::WriteableImage< SourceXtractor::SeFloat > WriteableInterfaceType
T ceil(T...args)
static std::size_t height(ImageType &image)
static WriteableInterfaceTypePtr factory(std::size_t width, std::size_t height)
static double & at(ImageType &image, std::size_t x, std::size_t y)
auto operator*(T v, const ImageTraits< WriteableInterfaceTypePtr >::WriteableSetter &setter) -> decltype(v *WriteableInterfaceType::PixelType(0))
static void addImageToImage(ImageType &image1, const ImageType &image2, double scale, double x, double y)
WriteableInterfaceType::PixelType operator+=(WriteableInterfaceType::PixelType v)
static iterator end(const WriteableInterfaceTypePtr &image)
static std::shared_ptr< VectorImage< T > > create(Args &&...args)
Definition: VectorImage.h:89
T floor(T...args)
T min(T...args)
void shiftResizeLancszos(const ImageInterfaceTypePtr &source, ImageInterfaceTypePtr &window, double scale_factor, double x_shift, double y_shift)
WriteableInterfaceType::PixelType operator=(WriteableInterfaceType::PixelType v)
static double getClamped(const WriteableInterfaceTypePtr &image, int x, int y)
T max(T...args)
static iterator begin(const WriteableInterfaceTypePtr &image)
static WriteableSetter at(WriteableInterfaceTypePtr &image, std::size_t x, std::size_t y)
float interpolate_pix(float *pix, float x, float y, int xsize, int ysize, interpenum interptype)
static std::size_t width(const WriteableInterfaceTypePtr &image)
static void shiftResize(const WriteableInterfaceTypePtr &source, WriteableInterfaceTypePtr &window, double scale_factor, double x_shift, double y_shift)
static void shiftResizeLancszos(const WriteableInterfaceTypePtr &source, WriteableInterfaceTypePtr &window, double scale_factor, double x_shift, double y_shift)
static ImageInterfaceType::PixelType at(const WriteableInterfaceTypePtr &image, std::size_t x, std::size_t y)
std::shared_ptr< WriteableInterfaceType > WriteableInterfaceTypePtr
static std::size_t width(ImageType &image)