SourceXtractorPlusPlus  0.15
Please provide a description of the project.
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 
28 #include "ImageInterfaceTraits.h"
29 
30 namespace ModelFitting {
31 
34 
35 
41 template<>
43 
44  class WriteableIterator;
45 
46  class WriteableSetter {
47  private:
50  int m_x, m_y;
51 
52  friend class WriteableIterator;
53 
54  public:
56  : m_image{image}, m_accessor{image}, m_x{x}, m_y{y} {}
57 
59  m_image->setValue(m_x, m_y, v);
60  return v;
61  }
62 
64  v += m_accessor.getValue(m_x, m_y);
65  m_image->setValue(m_x, m_y, v);
66  return v;
67  }
68 
70  return m_accessor.getValue(m_x, m_y);
71  }
72  };
73 
74  class WriteableIterator : std::iterator<std::forward_iterator_tag, WriteableInterfaceType::PixelType> {
75  private:
78  int m_x, m_y;
79  const int m_width, m_height;
80  WriteableSetter m_setter;
81 
82  public:
83 
85  : m_image{image}, m_accessor{image}, m_x{0}, m_y{0},
86  m_width{image->getWidth()},
87  m_height{image->getHeight()},
88  m_setter{image, 0, 0} {
89  }
90 
91  WriteableIterator(WriteableInterfaceTypePtr image, int) : WriteableIterator(image) {
92  m_y = m_height;
93  }
94 
95  bool operator!=(const WriteableIterator &b) const {
96  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;
97  }
98 
99  WriteableIterator &operator++() {
100  if (m_y < m_height) {
101  ++m_x;
102  if (m_x >= m_width) {
103  m_x = 0;
104  ++m_y;
105  if (m_y >= m_height) {
106  m_y = m_height;
107  }
108  }
109  }
110  return *this;
111  }
112 
113  WriteableSetter& operator*() {
114  m_setter.m_x = m_x;
115  m_setter.m_y = m_y;
116  return m_setter;
117  }
118  };
119 
120  using iterator = WriteableIterator;
121 
124  }
125 
127  return image->getWidth();
128  }
129 
131  return image->getHeight();
132  }
133 
134  static WriteableSetter at(WriteableInterfaceTypePtr &image, std::size_t x, std::size_t y) {
135  return WriteableSetter(image, x, y);
136  }
137 
140  return accessor.getValue(x, y);
141  }
142 
143  static iterator begin(const WriteableInterfaceTypePtr &image) {
144  return WriteableIterator{image};
145  }
146 
147  static iterator end(const WriteableInterfaceTypePtr &image) {
148  return WriteableIterator{image, 0};
149  }
150 
151  static void addImageToImage(WriteableInterfaceTypePtr &image1, const WriteableInterfaceTypePtr &image2,
152  double scale_factor, double x, double y);
153 
154  static double getClamped(const WriteableInterfaceTypePtr &image, int x, int y) {
155  return at(image, std::max(0, std::min(x, (int) width(image) - 1)),
156  std::max(0, std::min(y, (int) height(image) - 1)));
157  }
158 
159  static void
160  shiftResize(const WriteableInterfaceTypePtr &source, WriteableInterfaceTypePtr &window, double scale_factor,
161  double x_shift, double y_shift) {
162  int window_width = width(window);
163  int window_height = height(window);
164  for (int x_win = 0; x_win < window_width; x_win++) {
165  for (int y_win = 0; y_win < window_height; y_win++) {
166  double x = (x_win - 0.5 - x_shift) / scale_factor;
167  double y = (y_win - 0.5 - y_shift) / scale_factor;
168 
169  int xi = std::floor(x);
170  int yi = std::floor(y);
171 
172  double x_delta = x - xi;
173  double y_delta = y - yi;
174 
175  double v00 = getClamped(source, xi, yi);
176  double v01 = getClamped(source, xi, yi + 1);
177  double v10 = getClamped(source, xi + 1, yi);
178  double v11 = getClamped(source, xi + 1, yi + 1);
179 
180  window->setValue(x_win, y_win, (1.0 - y_delta) * ((1.0 - x_delta) * v00 + x_delta * v10) +
181  y_delta * ((1.0 - x_delta) * v01 + x_delta * v11));
182  }
183  }
184 
185  }
186 
187  static void
188  shiftResizeLancszos(const WriteableInterfaceTypePtr &source, WriteableInterfaceTypePtr &window, double scale_factor,
189  double x_shift, double y_shift) {
191  int window_width = width(window);
192  int window_height = height(window);
193  for (int x_win = 0; x_win < window_width; x_win++) {
194  for (int y_win = 0; y_win < window_height; y_win++) {
195  float x = (x_win - x_shift) / scale_factor;
196  float y = (y_win - y_shift) / scale_factor;
197 
198  // Work around the interface of interpolate_pix copying to memory the pixels surrounding
199  // the pixel to interpolate
200  float buffer[INTERP_MAXKERNELWIDTH * INTERP_MAXKERNELWIDTH] = {0.};
201  int ix = x, iy = y;
202 
203  for (int j = 0; j < INTERP_MAXKERNELWIDTH; ++j) {
204  for (int i = 0; i < INTERP_MAXKERNELWIDTH; ++i) {
205  int src_x = ix + i - INTERP_MAXKERNELWIDTH / 2;
206  int src_y = iy + j - INTERP_MAXKERNELWIDTH / 2;
207 
208  if (source->isInside(src_x, src_y)) {
209  buffer[j * INTERP_MAXKERNELWIDTH + i] = accessor.getValue(src_x, src_y);
210  }
211  }
212  }
213 
214  window->setValue(x_win, y_win,
216  INTERP_MAXKERNELWIDTH / 2 + y - iy,
218  }
219  }
220 
221  }
222 
223 
224 }; // end of class ImageTraits<WriteableInterfaceTypePtr>
225 
227  const WriteableInterfaceTypePtr &image2,
228  double scale_factor, double x, double y) {
229  // Calculate the size in pixels of the image2 after in the scale of image1
230  double scaled_width = width(image2) * scale_factor;
231  double scaled_height = height(image2) * scale_factor;
232  // Calculate the window of the image1 which is affected
233  int x_min = std::floor(x - scaled_width / 2.);
234  int x_max = std::ceil(x + scaled_width / 2.);
235  int window_width = x_max - x_min;
236  int y_min = std::floor(y - scaled_height / 2.);
237  int y_max = std::ceil(y + scaled_height / 2.);
238  int window_height = y_max - y_min;
239  // Calculate the shift of the image2 inside the window
240  double x_shift = x - scaled_width / 2. - x_min;
241  double y_shift = y - scaled_height / 2. - y_min;
242  // Create the scaled and shifted window
243  auto window = factory(window_width, window_height);
244 
245  //shiftResize(image2, window, scale_factor, x_shift, y_shift);
246  shiftResizeLancszos(image2, window, scale_factor, x_shift, y_shift);
247 
248  // We need to correct the window for the scaling, so it has the same integral
249  // with the image2
250  double corr_factor = 1. / (scale_factor * scale_factor);
251  // Add the window to the image1
252  for (int x_im = std::max(x_min, 0); x_im < std::min<int>(x_max, width(image1)); ++x_im) {
253  for (int y_im = std::max(y_min, 0); y_im < std::min<int>(y_max, height(image1)); ++y_im) {
254  int x_win = x_im - x_min;
255  int y_win = y_im - y_min;
256  at(image1, x_im, y_im) += corr_factor * at(window, x_win, y_win);
257  }
258  }
259 }
260 
261 } // end of namespace ModelFitting
262 
263 
264 #endif /* _SEIMPLEMENTATION_IMAGE_WRITEABLEIMAGEINTERFACETRAITS_H_ */
#define INTERP_MAXKERNELWIDTH
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
T ceil(T... args)
SourceXtractor::ImageAccessor< WriteableInterfaceType::PixelType > m_accessor
SourceXtractor::ImageAccessor< WriteableInterfaceType::PixelType > m_accessor
WriteableInterfaceType::PixelType operator+=(WriteableInterfaceType::PixelType v)
WriteableInterfaceType::PixelType operator=(WriteableInterfaceType::PixelType v)
static std::shared_ptr< VectorImage< T > > create(Args &&... args)
Definition: VectorImage.h:100
T floor(T... args)
T max(T... args)
T min(T... args)
SourceXtractor::WriteableImage< SourceXtractor::SeFloat > WriteableInterfaceType
std::shared_ptr< WriteableInterfaceType > WriteableInterfaceTypePtr
float interpolate_pix(float *pix, float x, float y, int xsize, int ysize, interpenum interptype)
void shiftResizeLancszos(const ImageInterfaceTypePtr &source, ImageInterfaceTypePtr &window, double scale_factor, double x_shift, double y_shift)
double getClamped(const ImageInterfaceTypePtr &image, int x, int y)
static WriteableSetter at(WriteableInterfaceTypePtr &image, std::size_t x, std::size_t y)
static double getClamped(const WriteableInterfaceTypePtr &image, int x, int y)
static iterator end(const WriteableInterfaceTypePtr &image)
static iterator begin(const WriteableInterfaceTypePtr &image)
static void shiftResize(const WriteableInterfaceTypePtr &source, WriteableInterfaceTypePtr &window, double scale_factor, double x_shift, double y_shift)
static std::size_t width(const WriteableInterfaceTypePtr &image)
static WriteableInterfaceTypePtr factory(std::size_t width, std::size_t height)
static std::size_t height(const WriteableInterfaceTypePtr &image)
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)
static std::size_t height(ImageType &image)
static double & at(ImageType &image, std::size_t x, std::size_t y)
static ImageType factory(std::size_t width, std::size_t height)
static std::size_t width(ImageType &image)
static void addImageToImage(ImageType &image1, const ImageType &image2, double scale, double x, double y)