SourceXtractorPlusPlus 1.0.3
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
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
29
30namespace ModelFitting {
31
32using WriteableInterfaceType = SourceXtractor::WriteableImage<SourceXtractor::SeFloat>;
34
35
41template<>
43
45
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;
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
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
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
114 m_setter.m_x = m_x;
115 m_setter.m_y = m_y;
116 return m_setter;
117 }
118 };
119
121
125
127 return image->getWidth();
128 }
129
131 return image->getHeight();
132 }
133
135 return WriteableSetter(image, x, y);
136 }
137
142
144 return WriteableIterator{image};
145 }
146
148 return WriteableIterator{image, 0};
149 }
150
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
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
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)
T floor(T... args)
T max(T... args)
T min(T... args)
std::shared_ptr< WriteableInterfaceType > WriteableInterfaceTypePtr
SourceXtractor::WriteableImage< SourceXtractor::SeFloat > WriteableInterfaceType
float interpolate_pix(float *pix, float x, float y, int xsize, int ysize, interpenum interptype)
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 std::size_t width(ImageType &image)
static void addImageToImage(ImageType &image1, const ImageType &image2, double scale, double x, double y)
static double & at(ImageType &image, std::size_t x, std::size_t y)