42 #include <visp3/core/vpImage.h>
44 #ifdef ENABLE_VISP_NAMESPACE
50 template <
typename PixelType> PixelType checkPixelAccess(
unsigned int height,
unsigned int width,
double v,
double u)
53 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
54 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
55 I[i][j] =
static_cast<PixelType
>(i * I.
getWidth() + j);
62 template <>
vpRGBa checkPixelAccess(
unsigned int height,
unsigned int width,
double v,
double u)
65 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
66 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
69 static_cast<unsigned char>(i * I.
getWidth() + j));
76 double randomDouble(
double a,
double b)
78 double random = (
static_cast<double>(rand())) /
static_cast<double>(RAND_MAX);
80 double r = random * diff;
84 unsigned char randomPixelValue()
86 const int min = 0, max = 255;
87 return static_cast<unsigned char>((rand() % (max - min + 1) + min));
90 template <
class PixelType> PixelType getValue(
const vpImage<PixelType> &I,
double i,
double j,
bool roundValue)
99 unsigned int iround =
static_cast<unsigned int>(floor(i));
100 unsigned int jround =
static_cast<unsigned int>(floor(j));
102 double rratio = i -
static_cast<double>(iround);
103 double cratio = j -
static_cast<double>(jround);
105 double rfrac = 1.0 - rratio;
106 double cfrac = 1.0 - cratio;
108 unsigned int iround_1 = std::min<unsigned int>(I.
getHeight() - 1, iround + 1);
109 unsigned int jround_1 = std::min<unsigned int>(I.
getWidth() - 1, jround + 1);
112 (
static_cast<double>(I[iround][jround]) * rfrac +
static_cast<double>(I[iround_1][jround]) * rratio) * cfrac +
113 (
static_cast<double>(I[iround][jround_1]) * rfrac +
static_cast<double>(I[iround_1][jround_1]) * rratio) * cratio;
115 return static_cast<PixelType
>(roundValue ?
vpMath::round(value) : value);
125 std::cout <<
"checkPixelAccess<unsigned char>(3, 4, 2, 3): "
126 <<
static_cast<unsigned int>(checkPixelAccess<unsigned char>(3, 4, 2, 3)) << std::endl;
128 std::cout <<
"checkPixelAccess<unsigned char>(3, 4, -2, -3): "
129 <<
static_cast<unsigned int>(checkPixelAccess<unsigned char>(3, 4, -2, -3)) << std::endl;
130 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
137 std::cout <<
"checkPixelAccess<unsigned char>(3, 4, 3, 4): "
138 <<
static_cast<unsigned int>(checkPixelAccess<unsigned char>(3, 4, 3, 4)) << std::endl;
139 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
147 std::cout <<
"checkPixelAccess<vpRGBa>(3, 4, 2, 3): " << checkPixelAccess<vpRGBa>(3, 4, 2, 3) << std::endl;
149 std::cout <<
"checkPixelAccess<vpRGBa>(3, 4, -2, -3): " << checkPixelAccess<vpRGBa>(3, 4, -2, -3) << std::endl;
150 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
157 std::cout <<
"checkPixelAccess<vpRGBa>(3, 4, 3, 4): " << checkPixelAccess<vpRGBa>(3, 4, 3, 4) << std::endl;
158 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
166 std::cout <<
"checkPixelAccess<int>(3, 4, 2, 3): " << checkPixelAccess<int>(3, 4, 2, 3) << std::endl;
168 std::cout <<
"checkPixelAccess<int>(3, 4, -2, -3): " << checkPixelAccess<int>(3, 4, -2, -3) << std::endl;
169 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
176 std::cout <<
"checkPixelAccess<int>(3, 4, 3, 4): " << checkPixelAccess<int>(3, 4, 3, 4) << std::endl;
177 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
185 std::cout <<
"checkPixelAccess<double>(3, 4, 2, 3): " << checkPixelAccess<double>(3, 4, 2, 3) << std::endl;
187 std::cout <<
"checkPixelAccess<double>(3, 4, -2, -3): " << checkPixelAccess<double>(3, 4, -2, -3) << std::endl;
188 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
195 std::cout <<
"checkPixelAccess<double>(3, 4, 3, 4): " << checkPixelAccess<double>(3, 4, 3, 4) << std::endl;
196 std::cerr <<
"Out of image access exception should have been thrown" << std::endl;
209 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
210 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
211 I[i][j] = randomPixelValue();
215 double diff_round = 0.0, diff = 0.0;
217 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
218 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
219 double idx1 = randomDouble(0, I.
getHeight() - 1);
220 double idx2 = randomDouble(0, I.
getWidth() - 1);
221 unsigned char val1 = I.
getValue(idx1, idx2);
222 unsigned char val2 = getValue<unsigned char>(I, idx1, idx2,
true);
223 unsigned char val3 = getValue<unsigned char>(I, idx1, idx2,
false);
225 diff_round += std::fabs((
double)val1 - (
double)val2);
226 diff += std::fabs((
double)val1 - (
double)val3);
230 double meanDiffRound = diff_round / I.
getSize();
231 double meanDiff = diff / I.
getSize();
232 std::cout <<
"diff_round: " << diff_round <<
" ; meanDiffRound: " << meanDiffRound << std::endl;
233 std::cout <<
"diff: " << diff <<
" ; meanDiff: " << meanDiff << std::endl;
234 const double maxInterpolationErrorDiff = 1.0;
235 if (std::fabs(meanDiffRound) > maxInterpolationErrorDiff) {
236 std::cerr <<
"Too much pixel difference between fixed-point vpImage::getValue(double, double) and old method."
245 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
246 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
247 I[i][j] = randomPixelValue();
251 std::vector<std::pair<double, double> > indexes;
252 for (
int cpt = 0; cpt < 1000000; cpt++) {
253 double idx1 = randomDouble(0, I.
getHeight() - 1);
254 double idx2 = randomDouble(0, I.
getWidth() - 1);
255 indexes.push_back(std::pair<double, double>(idx1, idx2));
260 for (
size_t cpt = 0; cpt < indexes.size(); cpt++) {
261 double idx1 = indexes[cpt].first;
262 double idx2 = indexes[cpt].second;
266 std::cout <<
"\nFixed-point vpImage::getValue(double, double), sum1: " << sum1 <<
" in " << t_optim <<
" ms"
271 for (
size_t cpt = 0; cpt < indexes.size(); cpt++) {
272 double idx1 = indexes[cpt].first;
273 double idx2 = indexes[cpt].second;
274 sum2 += getValue(I, idx1, idx2,
true);
277 std::cout <<
"Old method, sum2: " << sum2 <<
" in " << t_old <<
" ms" << std::endl;
278 std::cout <<
"Speed-up: " << t_old / t_optim <<
"X" << std::endl;
284 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
285 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
286 I[i][j] = randomPixelValue();
290 std::vector<std::pair<double, double> > indexes;
291 for (
int cpt = 0; cpt < 1000000; cpt++) {
292 double idx1 = randomDouble(0, I.
getHeight() - 1);
293 double idx2 = randomDouble(0, I.
getWidth() - 1);
294 indexes.push_back(std::pair<double, double>(idx1, idx2));
299 for (
size_t cpt = 0; cpt < indexes.size(); cpt++) {
300 double idx1 = indexes[cpt].first;
301 double idx2 = indexes[cpt].second;
305 std::cout <<
"\nFixed-point vpImage::getValue(double, double), sum1: " << sum1 <<
" in " << t_optim <<
" ms"
310 for (
size_t cpt = 0; cpt < indexes.size(); cpt++) {
311 double idx1 = indexes[cpt].first;
312 double idx2 = indexes[cpt].second;
313 sum2 += getValue(I, idx1, idx2,
false);
316 std::cout <<
"Old method (without vpMath::round()), sum2: " << sum2 <<
" in " << t_old <<
" ms" << std::endl;
317 std::cout <<
"Speed-up: " << t_old / t_optim <<
"X" << std::endl;
323 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
324 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
325 I[i][j] = randomPixelValue();
330 for (
unsigned int i = 0; i < I_copy.getHeight(); i++) {
331 double y =
static_cast<double>(i);
333 for (
unsigned int j = 0; j < I_copy.getWidth(); j++) {
334 double x =
static_cast<double>(j);
340 bool same = (I == I_copy);
341 std::cout <<
"\nCheck that getValue returns correct results for integer coordinates\n(I == I_copy)? " << same
344 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()