Visual Servoing Platform version 3.5.0
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
48namespace {
49void 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
65void 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
90int main()
91{
92 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
118 vpImageTools::imageDifference(I1, I2, Idiff_sse);
119 t_sse += vpTime::measureTimeMs() - t;
120
121 if (Idiff_regular != Idiff_sse) {
122 std::cerr << "Problem with vpImageTools::imageDifference()" << std::endl;
123 return EXIT_FAILURE;
124 }
125 }
126
127 std::cout << "(Idiff_regular == Idiff_sse)" << std::endl;
128 std::cout << "t_regular: " << t_regular << " ms ; mean t_regular: " << t_regular/256 << " ms" << std::endl;
129 std::cout << "t_sse: " << t_sse << " ms ; mean t_sse: " << t_sse/256 << " ms" << std::endl;
130 std::cout << "speed-up: " << t_regular / t_sse << " X" << std::endl;
131 }
132
133 {
134 std::cout << "\nColor:" << std::endl;
135
136 double t_regular = 0.0, t_sse = 0.0;
137 for (unsigned int cpt = 0; cpt < 256; cpt++) {
138 for (unsigned int i = 0; i < I2.getRows(); i++) {
139 for (unsigned int j = 0; j < I2.getCols(); j++) {
140 I2_color[i][j] = vpRGBa(static_cast<unsigned char>(i*I2.getCols() + j + cpt));
141 }
142 }
143
144 double t = vpTime::measureTimeMs();
145 regularImageDifference(I1_color, I2_color, Idiff_regular_color);
146 t_regular += vpTime::measureTimeMs() - t;
147
149 vpImageTools::imageDifference(I1_color, I2_color, Idiff_sse_color);
150 t_sse += vpTime::measureTimeMs() - t;
151
152 if (Idiff_regular_color != Idiff_sse_color) {
153 std::cerr << "Problem with vpImageTools::imageDifference()" << std::endl;
154 return EXIT_FAILURE;
155 }
156 }
157
158 std::cout << "(Idiff_regular_color == Idiff_sse_color)" << std::endl;
159 std::cout << "t_regular: " << t_regular << " ms ; mean t_regular: " << t_regular/256 << " ms" << std::endl;
160 std::cout << "t_sse: " << t_sse << " ms ; mean t_sse: " << t_sse/256 << " ms" << std::endl;
161 std::cout << "speed-up: " << t_regular / t_sse << " X" << std::endl;
162 }
163
164 return EXIT_SUCCESS;
165}
error that can be emited by ViSP classes.
Definition: vpException.h:72
@ dimensionError
Bad dimension.
Definition: vpException.h:95
static void imageDifference(const vpImage< unsigned char > &I1, const vpImage< unsigned char > &I2, vpImage< unsigned char > &Idiff)
unsigned int getWidth() const
Definition: vpImage.h:246
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:800
unsigned int getCols() const
Definition: vpImage.h:179
Type * bitmap
points toward the bitmap
Definition: vpImage.h:143
unsigned int getHeight() const
Definition: vpImage.h:188
unsigned int getRows() const
Definition: vpImage.h:218
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:145
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:153
Definition: vpRGBa.h:67
unsigned char B
Blue component.
Definition: vpRGBa.h:150
unsigned char R
Red component.
Definition: vpRGBa.h:148
unsigned char G
Green component.
Definition: vpRGBa.h:149
unsigned char A
Additionnal component.
Definition: vpRGBa.h:151
VISP_EXPORT double measureTimeMs()