24 #ifndef _SEIMPLEMENTATION_IMAGE_IMAGEINTERFACETRAITS_H_
25 #define _SEIMPLEMENTATION_IMAGE_IMAGEINTERFACETRAITS_H_
27 #define INTERP_MAXKERNELWIDTH 8 // Max. range of kernel (pixels)
29 #include <boost/math/constants/constants.hpp>
41 #define sincosf __sincosf
44 namespace ModelFitting {
57 const float pi = boost::math::constants::pi<float>();
58 const float threshold = 1
e-6;
59 float x, val, sinx1,sinx2,sinx3,cosx1;
64 *(kernel++) = 1.0 - pos;
67 if (pos < threshold && pos > - threshold) {
73 x = - pi / 2.0 * (pos + 1.0);
74 sincosf(x, &sinx1, &cosx1);
75 val = (*(kernel++) = sinx1 / (x * x));
77 val += (*(kernel++) = -cosx1 / (x * x));
79 val += (*(kernel++) = -sinx1 / (x * x));
81 val += (*kernel = cosx1 / (x *
x));
89 if (pos < threshold && pos > - threshold) {
97 x = - pi / 3.0 * (pos + 2.0);
98 sincosf(x, &sinx1, &cosx1);
99 val = (*(kernel++) = sinx1 / (x * x));
101 val += (*(kernel++) = (sinx2 = -0.5 * sinx1 - 0.866025403785 * cosx1)
104 val += (*(kernel++) = (sinx3 = - 0.5 * sinx1 + 0.866025403785 * cosx1)
107 val += (*(kernel++) = sinx1 / (x * x));
109 val += (*(kernel++) = sinx2 / (x * x));
111 val += (*kernel = sinx3 / (x *
x));
121 if (pos < threshold && pos > - threshold) {
131 x = - pi / 4.0 * (pos + 3.0);
132 sincosf(x, &sinx1, &cosx1);
133 val = (*(kernel++) = sinx1 / (x * x));
135 val += (*(kernel++) = - (sinx2 = 0.707106781186 * (sinx1 + cosx1))
138 val += (*(kernel++) = cosx1 / (x * x));
140 val += (*(kernel++) = - (sinx3 = 0.707106781186 * (cosx1 - sinx1))
143 val += (*(kernel++) = -sinx1 / (x * x));
145 val += (*(kernel++) = sinx2 / (x * x));
147 val += (*(kernel++) = -cosx1 / (x * x));
149 val += (*kernel = sinx3 / (x *
x));
165 int xsize,
int ysize,
interpenum interptype) {
167 static const int interp_kernwidth[5]={1,2,4,6,8};
171 *kvector, *pixin, *pixout,
173 int i, j, ix, iy, kwidth, step;
175 kwidth = interp_kernwidth[interptype];
179 ix = (int)(x-0.50001);
180 iy = (int)(y-0.50001);
192 if (ix < 0 || ix + kwidth <= 0 || ix + kwidth > xsize ||
193 iy < 0 || iy + kwidth <= 0 || iy + kwidth > ysize)
198 step = xsize - kwidth;
199 pixin = pix + iy * xsize + ix ;
201 for (j = kwidth; j--;) {
204 for (i = kwidth; i--;)
205 val += *(kvector++) * *(pixin++);
215 for (i = kwidth; i--;)
216 val += *(kvector++) * *(pixin++);
232 return image->getWidth();
236 return image->getHeight();
240 return image->at(x, y);
244 return image->at(x, y);
248 return image->getData().begin();
252 return image->getData().end();
257 double scale_factor,
double x,
double y) {
259 double scaled_width =
width(source_image) * scale_factor;
260 double scaled_height =
height(source_image) * scale_factor;
262 int x_min =
std::floor(x - scaled_width / 2.);
263 int x_max =
std::ceil(x + scaled_width / 2.);
264 int window_width = x_max - x_min;
265 int y_min =
std::floor(y - scaled_height / 2.);
266 int y_max=
std::ceil(y + scaled_height / 2.);
267 int window_height = y_max - y_min;
269 double x_shift = x - scaled_width / 2. - x_min;
270 double y_shift = y - scaled_height / 2. - y_min;
272 auto window =
factory(window_width, window_height);
275 shiftResizeLancszos(source_image, window, scale_factor, x_shift, y_shift);
279 double corr_factor = 1. / (scale_factor * scale_factor);
281 for(
int x_im=
std::max(x_min,0); x_im<std::min<int>(x_max,
width(target_image)); ++x_im) {
282 for (
int y_im=
std::max(y_min,0); y_im<std::min<int>(y_max,
height(target_image)); ++y_im) {
283 int x_win = x_im - x_min;
284 int y_win = y_im - y_min;
285 at(target_image, x_im, y_im) += corr_factor *
at(window, x_win, y_win);
295 int window_width =
width(window);
296 int window_height =
height(window);
297 for(
int x_win=0; x_win < window_width; x_win++) {
298 for(
int y_win=0; y_win < window_height; y_win++) {
299 double x = (x_win + 0.5 - x_shift) / scale_factor - 0.5;
300 double y = (y_win + 0.5 - y_shift) / scale_factor - 0.5;
305 double x_delta = x - xi;
306 double y_delta = y - yi;
308 double v00 = getClamped(source, xi, yi);
309 double v01 = getClamped(source, xi, yi+1);
310 double v10 = getClamped(source, xi+1, yi);
311 double v11 = getClamped(source, xi+1, yi+1);
313 at(window, x_win, y_win) = (1.0 - y_delta) * ((1.0 - x_delta) * v00 + x_delta * v10) +
314 y_delta * ((1.0 - x_delta) * v01 + x_delta * v11);
320 int window_width =
width(window);
321 int window_height =
height(window);
322 for(
int x_win=0; x_win < window_width; x_win++) {
323 for(
int y_win=0; y_win < window_height; y_win++) {
324 float x = (x_win + 0.5 - x_shift) / scale_factor + 0.5;
325 float y = (y_win + 0.5 - y_shift) / scale_factor + 0.5;
static ImageType factory(std::size_t width, std::size_t height)
#define INTERP_MAXKERNELWIDTH
static std::size_t height(const ImageInterfaceTypePtr &image)
static std::size_t height(ImageType &image)
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
static double & at(ImageType &image, std::size_t x, std::size_t y)
static void shiftResizeLancszos(const ImageInterfaceTypePtr &source, ImageInterfaceTypePtr &window, double scale_factor, double x_shift, double y_shift)
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
static void addImageToImage(ImageInterfaceTypePtr &target_image, const ImageInterfaceTypePtr &source_image, double scale_factor, double x, double y)
static ImageInterfaceType::PixelType & at(ImageInterfaceTypePtr &image, std::size_t x, std::size_t y)
static iterator end(const ImageInterfaceTypePtr &image)
static ImageInterfaceType::PixelType at(const ImageInterfaceTypePtr &image, std::size_t x, std::size_t y)
static void shiftResize(const ImageInterfaceTypePtr &source, ImageInterfaceTypePtr &window, double scale_factor, double x_shift, double y_shift)
static void make_kernel(float pos, float *kernel, interpenum interptype)
static double getClamped(const ImageInterfaceTypePtr &image, int x, int y)
std::vector< ImageInterfaceType::PixelType >::iterator iterator
static ImageInterfaceTypePtr factory(std::size_t width, std::size_t height)
static std::size_t width(const ImageInterfaceTypePtr &image)
std::shared_ptr< EngineParameter > dx
static std::size_t width(ImageType &image)
static iterator begin(const ImageInterfaceTypePtr &image)
static float interpolate_pix(float *pix, float x, float y, int xsize, int ysize, interpenum interptype)
std::shared_ptr< EngineParameter > dy