Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
testImageComparison.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2023 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 https://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 * Test the comparison of two vpImage objects of the same type.
33 *
34 * Authors:
35 * Souriya Trinh
36 *
37*****************************************************************************/
44#include <visp3/core/vpImage.h>
45#include <visp3/core/vpIoTools.h>
46#include <visp3/io/vpImageIo.h>
47#include <visp3/io/vpParseArgv.h>
48
49// List of allowed command line options
50#define GETOPTARGS "cdi:h"
51
52void usage(const char *name, const char *badparam, std::string ipath);
53bool getOptions(int argc, const char **argv, std::string &ipath);
54
55/*
56 Print the program options.
57
58 \param name : Program name.
59 \param badparam : Bad parameter name.
60 \param ipath: Input image path.
61 */
62void usage(const char *name, const char *badparam, std::string ipath)
63{
64 fprintf(stdout, "\n\
65Test the comparison of two vpImage objects of the same type.\n\
66\n\
67SYNOPSIS\n\
68 %s [-i <input image path>]\n\
69 [-h]\n \
70",
71 name);
72
73 fprintf(stdout, "\n\
74OPTIONS: Default\n\
75 -i <input image path> %s\n\
76 Set image input path.\n\
77 From this path read \"Klimt/Klimt.pgm\"\n\
78 and \"Klimt/Klimt.ppm\" images.\n\
79 Setting the VISP_INPUT_IMAGE_PATH environment\n\
80 variable produces the same behaviour than using\n\
81 this option.\n\
82\n\
83 -h\n\
84 Print the help.\n\n",
85 ipath.c_str());
86
87 if (badparam)
88 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
89}
90
99bool getOptions(int argc, const char **argv, std::string &ipath)
100{
101 const char *optarg_;
102 int c;
103 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
104
105 switch (c) {
106 case 'i':
107 ipath = optarg_;
108 break;
109 case 'h':
110 usage(argv[0], NULL, ipath);
111 return false;
112 break;
113
114 case 'c':
115 case 'd':
116 break;
117
118 default:
119 usage(argv[0], optarg_, ipath);
120 return false;
121 break;
122 }
123 }
124
125 if ((c == 1) || (c == -1)) {
126 // standalone param or error
127 usage(argv[0], NULL, ipath);
128 std::cerr << "ERROR: " << std::endl;
129 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
130 return false;
131 }
132
133 return true;
134}
135
136int main(int argc, const char **argv)
137{
138 try {
139 std::string env_ipath;
140 std::string opt_ipath;
141 std::string ipath;
142 std::string filename;
143 std::string username;
144
145 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
146 // environment variable value
148
149 // Set the default input path
150 if (!env_ipath.empty()) {
151 ipath = env_ipath;
152 }
153
154 // Get the user login name
155 vpIoTools::getUserName(username);
156
157 // Read the command line options
158 if (getOptions(argc, argv, opt_ipath) == false) {
159 return EXIT_FAILURE;
160 }
161
162 // Get the option values
163 if (!opt_ipath.empty()) {
164 ipath = opt_ipath;
165 }
166
167 // Compare ipath and env_ipath. If they differ, we take into account
168 // the input path comming from the command line option
169 if (!opt_ipath.empty() && !env_ipath.empty()) {
170 if (ipath != env_ipath) {
171 std::cout << std::endl << "WARNING: " << std::endl;
172 std::cout << " Since -i <visp image path=" << ipath << "> "
173 << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
174 << " we skip the environment variable." << std::endl;
175 }
176 }
177
178 // Test if an input path is set
179 if (opt_ipath.empty() && env_ipath.empty()) {
180 usage(argv[0], NULL, ipath);
181 std::cerr << std::endl << "ERROR:" << std::endl;
182 std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
183 << " environment variable to specify the location of the " << std::endl
184 << " image path where test images are located." << std::endl
185 << std::endl;
186 exit(EXIT_FAILURE);
187 }
188
189 //
190 // Here starts really the test
191 //
192
193 // Load grayscale Klimt
194 filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
195
196 vpImage<unsigned char> I_Klimt1, I_Klimt2;
197 vpImageIo::read(I_Klimt1, filename);
198 vpImageIo::read(I_Klimt2, filename);
199
200 std::cout << "\nI_Klimt1=" << I_Klimt1.getWidth() << "x" << I_Klimt1.getHeight() << std::endl;
201 std::cout << "I_Klimt2=" << I_Klimt2.getWidth() << "x" << I_Klimt2.getHeight() << std::endl;
202
203 std::cout << "\nThe two grayscale images are equal." << std::endl;
204 std::cout << "(I_Klimt1 == I_Klimt2)=" << (I_Klimt1 == I_Klimt2) << std::endl;
205 std::cout << "(I_Klimt1 != I_Klimt2)=" << (I_Klimt1 != I_Klimt2) << std::endl;
206
207 // The two images should be equal
208 if (!(I_Klimt1 == I_Klimt2) || (I_Klimt1 != I_Klimt2)) {
209 std::stringstream ss;
210 ss << "\nProblem when comparing two grayscale images!\n";
211 ss << "(I_Klimt1 == I_Klimt2)=" << (I_Klimt1 == I_Klimt2) << std::endl;
212 ss << "(I_Klimt1 != I_Klimt2)=" << (I_Klimt1 != I_Klimt2) << std::endl;
213
214 throw vpException(vpException::fatalError, ss.str());
215 }
216
217 // Modify I_Klimt1
218 if (I_Klimt1[I_Klimt1.getHeight() / 2][I_Klimt1.getWidth() / 2] < 255) {
219 I_Klimt1[I_Klimt1.getHeight() / 2][I_Klimt1.getWidth() / 2]++;
220 } else {
221 I_Klimt1[I_Klimt1.getHeight() / 2][I_Klimt1.getWidth() / 2]--;
222 }
223
224 std::cout << "\nThe two grayscale images are different." << std::endl;
225 std::cout << "(I_Klimt1 == I_Klimt2)=" << (I_Klimt1 == I_Klimt2) << std::endl;
226 std::cout << "(I_Klimt1 != I_Klimt2)=" << (I_Klimt1 != I_Klimt2) << std::endl;
227
228 // The two images should be different
229 if ((I_Klimt1 == I_Klimt2) || !(I_Klimt1 != I_Klimt2)) {
230 std::stringstream ss;
231 ss << "\nProblem when comparing two grayscale images!\n";
232 ss << "(I_Klimt1 == I_Klimt2)=" << (I_Klimt1 == I_Klimt2) << std::endl;
233 ss << "(I_Klimt1 != I_Klimt2)=" << (I_Klimt1 != I_Klimt2) << std::endl;
234
235 throw vpException(vpException::fatalError, ss.str());
236 }
237
238 // Load color Klimt
239 filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
240
241 vpImage<vpRGBa> I_color_Klimt1, I_color_Klimt2;
242 vpImageIo::read(I_color_Klimt1, filename);
243 I_color_Klimt2 = I_color_Klimt1;
244
245 std::cout << "\nI_color_Klimt1=" << I_color_Klimt1.getWidth() << "x" << I_color_Klimt1.getHeight() << std::endl;
246 std::cout << "I_color_Klimt2=" << I_color_Klimt2.getWidth() << "x" << I_color_Klimt2.getHeight() << std::endl;
247
248 std::cout << "\nThe two color images are equal." << std::endl;
249 std::cout << "(I_color_Klimt1 == I_color_Klimt2)=" << (I_color_Klimt1 == I_color_Klimt2) << std::endl;
250 std::cout << "(I_color_Klimt1 != I_color_Klimt2)=" << (I_color_Klimt1 != I_color_Klimt2) << std::endl;
251
252 // The two images should be equal
253 if (!(I_color_Klimt1 == I_color_Klimt2) || (I_color_Klimt1 != I_color_Klimt2)) {
254 std::stringstream ss;
255 ss << "\nProblem when comparing two color images!\n";
256 ss << "(I_color_Klimt1 == I_color_Klimt2)=" << (I_color_Klimt1 == I_color_Klimt2) << std::endl;
257 ss << "(I_color_Klimt1 != I_color_Klimt2)=" << (I_color_Klimt1 != I_color_Klimt2) << std::endl;
258
259 throw vpException(vpException::fatalError, ss.str());
260 }
261
262 // Modify I_color_Klimt2
263 if (I_color_Klimt2[I_color_Klimt2.getHeight() / 2][I_color_Klimt2.getWidth() / 2].R < 255) {
264 I_color_Klimt2[I_color_Klimt2.getHeight() / 2][I_color_Klimt2.getWidth() / 2].R++;
265 } else {
266 I_color_Klimt2[I_color_Klimt2.getHeight() / 2][I_color_Klimt2.getWidth() / 2].R--;
267 }
268
269 std::cout << "\nThe two color images are different." << std::endl;
270 std::cout << "(I_color_Klimt1 == I_color_Klimt2)=" << (I_color_Klimt1 == I_color_Klimt2) << std::endl;
271 std::cout << "(I_color_Klimt1 != I_color_Klimt2)=" << (I_color_Klimt1 != I_color_Klimt2) << std::endl;
272
273 // The two images should be different
274 if ((I_color_Klimt1 == I_color_Klimt2) || !(I_color_Klimt1 != I_color_Klimt2)) {
275 std::stringstream ss;
276 ss << "\nProblem when comparing two color images!\n";
277 ss << "(I_color_Klimt1 == I_color_Klimt2)=" << (I_color_Klimt1 == I_color_Klimt2) << std::endl;
278 ss << "(I_color_Klimt1 != I_color_Klimt2)=" << (I_color_Klimt1 != I_color_Klimt2) << std::endl;
279
280 throw vpException(vpException::fatalError, ss.str());
281 }
282
283 } catch (const vpException &e) {
284 std::cerr << "\nCatch an exception: " << e << std::endl;
285 return EXIT_FAILURE;
286 }
287
288 std::cout << "\nThe comparison of two images of the same type is OK!" << std::endl;
289 return EXIT_SUCCESS;
290}
error that can be emitted by ViSP classes.
Definition vpException.h:59
@ fatalError
Fatal error.
Definition vpException.h:84
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition of the vpImage class member functions.
Definition vpImage.h:135
unsigned int getWidth() const
Definition vpImage.h:242
unsigned int getHeight() const
Definition vpImage.h:184
static std::string getViSPImagesDataPath()
static std::string getUserName()
static std::string createFilePath(const std::string &parent, const std::string &child)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)