Visual Servoing Platform  version 3.2.0 under development (2019-01-22)
testImageDifference.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Image difference.
33  *
34  * Authors:
35  * Fabien Spindler
36  * Souriya Trinh
37  *
38  *****************************************************************************/
39 
40 #include <iostream>
41 #include <visp3/core/vpImageTools.h>
42 
48 namespace {
49 void regularImageDifference(const vpImage<unsigned char> &I1, const vpImage<unsigned char> &I2, vpImage<unsigned char> &Idiff)
50 {
51  if ((I1.getHeight() != I2.getHeight()) || (I1.getWidth() != I2.getWidth())) {
52  throw(vpException(vpException::dimensionError, "The two images have not the same size"));
53  }
54 
55  if ((I1.getHeight() != Idiff.getHeight()) || (I1.getWidth() != Idiff.getWidth()))
56  Idiff.resize(I1.getHeight(), I1.getWidth());
57 
58  unsigned int n = I1.getHeight() * I1.getWidth();
59  for (unsigned int b = 0; b < n; b++) {
60  int diff = I1.bitmap[b] - I2.bitmap[b] + 128u;
61  Idiff.bitmap[b] = static_cast<unsigned char>(vpMath::maximum(vpMath::minimum(diff, 255), 0));
62  }
63 }
64 
65 void regularImageDifference(const vpImage<vpRGBa> &I1, const vpImage<vpRGBa> &I2, vpImage<vpRGBa> &Idiff)
66 {
67  if ((I1.getHeight() != I2.getHeight()) || (I1.getWidth() != I2.getWidth())) {
68  throw(vpException(vpException::dimensionError, "Cannot compute image difference. The two images "
69  "(%ux%u) and (%ux%u) have not the same size",
70  I1.getWidth(), I1.getHeight(), I2.getWidth(), I2.getHeight()));
71  }
72 
73  if ((I1.getHeight() != Idiff.getHeight()) || (I1.getWidth() != Idiff.getWidth()))
74  Idiff.resize(I1.getHeight(), I1.getWidth());
75 
76  unsigned int n = I1.getHeight() * I1.getWidth();
77  for (unsigned int b = 0; b < n; b++) {
78  int diffR = I1.bitmap[b].R - I2.bitmap[b].R + 128;
79  int diffG = I1.bitmap[b].G - I2.bitmap[b].G + 128;
80  int diffB = I1.bitmap[b].B - I2.bitmap[b].B + 128;
81  int diffA = I1.bitmap[b].A - I2.bitmap[b].A + 128;
82  Idiff.bitmap[b].R = static_cast<unsigned char>(vpMath::maximum(vpMath::minimum(diffR, 255), 0));
83  Idiff.bitmap[b].G = static_cast<unsigned char>(vpMath::maximum(vpMath::minimum(diffG, 255), 0));
84  Idiff.bitmap[b].B = static_cast<unsigned char>(vpMath::maximum(vpMath::minimum(diffB, 255), 0));
85  Idiff.bitmap[b].A = static_cast<unsigned char>(vpMath::maximum(vpMath::minimum(diffA, 255), 0));
86  }
87 }
88 }
89 
90 int main()
91 {
92  const unsigned int width = 501, height = 447;
93  vpImage<unsigned char> I1(height,width), I2(height,width), Idiff_regular(height,width), Idiff_sse(height,width);
94  vpImage<vpRGBa> I1_color(height, width), I2_color(height, width), Idiff_regular_color(height, width), Idiff_sse_color(height, width);
95  for (unsigned int i = 0; i < I1.getRows(); i++) {
96  for (unsigned int j = 0; j < I1.getCols(); j++) {
97  I1[i][j] = static_cast<unsigned char>(i*I1.getCols() + j);
98  I1_color[i][j] = vpRGBa(static_cast<unsigned char>(i*I1.getCols() + j));
99  }
100  }
101 
102  {
103  std::cout << "Grayscale:" << std::endl;
104 
105  double t_regular = 0.0, t_sse = 0.0;
106  for (unsigned int cpt = 0; cpt < 256; cpt++) {
107  for (unsigned int i = 0; i < I2.getRows(); i++) {
108  for (unsigned int j = 0; j < I2.getCols(); j++) {
109  I2[i][j] = static_cast<unsigned char>(i*I2.getCols() + j + cpt);
110  }
111  }
112 
113  double t = vpTime::measureTimeMs();
114  regularImageDifference(I1, I2, Idiff_regular);
115  t_regular += vpTime::measureTimeMs() - t;
116 
117  t = vpTime::measureTimeMs();
118  vpImageTools::imageDifference(I1, I2, Idiff_sse);
119  t_sse += vpTime::measureTimeMs() - t;
120 
121  bool same_result = Idiff_regular == Idiff_sse;
122  std::cout << "(Idiff_regular == Idiff_sse)? " << same_result << std::endl;
123  if (!same_result) {
124  std::cerr << "Problem with vpImageTools::imageDifference()" << std::endl;
125  return EXIT_FAILURE;
126  }
127  }
128 
129  std::cout << "t_regular: " << t_regular << " ms ; mean t_regular: " << t_regular/256 << " ms" << std::endl;
130  std::cout << "t_sse: " << t_sse << " ms ; mean t_sse: " << t_sse/256 << " ms" << std::endl;
131  std::cout << "speed-up: " << t_regular / t_sse << " X" << std::endl;
132  }
133 
134  {
135  std::cout << "\nColor:" << std::endl;
136 
137  double t_regular = 0.0, t_sse = 0.0;
138  for (unsigned int cpt = 0; cpt < 256; cpt++) {
139  for (unsigned int i = 0; i < I2.getRows(); i++) {
140  for (unsigned int j = 0; j < I2.getCols(); j++) {
141  I2_color[i][j] = vpRGBa(static_cast<unsigned char>(i*I2.getCols() + j + cpt));
142  }
143  }
144 
145  double t = vpTime::measureTimeMs();
146  regularImageDifference(I1_color, I2_color, Idiff_regular_color);
147  t_regular += vpTime::measureTimeMs() - t;
148 
149  t = vpTime::measureTimeMs();
150  vpImageTools::imageDifference(I1_color, I2_color, Idiff_sse_color);
151  t_sse += vpTime::measureTimeMs() - t;
152 
153  bool same_result = Idiff_regular_color == Idiff_sse_color;
154  std::cout << "(Idiff_regular_color == Idiff_sse_color)? " << same_result << std::endl;
155  if (!same_result) {
156  std::cerr << "Problem with vpImageTools::imageDifference()" << std::endl;
157  return EXIT_FAILURE;
158  }
159  }
160 
161  std::cout << "t_regular: " << t_regular << " ms ; mean t_regular: " << t_regular/256 << " ms" << std::endl;
162  std::cout << "t_sse: " << t_sse << " ms ; mean t_sse: " << t_sse/256 << " ms" << std::endl;
163  std::cout << "speed-up: " << t_regular / t_sse << " X" << std::endl;
164  }
165 
166  return EXIT_SUCCESS;
167 }
unsigned int getCols() const
Definition: vpImage.h:169
unsigned int getWidth() const
Definition: vpImage.h:239
unsigned char B
Blue component.
Definition: vpRGBa.h:150
Type * bitmap
points toward the bitmap
Definition: vpImage.h:133
error that can be emited by ViSP classes.
Definition: vpException.h:71
unsigned char G
Green component.
Definition: vpRGBa.h:149
static void imageDifference(const vpImage< unsigned char > &I1, const vpImage< unsigned char > &I2, vpImage< unsigned char > &Idiff)
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:88
Definition: vpRGBa.h:66
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:137
unsigned int getRows() const
Definition: vpImage.h:211
unsigned char A
Additionnal component.
Definition: vpRGBa.h:151
void resize(const unsigned int h, const unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:866
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:145
unsigned char R
Red component.
Definition: vpRGBa.h:148
unsigned int getHeight() const
Definition: vpImage.h:178