40 #include <visp3/core/vpDebug.h>
41 #include <visp3/core/vpImage.h>
42 #include <visp3/core/vpImageTools.h>
43 #include <visp3/core/vpIoTools.h>
44 #include <visp3/core/vpRGBa.h>
45 #include <visp3/core/vpTime.h>
46 #include <visp3/io/vpImageIo.h>
47 #include <visp3/io/vpParseArgv.h>
59 #define GETOPTARGS "cdi:o:t:s:h"
70 void usage(
const char *name,
const char *badparam,
const std::string &ipath,
const std::string &opath,
71 const std::string &user)
74 Read an image from the disk, undistort it \n\
75 and save the undistorted image on the disk.\n\
76 (grid36-01_undistorted.pgm).\n\
79 %s [-i <input image path>] [-o <output image path>] [-t <nThreads>] [-s <scale>]\n\
85 -i <input image path> %s\n\
86 Set image input path.\n\
87 From this path read \"calibration/grid36-01.pgm\"\n\
89 Setting the VISP_INPUT_IMAGE_PATH environment\n\
90 variable produces the same behaviour than using\n\
93 -o <output image path> %s\n\
94 Set image output path.\n\
95 From this directory, creates the \"%s\"\n\
96 subdirectory depending on the username, where \n\
97 grid36-01_undistorted.pgm output image is written.\n\
100 Set the number of threads to use for vpImageTools::undistort().\n\
103 Resize the image by the specified scale factor.\n\
106 Print the help.\n\n", ipath.c_str(), opath.c_str(), user.c_str());
109 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
124 bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &opath,
125 const std::string &user,
unsigned int &nThreads,
unsigned int &scale)
139 nThreads = atoi(optarg_);
142 scale = atoi(optarg_);
145 usage(argv[0], NULL, ipath, opath, user);
153 usage(argv[0], optarg_, ipath, opath, user);
158 if ((c == 1) || (c == -1)) {
160 usage(argv[0], NULL, ipath, opath, user);
161 std::cerr <<
"ERROR: " << std::endl;
162 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
169 int main(
int argc,
const char **argv)
172 std::string env_ipath;
173 std::string opt_ipath;
174 std::string opt_opath;
177 std::string filename;
178 std::string username;
179 unsigned int nThreads = 2;
180 unsigned int scale = 1;
187 if (!env_ipath.empty())
191 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
193 #elif defined(_WIN32)
194 opt_opath =
"C:\\temp";
201 if (getOptions(argc, argv, opt_ipath, opt_opath, username, nThreads, scale) ==
false) {
206 if (!opt_ipath.empty())
208 if (!opt_opath.empty())
220 usage(argv[0], NULL, ipath, opt_opath, username);
221 std::cerr << std::endl <<
"ERROR:" << std::endl;
222 std::cerr <<
" Cannot create " << opath << std::endl;
223 std::cerr <<
" Check your -o " << opt_opath <<
" option " << std::endl;
230 if (opt_ipath.empty()) {
231 if (ipath != env_ipath) {
232 std::cout << std::endl <<
"WARNING: " << std::endl;
233 std::cout <<
" Since -i <visp image path=" << ipath <<
"> "
234 <<
" is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
235 <<
" we skip the environment variable." << std::endl;
240 if (opt_ipath.empty() && env_ipath.empty()) {
241 usage(argv[0], NULL, ipath, opt_opath, username);
242 std::cerr << std::endl <<
"ERROR:" << std::endl;
243 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
244 <<
" environment variable to specify the location of the " << std::endl
245 <<
" image path where test images are located." << std::endl
264 std::cout <<
"Read image: " << filename << std::endl;
267 std::cout <<
"Scale the image by a factor of " << scale << std::endl;
272 std::cout <<
"Input image: " << I.
getWidth() <<
"x" << I.
getHeight() << std::endl;
275 std::cout <<
"Nb threads to use for vpImageTools::undistort(): " << nThreads << std::endl;
277 double t_undistort = 0.0, t_remap = 0.0;
279 std::cout <<
"\nUndistortion in process (color image)... " << std::endl;
286 for (
unsigned int i = 0; i < 10; i++)
291 t_undistort = endtime - begintime;
293 std::cout <<
"Time for 10 color image undistortion (ms): " << t_undistort << std::endl;
297 std::cout <<
"Undistortion in process with remap (color image)... " << std::endl;
305 for (
unsigned int i = 0; i < 10; i++) {
313 t_remap = endtime - begintime;
315 std::cout <<
"Time for 10 color image undistortion with remap (ms): " << t_remap << std::endl;
316 std::cout <<
"Speed-up: " << t_undistort / t_remap <<
"X" << std::endl;
320 std::cout <<
"\nUndistortion in process (gray image)... " << std::endl;
327 for (
unsigned int i = 0; i < 100; i++)
332 t_undistort = endtime - begintime;
334 std::cout <<
"Time for 100 gray image undistortion (ms): " << t_undistort << std::endl;
338 std::cout <<
"Undistortion in process with remap (gray image)... " << std::endl;
346 for (
unsigned int i = 0; i < 10; i++) {
354 t_remap = endtime - begintime;
356 std::cout <<
"Time for 100 gray image undistortion with remap (ms): " << t_remap << std::endl;
357 std::cout <<
"Speed-up: " << t_undistort / t_remap <<
"X" << std::endl;
362 std::cout <<
"\nWrite undistorted image: " << filename << std::endl;
366 std::cout <<
"Write undistorted image: " << filename << std::endl;
370 std::cout <<
"\nWrite undistorted image with remap: " << filename << std::endl;
374 std::cout <<
"Write undistorted image with remap: " << filename << std::endl;
380 double mean_diff = 0.0;
381 for (
unsigned int i = 0; i < U_diff_abs.
getHeight(); i++) {
382 for (
unsigned int j = 0; j < U_diff_abs.
getWidth(); j++) {
383 mean_diff += U_diff_abs[i][j].R;
384 mean_diff += U_diff_abs[i][j].G;
385 mean_diff += U_diff_abs[i][j].B;
386 mean_diff += U_diff_abs[i][j].A;
389 double remap_mean_error = mean_diff / (4*U_diff_abs.
getSize());
390 std::cout <<
"U_diff_abs mean value: " << remap_mean_error << std::endl;
391 const double remap_error_threshold = 0.5;
392 if (remap_mean_error > remap_error_threshold) {
393 std::cerr <<
"Issue with vpImageTools::remap() with vpRGBa image" << std::endl;
399 double remap_mean_error_gray = U_diff_gray_abs.
getSum() / U_diff_gray_abs.
getSize();
400 std::cout <<
"U_diff_gray_abs mean value: " << remap_mean_error_gray << std::endl;
401 if (remap_mean_error_gray > remap_error_threshold) {
402 std::cerr <<
"Issue with vpImageTools::remap() with unsigned char image" << std::endl;
411 std::cout <<
"\nWrite undistorted image: " << filename << std::endl;
416 std::cout <<
"Write undistorted image: " << filename << std::endl;
421 std::cout <<
"Catch an exception: " << e << std::endl;
Implementation of a generic 2D array used as base class for matrices and vectors.
Generic class defining intrinsic camera parameters.
void initPersProjWithDistortion(double px, double py, double u0, double v0, double kud, double kdu)
error that can be emited by ViSP classes.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
static void write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
unsigned int getWidth() const
unsigned int getSize() const
unsigned int getHeight() const
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
VISP_EXPORT double measureTimeMs()