42#include <visp3/core/vpImage.h>
46template <
typename PixelType> PixelType checkPixelAccess(
unsigned int height,
unsigned int width,
double v,
double u)
49 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
50 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
51 I[i][j] =
static_cast<PixelType
>(i * I.
getWidth() + j);
58template <>
vpRGBa checkPixelAccess(
unsigned int height,
unsigned int width,
double v,
double u)
61 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
62 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
65 static_cast<unsigned char>(i * I.
getWidth() + j));
72double randomDouble(
double a,
double b)
74 double random = (
static_cast<double>(rand())) /
static_cast<double>(RAND_MAX);
76 double r = random * diff;
80unsigned char randomPixelValue()
82 const int min = 0, max = 255;
83 return static_cast<unsigned char>((rand() % (max - min + 1) + min));
86template <
class PixelType> PixelType getValue(
const vpImage<PixelType> &I,
double i,
double j,
bool roundValue)
95 unsigned int iround =
static_cast<unsigned int>(floor(i));
96 unsigned int jround =
static_cast<unsigned int>(floor(j));
98 double rratio = i -
static_cast<double>(iround);
99 double cratio = j -
static_cast<double>(jround);
101 double rfrac = 1.0 - rratio;
102 double cfrac = 1.0 - cratio;
104 unsigned int iround_1 = (std::min)(I.
getHeight() - 1, iround + 1);
105 unsigned int jround_1 = (std::min)(I.
getWidth() - 1, jround + 1);
108 (
static_cast<double>(I[iround][jround]) * rfrac +
static_cast<double>(I[iround_1][jround]) * rratio) * cfrac +
109 (
static_cast<double>(I[iround][jround_1]) * rfrac +
static_cast<double>(I[iround_1][jround_1]) * rratio) * cratio;
111 return static_cast<PixelType
>(roundValue ?
vpMath::round(value) : value);
121 std::cout <<
"checkPixelAccess<unsigned char>(3, 4, 2, 3): "
122 <<
static_cast<unsigned int>(checkPixelAccess<unsigned char>(3, 4, 2, 3)) << std::endl;
124 std::cout <<
"checkPixelAccess<unsigned char>(3, 4, -2, -3): "
125 <<
static_cast<unsigned int>(checkPixelAccess<unsigned char>(3, 4, -2, -3)) << std::endl;
126 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
132 std::cout <<
"checkPixelAccess<unsigned char>(3, 4, 3, 4): "
133 <<
static_cast<unsigned int>(checkPixelAccess<unsigned char>(3, 4, 3, 4)) << std::endl;
134 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
141 std::cout <<
"checkPixelAccess<vpRGBa>(3, 4, 2, 3): " << checkPixelAccess<vpRGBa>(3, 4, 2, 3) << std::endl;
143 std::cout <<
"checkPixelAccess<vpRGBa>(3, 4, -2, -3): " << checkPixelAccess<vpRGBa>(3, 4, -2, -3) << std::endl;
144 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
150 std::cout <<
"checkPixelAccess<vpRGBa>(3, 4, 3, 4): " << checkPixelAccess<vpRGBa>(3, 4, 3, 4) << std::endl;
151 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
158 std::cout <<
"checkPixelAccess<int>(3, 4, 2, 3): " << checkPixelAccess<int>(3, 4, 2, 3) << std::endl;
160 std::cout <<
"checkPixelAccess<int>(3, 4, -2, -3): " << checkPixelAccess<int>(3, 4, -2, -3) << std::endl;
161 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
167 std::cout <<
"checkPixelAccess<int>(3, 4, 3, 4): " << checkPixelAccess<int>(3, 4, 3, 4) << std::endl;
168 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
175 std::cout <<
"checkPixelAccess<double>(3, 4, 2, 3): " << checkPixelAccess<double>(3, 4, 2, 3) << std::endl;
177 std::cout <<
"checkPixelAccess<double>(3, 4, -2, -3): " << checkPixelAccess<double>(3, 4, -2, -3) << std::endl;
178 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
184 std::cout <<
"checkPixelAccess<double>(3, 4, 3, 4): " << checkPixelAccess<double>(3, 4, 3, 4) << std::endl;
185 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
197 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
198 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
199 I[i][j] = randomPixelValue();
203 double diff_round = 0.0, diff = 0.0;
205 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
206 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
207 double idx1 = randomDouble(0, I.
getHeight() - 1);
208 double idx2 = randomDouble(0, I.
getWidth() - 1);
209 unsigned char val1 = I.
getValue(idx1, idx2);
210 unsigned char val2 = getValue<unsigned char>(I, idx1, idx2,
true);
211 unsigned char val3 = getValue<unsigned char>(I, idx1, idx2,
false);
213 diff_round += std::fabs((
double)val1 - (
double)val2);
214 diff += std::fabs((
double)val1 - (
double)val3);
218 double meanDiffRound = diff_round / I.
getSize();
219 double meanDiff = diff / I.
getSize();
220 std::cout <<
"diff_round: " << diff_round <<
" ; meanDiffRound: " << meanDiffRound << std::endl;
221 std::cout <<
"diff: " << diff <<
" ; meanDiff: " << meanDiff << std::endl;
222 const double maxInterpolationErrorDiff = 1.0;
223 if (std::fabs(meanDiffRound) > maxInterpolationErrorDiff) {
224 std::cerr <<
"Too much pixel difference between fixed-point vpImage::getValue(double, double) and old method."
233 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
234 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
235 I[i][j] = randomPixelValue();
239 std::vector<std::pair<double, double> > indexes;
240 for (
int cpt = 0; cpt < 1000000; cpt++) {
241 double idx1 = randomDouble(0, I.
getHeight() - 1);
242 double idx2 = randomDouble(0, I.
getWidth() - 1);
243 indexes.push_back(std::pair<double, double>(idx1, idx2));
248 for (
size_t cpt = 0; cpt < indexes.size(); cpt++) {
249 double idx1 = indexes[cpt].first;
250 double idx2 = indexes[cpt].second;
254 std::cout <<
"\nFixed-point vpImage::getValue(double, double), sum1: " << sum1 <<
" in " << t_optim <<
" ms"
259 for (
size_t cpt = 0; cpt < indexes.size(); cpt++) {
260 double idx1 = indexes[cpt].first;
261 double idx2 = indexes[cpt].second;
262 sum2 += getValue(I, idx1, idx2,
true);
265 std::cout <<
"Old method, sum2: " << sum2 <<
" in " << t_old <<
" ms" << std::endl;
266 std::cout <<
"Speed-up: " << t_old / t_optim <<
"X" << std::endl;
272 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
273 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
274 I[i][j] = randomPixelValue();
278 std::vector<std::pair<double, double> > indexes;
279 for (
int cpt = 0; cpt < 1000000; cpt++) {
280 double idx1 = randomDouble(0, I.
getHeight() - 1);
281 double idx2 = randomDouble(0, I.
getWidth() - 1);
282 indexes.push_back(std::pair<double, double>(idx1, idx2));
287 for (
size_t cpt = 0; cpt < indexes.size(); cpt++) {
288 double idx1 = indexes[cpt].first;
289 double idx2 = indexes[cpt].second;
293 std::cout <<
"\nFixed-point vpImage::getValue(double, double), sum1: " << sum1 <<
" in " << t_optim <<
" ms"
298 for (
size_t cpt = 0; cpt < indexes.size(); cpt++) {
299 double idx1 = indexes[cpt].first;
300 double idx2 = indexes[cpt].second;
301 sum2 += getValue(I, idx1, idx2,
false);
304 std::cout <<
"Old method (without vpMath::round()), sum2: " << sum2 <<
" in " << t_old <<
" ms" << std::endl;
305 std::cout <<
"Speed-up: " << t_old / t_optim <<
"X" << std::endl;
311 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
312 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
313 I[i][j] = randomPixelValue();
318 for (
unsigned int i = 0; i < I_copy.getHeight(); i++) {
319 double y =
static_cast<double>(i);
321 for (
unsigned int j = 0; j < I_copy.getWidth(); j++) {
322 double x =
static_cast<double>(j);
328 bool same = (I == I_copy);
329 std::cout <<
"\nCheck that getValue returns correct results for integer coordinates\n(I == I_copy)? " << same
332 std::cerr <<
"Issue with vpImage::getValue(double, double)!" << std::endl;
error that can be emitted by ViSP classes.
@ notInitializedError
Image not initialized.
@ notInTheImage
Pixel not in the image.
Definition of the vpImage class member functions.
unsigned int getWidth() const
Type getValue(unsigned int i, unsigned int j) const
unsigned int getSize() const
unsigned int getHeight() const
static int round(double x)
VISP_EXPORT double measureTimeMs()