Skip to content

Commit 1b5058a

Browse files
authored
Merge pull request #63 from ebertin/fix/coordinate_shift
Fix/coordinate shift
2 parents b8c8f93 + 7ba8d0a commit 1b5058a

File tree

10 files changed

+159
-41
lines changed

10 files changed

+159
-41
lines changed

ModelFitting/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,16 @@ elements_add_unit_test(DependentParameter_test
5959
tests/src/Parameters/DependentParameter_test.cpp
6060
LINK_LIBRARIES ModelFitting TYPE Boost )
6161

62+
6263
find_package(CCfits)
6364
find_package(OpenCV)
6465

66+
if (OPENCV_FOUND)
67+
elements_add_unit_test(OpenCvMatImageTraits_test
68+
tests/src/Image/OpenCvMatImageTraits_test.cpp
69+
LINK_LIBRARIES ModelFitting TYPE Boost ${OpenCV_LIBS})
70+
endif ()
71+
6572
if (OPENCV_FOUND AND CCFITS_FOUND)
6673
elements_add_executable(Example1 src/program/Example1.cpp
6774
LINK_LIBRARIES ModelFitting ${CCFITS_LIBRARIES} ${OpenCV_LIBS}

ModelFitting/ModelFitting/Image/OpenCvMatImageTraits.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ struct ImageTraits<cv::Mat> {
106106
int window_height = height(window);
107107
for(int x_win=0; x_win < window_width; x_win++) {
108108
for(int y_win=0; y_win < window_height; y_win++) {
109-
double x = (x_win - 0.5 - x_shift) / scale_factor;
110-
double y = (y_win - 0.5 - y_shift) / scale_factor;
109+
double x = (x_win - 0.5 - x_shift) / scale_factor + 0.5;
110+
double y = (y_win - 0.5 - y_shift) / scale_factor + 0.5;
111111

112112
int xi = std::floor(x);
113113
int yi = std::floor(y);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* OpenCvMatImageTraits_test.cpp
3+
*
4+
* Created on: May 23, 2019
5+
* Author: mschefer
6+
*/
7+
8+
#include <iostream>
9+
10+
#include <boost/test/unit_test.hpp>
11+
12+
#include "ModelFitting/Image/OpenCvMatImageTraits.h"
13+
14+
using namespace ModelFitting;
15+
16+
//-----------------------------------------------------------------------------
17+
18+
BOOST_AUTO_TEST_SUITE (OpenCvMatImageTraits_test)
19+
20+
//-----------------------------------------------------------------------------
21+
22+
using Traits = ImageTraits<cv::Mat>;
23+
24+
void copy_test(unsigned int image_size) {
25+
auto image_original = Traits::factory(image_size,image_size);
26+
auto image_copy = Traits::factory(image_size,image_size);
27+
28+
for (unsigned int i=0; i < image_size; i++) {
29+
for (unsigned int j=0; j < image_size; j++) {
30+
Traits::at(image_original, i, j) = i * image_size + j;
31+
Traits::at(image_copy, i, j) = 0;
32+
}
33+
}
34+
35+
Traits::addImageToImage(image_copy, image_original, 1, Traits::width(image_original) / 2.0, Traits::height(image_original) / 2.0);
36+
37+
for (unsigned int i=0; i < image_size; i++) {
38+
for (unsigned int j=0; j < image_size; j++) {
39+
BOOST_CHECK_CLOSE(Traits::at(image_original, i, j), Traits::at(image_copy, i, j), .001);
40+
}
41+
}
42+
}
43+
44+
BOOST_AUTO_TEST_CASE (copy_test_even) {
45+
copy_test(128);
46+
}
47+
48+
BOOST_AUTO_TEST_CASE (copy_test_odd) {
49+
copy_test(127);
50+
}
51+
52+
//-----------------------------------------------------------------------------
53+
54+
BOOST_AUTO_TEST_SUITE_END ()

SEImplementation/CMakeLists.txt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,14 @@ elements_add_unit_test(PsfTask_test tests/src/Plugin/Psf/PsfTask_test.cpp
135135
LINK_LIBRARIES SEImplementation
136136
TYPE Boost)
137137
elements_add_unit_test(ImagePsf_test tests/src/Image/ImagePsf_test.cpp
138-
LINK_LIBRARIES SEImplementation
139-
TYPE Boost)
138+
LINK_LIBRARIES SEImplementation
139+
TYPE Boost)
140+
elements_add_unit_test(ImageInterfaceTraits_test tests/src/Image/ImageInterfaceTraits_test.cpp
141+
LINK_LIBRARIES SEImplementation
142+
TYPE Boost)
140143
elements_add_unit_test(BackgroundConvolution_test tests/src/Segmentation/BackgroundConvolution_test.cpp
141-
LINK_LIBRARIES SEImplementation
142-
TYPE Boost)
144+
LINK_LIBRARIES SEImplementation
145+
TYPE Boost)
143146

144147
#===============================================================================
145148
# Declare the Python programs here

SEImplementation/SEImplementation/Image/ImageInterfaceTraits.h

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,12 @@ struct ImageTraits<ImageInterfaceTypePtr> {
237237
return image->getData().end();
238238
}
239239

240-
static void addImageToImage(ImageInterfaceTypePtr& image1, const ImageInterfaceTypePtr& image2,
240+
// Adds the source_image to the traget image scaled by scale_factor and centered at x, y
241+
static void addImageToImage(ImageInterfaceTypePtr& target_image, const ImageInterfaceTypePtr& source_image,
241242
double scale_factor, double x, double y) {
242243
// Calculate the size in pixels of the image2 after in the scale of image1
243-
double scaled_width = width(image2) * scale_factor;
244-
double scaled_height = height(image2) * scale_factor;
244+
double scaled_width = width(source_image) * scale_factor;
245+
double scaled_height = height(source_image) * scale_factor;
245246
// Calculate the window of the image1 which is affected
246247
int x_min = std::floor(x - scaled_width / 2.);
247248
int x_max = std::ceil(x + scaled_width / 2.);
@@ -255,18 +256,18 @@ struct ImageTraits<ImageInterfaceTypePtr> {
255256
// Create the scaled and shifted window
256257
auto window = factory(window_width, window_height);
257258

258-
//shiftResize(image2, window, scale_factor, x_shift, y_shift);
259-
shiftResizeLancszos(image2, window, scale_factor, x_shift, y_shift);
259+
//shiftResize(source_image, window, scale_factor, x_shift, y_shift);
260+
shiftResizeLancszos(source_image, window, scale_factor, x_shift, y_shift);
260261

261262
// We need to correct the window for the scaling, so it has the same integral
262263
// with the image2
263264
double corr_factor = 1. / (scale_factor * scale_factor);
264265
// Add the window to the image1
265-
for(int x_im=std::max(x_min,0); x_im<std::min<int>(x_max, width(image1)); ++x_im) {
266-
for (int y_im=std::max(y_min,0); y_im<std::min<int>(y_max, height(image1)); ++y_im) {
266+
for(int x_im=std::max(x_min,0); x_im<std::min<int>(x_max, width(target_image)); ++x_im) {
267+
for (int y_im=std::max(y_min,0); y_im<std::min<int>(y_max, height(target_image)); ++y_im) {
267268
int x_win = x_im - x_min;
268269
int y_win = y_im - y_min;
269-
at(image1, x_im, y_im) += corr_factor * at(window, x_win, y_win);
270+
at(target_image, x_im, y_im) += corr_factor * at(window, x_win, y_win);
270271
}
271272
}
272273
}
@@ -280,8 +281,8 @@ struct ImageTraits<ImageInterfaceTypePtr> {
280281
int window_height = height(window);
281282
for(int x_win=0; x_win < window_width; x_win++) {
282283
for(int y_win=0; y_win < window_height; y_win++) {
283-
double x = (x_win - 0.5 - x_shift) / scale_factor;
284-
double y = (y_win - 0.5 - y_shift) / scale_factor;
284+
double x = (x_win + 0.5 - x_shift) / scale_factor - 0.5;
285+
double y = (y_win + 0.5 - y_shift) / scale_factor - 0.5;
285286

286287
int xi = std::floor(x);
287288
int yi = std::floor(y);
@@ -298,31 +299,24 @@ struct ImageTraits<ImageInterfaceTypePtr> {
298299
y_delta * ((1.0 - x_delta) * v01 + x_delta * v11);
299300
}
300301
}
301-
302302
}
303303

304304
static void shiftResizeLancszos(const ImageInterfaceTypePtr& source, ImageInterfaceTypePtr& window, double scale_factor, double x_shift, double y_shift) {
305305
int window_width = width(window);
306306
int window_height = height(window);
307307
for(int x_win=0; x_win < window_width; x_win++) {
308308
for(int y_win=0; y_win < window_height; y_win++) {
309-
float x = (x_win - x_shift) / scale_factor;
310-
float y = (y_win - y_shift) / scale_factor;
309+
float x = (x_win + 0.5 - x_shift) / scale_factor + 0.5;
310+
float y = (y_win + 0.5 - y_shift) / scale_factor + 0.5;
311311

312312
at(window, x_win, y_win) = interpolate_pix(&source->getData()[0], x, y, source->getWidth(), source->getHeight(), INTERP_LANCZOS4);
313313
}
314314
}
315315

316316
}
317317

318-
319318
}; // end of class ImageTraits<ImageInterfaceTypePtr>
320319

321-
//ImageInterfaceTypePtr operator*(std::shared_ptr<const Image<ImageInterfaceType::PixelType>> image, ImageInterfaceType::PixelType factor) {
322-
// auto mult_image = SExtractor::MultiplyImage<ImageInterfaceType::PixelType>::create(image, factor);
323-
// return ImageInterfaceType::create(*mult_image);
324-
//}
325-
326320
} // end of namespace ModelFitting
327321

328322

SEImplementation/src/lib/Plugin/FlexibleModelFitting/FlexibleModelFittingModel.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@ void FlexibleModelFittingPointModel::addForSource(FlexibleModelFittingParameterM
6161

6262
auto pixel_x = std::make_shared<DependentParameter<BasicParameter, BasicParameter>>(
6363
[reference_coordinates, coordinates, offset](double x, double y) {
64-
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_x - offset.m_x - 0.5;
64+
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_x - offset.m_x + 0.5;
6565
}, *manager.getParameter(source, m_x), *manager.getParameter(source, m_y));
6666
auto pixel_y = std::make_shared<DependentParameter<BasicParameter, BasicParameter>>(
6767
[reference_coordinates, coordinates, offset](double x, double y) {
68-
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_y - offset.m_y - 0.5;
68+
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_y - offset.m_y + 0.5;
6969
}, *manager.getParameter(source, m_x), *manager.getParameter(source, m_y));
7070

7171
manager.storeParameter(pixel_x);
@@ -84,11 +84,11 @@ void FlexibleModelFittingExponentialModel::addForSource(FlexibleModelFittingPara
8484

8585
auto pixel_x = std::make_shared<DependentParameter<BasicParameter, BasicParameter>>(
8686
[reference_coordinates, coordinates, offset](double x, double y) {
87-
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_x - offset.m_x - 0.5;
87+
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_x - offset.m_x + 0.5;
8888
}, *manager.getParameter(source, m_x), *manager.getParameter(source, m_y));
8989
auto pixel_y = std::make_shared<DependentParameter<BasicParameter, BasicParameter>>(
9090
[reference_coordinates, coordinates, offset](double x, double y) {
91-
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_y - offset.m_y - 0.5;
91+
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_y - offset.m_y + 0.5;
9292
}, *manager.getParameter(source, m_x), *manager.getParameter(source, m_y));
9393

9494

@@ -136,11 +136,11 @@ void FlexibleModelFittingDevaucouleursModel::addForSource(FlexibleModelFittingPa
136136

137137
auto pixel_x = std::make_shared<DependentParameter<BasicParameter, BasicParameter>>(
138138
[reference_coordinates, coordinates, offset](double x, double y) {
139-
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_x - offset.m_x - 0.5;
139+
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_x - offset.m_x + 0.5;
140140
}, *manager.getParameter(source, m_x), *manager.getParameter(source, m_y));
141141
auto pixel_y = std::make_shared<DependentParameter<BasicParameter, BasicParameter>>(
142142
[reference_coordinates, coordinates, offset](double x, double y) {
143-
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_y - offset.m_y - 0.5;
143+
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_y - offset.m_y + 0.5;
144144
}, *manager.getParameter(source, m_x), *manager.getParameter(source, m_y));
145145

146146

@@ -194,11 +194,11 @@ void FlexibleModelFittingSersicModel::addForSource(FlexibleModelFittingParameter
194194

195195
auto pixel_x = std::make_shared<DependentParameter<BasicParameter, BasicParameter>>(
196196
[reference_coordinates, coordinates, offset](double x, double y) {
197-
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_x - offset.m_x - 0.5;
197+
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_x - offset.m_x + 0.5;
198198
}, *manager.getParameter(source, m_x), *manager.getParameter(source, m_y));
199199
auto pixel_y = std::make_shared<DependentParameter<BasicParameter, BasicParameter>>(
200200
[reference_coordinates, coordinates, offset](double x, double y) {
201-
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_y - offset.m_y - 0.5;
201+
return coordinates->worldToImage(reference_coordinates->imageToWorld(ImageCoordinate(x-1, y-1))).m_y - offset.m_y + 0.5;
202202
}, *manager.getParameter(source, m_x), *manager.getParameter(source, m_y));
203203

204204
ManualParameter x_scale(1); // we don't scale the x coordinate

SEImplementation/src/lib/Plugin/MoffatModelFitting/MoffatModelFittingPlugin.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ void MoffatModelFittingPlugin::registerPlugin(PluginAPI& plugin_api) {
2121
plugin_api.getOutputRegistry().registerColumnConverter<MoffatModelFitting, double>(
2222
"smf_x",
2323
[](const MoffatModelFitting& prop) {
24-
return prop.getX();
24+
return prop.getX() + 1.0;
2525
},
2626
"[pixel]",
2727
"X-position of the Moffat fit"
@@ -30,7 +30,7 @@ void MoffatModelFittingPlugin::registerPlugin(PluginAPI& plugin_api) {
3030
plugin_api.getOutputRegistry().registerColumnConverter<MoffatModelFitting, double>(
3131
"smf_y",
3232
[](const MoffatModelFitting& prop) {
33-
return prop.getY();
33+
return prop.getY() + 1.0;
3434
},
3535
"[pixel]",
3636
"Y-position of the Moffat fit"

SEImplementation/src/lib/Plugin/MoffatModelFitting/MoffatModelFittingTask.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ struct SourceModel {
9090
dx(0, make_unique<SigmoidConverter>(-pos_range, pos_range)),
9191
dy(0, make_unique<SigmoidConverter>(-pos_range, pos_range)),
9292

93-
x([x_guess](double dx) { return dx + x_guess - 0.5; }, dx),
94-
y([y_guess](double dy) { return dy + y_guess - 0.5; }, dy),
93+
x([x_guess](double dx) { return dx + x_guess + 0.5; }, dx),
94+
y([y_guess](double dy) { return dy + y_guess + 0.5; }, dy),
9595

9696
// FIXME
9797
exp_i0_guess(exp_flux_guess / (M_PI * 2.0 * 0.346 * exp_radius_guess * exp_radius_guess * exp_aspect_guess)),
@@ -266,8 +266,8 @@ void MoffatModelFittingTask::computeProperties(SourceInterface& source) const {
266266

267267
auto coordinate_system = source.getProperty<DetectionFrame>().getFrame()->getCoordinateSystem();
268268

269-
SeFloat x = stamp_top_left.m_x + source_model->x.getValue();
270-
SeFloat y = stamp_top_left.m_y + source_model->y.getValue();
269+
SeFloat x = stamp_top_left.m_x + source_model->x.getValue() - 0.5f;
270+
SeFloat y = stamp_top_left.m_y + source_model->y.getValue() - 0.5f;
271271

272272
source.setProperty<MoffatModelFitting>(
273273
x, y,
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* ImageInterfaceTraits_test.cpp
3+
*
4+
* Created on: May 23, 2019
5+
* Author: mschefer
6+
*/
7+
8+
#include <iostream>
9+
10+
#include <boost/test/unit_test.hpp>
11+
12+
#include "SEImplementation/Image/ImageInterfaceTraits.h"
13+
14+
using namespace SExtractor;
15+
using namespace ModelFitting;
16+
17+
//-----------------------------------------------------------------------------
18+
19+
BOOST_AUTO_TEST_SUITE (ImageInterfaceTraits_test)
20+
21+
//-----------------------------------------------------------------------------
22+
23+
using Traits = ImageTraits<ImageInterfaceTypePtr>;
24+
25+
26+
// Note: for performance our Lanczos function does not interpolate the border (we assume images to be added are
27+
// source models with borders going to zero and it shouldn't matter.
28+
29+
void copy_test(unsigned int image_size, unsigned int check_border) {
30+
auto image_original = Traits::factory(image_size,image_size);
31+
auto image_copy = Traits::factory(image_size,image_size);
32+
33+
for (unsigned int i=0; i < image_size; i++) {
34+
for (unsigned int j=0; j < image_size; j++) {
35+
Traits::at(image_original, i, j) = i * image_size + j;
36+
Traits::at(image_copy, i, j) = 0;
37+
}
38+
}
39+
40+
Traits::addImageToImage(image_copy, image_original, 1, Traits::width(image_original) / 2.0, Traits::height(image_original) / 2.0);
41+
42+
for (unsigned int i=check_border; i < image_size - check_border; i++) {
43+
for (unsigned int j=check_border; j < image_size - check_border; j++) {
44+
BOOST_CHECK_CLOSE(Traits::at(image_original, i, j), Traits::at(image_copy, i, j), .001);
45+
}
46+
}
47+
}
48+
49+
BOOST_AUTO_TEST_CASE (copy_test_even) {
50+
copy_test(128, 4);
51+
}
52+
53+
BOOST_AUTO_TEST_CASE (copy_test_odd) {
54+
copy_test(127, 4);
55+
}
56+
57+
58+
//-----------------------------------------------------------------------------
59+
60+
BOOST_AUTO_TEST_SUITE_END ()

SEImplementation/tests/src/Plugin/MoffatModelFitting/MoffatModelFitting_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ BOOST_FIXTURE_TEST_CASE(modelfitting_test, MoffatModelFittingFixture) {
8787

8888
auto moffat_model = source->getProperty<MoffatModelFitting>();
8989
BOOST_CHECK(moffat_model.getIterations() > 0);
90-
BOOST_CHECK_CLOSE(moffat_model.getX(), 9.5, 1);
91-
BOOST_CHECK_CLOSE(moffat_model.getY(), 9.5, 1);
90+
BOOST_CHECK_CLOSE(moffat_model.getX(), 10.0, 1);
91+
BOOST_CHECK_CLOSE(moffat_model.getY(), 10.0, 1);
9292
}
9393

9494
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)