42 #include <visp3/core/vpImage.h> 46 template<
typename PixelType> PixelType checkPixelAccess(
unsigned int height,
unsigned int width,
double v,
double u) {
48 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
49 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
50 I[i][j] =
static_cast<PixelType
>(i * I.
getWidth() + j);
57 template<>
vpRGBa checkPixelAccess(
unsigned int height,
unsigned int width,
double v,
double u) {
59 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
60 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
62 static_cast<unsigned char>(i * I.
getWidth() + j),
63 static_cast<unsigned char>(i * I.
getWidth() + j));
70 double randomDouble(
double a,
double b) {
71 double random = (
static_cast<double>(rand())) /
static_cast<double>(RAND_MAX);
73 double r = random * diff;
77 unsigned char randomPixelValue() {
78 const int min = 0, max = 255;
79 return static_cast<unsigned char>((rand() % (max - min + 1) + min));
82 template <
class PixelType> PixelType getValue(
const vpImage<PixelType> &I,
double i,
double j,
bool roundValue) {
90 unsigned int iround =
static_cast<unsigned int>(floor(i));
91 unsigned int jround =
static_cast<unsigned int>(floor(j));
93 double rratio = i -
static_cast<double>(iround);
94 double cratio = j -
static_cast<double>(jround);
96 double rfrac = 1.0 - rratio;
97 double cfrac = 1.0 - cratio;
99 unsigned int iround_1 = (std::min)(I.
getHeight() - 1, iround + 1);
100 unsigned int jround_1 = (std::min)(I.
getWidth() - 1, jround + 1);
102 double value = (
static_cast<double>(I[iround][jround]) * rfrac + static_cast<double>(I[iround_1][jround]) * rratio) * cfrac +
103 (static_cast<double>(I[iround][jround_1]) * rfrac +
static_cast<double>(I[iround_1][jround_1]) * rratio) * cratio;
105 return static_cast<PixelType
>(roundValue ?
vpMath::round(value) : value);
114 std::cout <<
"checkPixelAccess<unsigned char>(3, 4, 2, 3): " 115 <<
static_cast<unsigned int>(checkPixelAccess<unsigned char>(3, 4, 2, 3)) << std::endl;
117 std::cout <<
"checkPixelAccess<unsigned char>(3, 4, -2, -3): " 118 <<
static_cast<unsigned int>(checkPixelAccess<unsigned char>(3, 4, -2, -3)) << std::endl;
119 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
121 }
catch (...) { std::cout <<
"\n"; }
123 std::cout <<
"checkPixelAccess<unsigned char>(3, 4, 3, 4): " 124 <<
static_cast<unsigned int>(checkPixelAccess<unsigned char>(3, 4, 3, 4)) << std::endl;
125 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
127 }
catch (...) { std::cout <<
"\n"; }
130 std::cout <<
"checkPixelAccess<vpRGBa>(3, 4, 2, 3): " << checkPixelAccess<vpRGBa>(3, 4, 2, 3) << std::endl;
132 std::cout <<
"checkPixelAccess<vpRGBa>(3, 4, -2, -3): " << checkPixelAccess<vpRGBa>(3, 4, -2, -3) << std::endl;
133 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
135 }
catch (...) { std::cout <<
"\n"; }
137 std::cout <<
"checkPixelAccess<vpRGBa>(3, 4, 3, 4): " << checkPixelAccess<vpRGBa>(3, 4, 3, 4) << std::endl;
138 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
140 }
catch (...) { std::cout <<
"\n"; }
143 std::cout <<
"checkPixelAccess<int>(3, 4, 2, 3): " << checkPixelAccess<int>(3, 4, 2, 3) << std::endl;
145 std::cout <<
"checkPixelAccess<int>(3, 4, -2, -3): " << checkPixelAccess<int>(3, 4, -2, -3) << std::endl;
146 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
148 }
catch (...) { std::cout <<
"\n"; }
150 std::cout <<
"checkPixelAccess<int>(3, 4, 3, 4): " << checkPixelAccess<int>(3, 4, 3, 4) << std::endl;
151 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
153 }
catch (...) { std::cout <<
"\n"; }
156 std::cout <<
"checkPixelAccess<double>(3, 4, 2, 3): " << checkPixelAccess<double>(3, 4, 2, 3) << std::endl;
158 std::cout <<
"checkPixelAccess<double>(3, 4, -2, -3): " << checkPixelAccess<double>(3, 4, -2, -3) << std::endl;
159 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
161 }
catch (...) { std::cout <<
"\n"; }
163 std::cout <<
"checkPixelAccess<double>(3, 4, 3, 4): " << checkPixelAccess<double>(3, 4, 3, 4) << std::endl;
164 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
166 }
catch (...) { std::cout <<
"\n"; }
174 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
175 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
176 I[i][j] = randomPixelValue();
180 double diff_round = 0.0, diff = 0.0;
182 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
183 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
184 double idx1 = randomDouble(0, I.
getHeight() - 1);
185 double idx2 = randomDouble(0, I.
getWidth() - 1);
186 unsigned char val1 = I.
getValue(idx1, idx2);
187 unsigned char val2 = getValue<unsigned char>(I, idx1, idx2,
true);
188 unsigned char val3 = getValue<unsigned char>(I, idx1, idx2,
false);
190 diff_round += std::fabs((
double)val1 - (
double)val2);
191 diff += std::fabs((
double)val1 - (
double)val3);
195 double meanDiffRound = diff_round / I.getSize();
196 double meanDiff = diff / I.getSize();
197 std::cout <<
"diff_round: " << diff_round <<
" ; meanDiffRound: " << meanDiffRound << std::endl;
198 std::cout <<
"diff: " << diff <<
" ; meanDiff: " << meanDiff << std::endl;
199 const double maxInterpolationErrorDiff = 1.0;
200 if (std::fabs(meanDiffRound) > maxInterpolationErrorDiff) {
201 std::cerr <<
"Too much pixel difference between fixed-point vpImage::getValue(double, double) and old method." 210 for (
unsigned int i = 0; i < I.getHeight(); i++) {
211 for (
unsigned int j = 0; j < I.getWidth(); j++) {
212 I[i][j] = randomPixelValue();
216 std::vector<std::pair<double, double> > indexes;
217 for (
int cpt = 0; cpt < 1000000; cpt++) {
218 double idx1 = randomDouble(0, I.getHeight() - 1);
219 double idx2 = randomDouble(0, I.getWidth() - 1);
220 indexes.push_back(std::pair<double, double>(idx1, idx2));
225 for (
size_t cpt = 0; cpt < indexes.size(); cpt++) {
226 double idx1 = indexes[cpt].first;
227 double idx2 = indexes[cpt].second;
228 sum1 += I.getValue(idx1, idx2);
231 std::cout <<
"\nFixed-point vpImage::getValue(double, double), sum1: " << sum1 <<
" in " << t_optim <<
" ms" << std::endl;
235 for (
size_t cpt = 0; cpt < indexes.size(); cpt++) {
236 double idx1 = indexes[cpt].first;
237 double idx2 = indexes[cpt].second;
238 sum2 += getValue(I, idx1, idx2,
true);
241 std::cout <<
"Old method, sum2: " << sum2 <<
" in " << t_old <<
" ms" << std::endl;
242 std::cout <<
"Speed-up: " << t_old / t_optim <<
"X" << std::endl;
248 for (
unsigned int i = 0; i < I.getHeight(); i++) {
249 for (
unsigned int j = 0; j < I.getWidth(); j++) {
250 I[i][j] = randomPixelValue();
254 std::vector<std::pair<double, double> > indexes;
255 for (
int cpt = 0; cpt < 1000000; cpt++) {
256 double idx1 = randomDouble(0, I.getHeight() - 1);
257 double idx2 = randomDouble(0, I.getWidth() - 1);
258 indexes.push_back(std::pair<double, double>(idx1, idx2));
263 for (
size_t cpt = 0; cpt < indexes.size(); cpt++) {
264 double idx1 = indexes[cpt].first;
265 double idx2 = indexes[cpt].second;
266 sum1 += I.getValue(idx1, idx2);
269 std::cout <<
"\nFixed-point vpImage::getValue(double, double), sum1: " << sum1 <<
" in " << t_optim <<
" ms" << std::endl;
273 for (
size_t cpt = 0; cpt < indexes.size(); cpt++) {
274 double idx1 = indexes[cpt].first;
275 double idx2 = indexes[cpt].second;
276 sum2 += getValue(I, idx1, idx2,
false);
279 std::cout <<
"Old method (without vpMath::round()), sum2: " << sum2 <<
" in " << t_old <<
" ms" << std::endl;
280 std::cout <<
"Speed-up: " << t_old / t_optim <<
"X" << std::endl;
286 for (
unsigned int i = 0; i < I.getHeight(); i++) {
287 for (
unsigned int j = 0; j < I.getWidth(); j++) {
288 I[i][j] = randomPixelValue();
293 for (
unsigned int i = 0; i < I_copy.getHeight(); i++) {
294 double y =
static_cast<double>(i);
296 for (
unsigned int j = 0; j < I_copy.getWidth(); j++) {
297 double x =
static_cast<double>(j);
299 I_copy[i][j] = I.getValue(y, x);
303 bool same = (I == I_copy);
304 std::cout <<
"\nCheck that getValue returns correct results for integer coordinates\n(I == I_copy)? " << same << std::endl;
306 std::cerr <<
"Issue with vpImage::getValue(double, double)!" << std::endl;
unsigned int getWidth() const
error that can be emited by ViSP classes.
VISP_EXPORT double measureTimeMs()
Type getValue(unsigned int i, unsigned int j) const
static int round(double x)
unsigned int getHeight() const
Definition of the vpImage class member functions.