Visual Servoing Platform  version 3.4.0
testAutoThreshold.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  * Test automatic thresholding.
33  *
34  * Authors:
35  * Souriya Trinh
36  *
37  *****************************************************************************/
38 
39 #include <visp3/core/vpImageTools.h>
40 #include <visp3/core/vpIoTools.h>
41 #include <visp3/imgproc/vpImgproc.h>
42 #include <visp3/io/vpImageIo.h>
43 #include <visp3/io/vpParseArgv.h>
44 
51 // List of allowed command line options
52 #define GETOPTARGS "cdi:o:h"
53 
54 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user);
55 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, std::string user);
56 
57 /*
58  Print the program options.
59 
60  \param name : Program name.
61  \param badparam : Bad parameter name.
62  \param ipath: Input image path.
63  \param opath : Output image path.
64  \param user : Username.
65  */
66 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
67 {
68  fprintf(stdout, "\n\
69 Test automatic thresholding.\n\
70 \n\
71 SYNOPSIS\n\
72  %s [-i <input image path>] [-o <output image path>]\n\
73  [-h]\n \
74 ", name);
75 
76  fprintf(stdout, "\n\
77 OPTIONS: Default\n\
78  -i <input image path> %s\n\
79  Set image input path.\n\
80  From this path read \"Klimt/Klimt.pgm\"\n\
81  image.\n\
82  Setting the VISP_INPUT_IMAGE_PATH environment\n\
83  variable produces the same behaviour than using\n\
84  this option.\n\
85 \n\
86  -o <output image path> %s\n\
87  Set image output path.\n\
88  From this directory, creates the \"%s\"\n\
89  subdirectory depending on the username, where \n\
90  output result images are written.\n\
91 \n\
92  -h\n\
93  Print the help.\n\n", ipath.c_str(), opath.c_str(), user.c_str());
94 
95  if (badparam)
96  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
97 }
98 
110 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, std::string user)
111 {
112  const char *optarg_;
113  int c;
114  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
115 
116  switch (c) {
117  case 'i':
118  ipath = optarg_;
119  break;
120  case 'o':
121  opath = optarg_;
122  break;
123  case 'h':
124  usage(argv[0], NULL, ipath, opath, user);
125  return false;
126  break;
127 
128  case 'c':
129  case 'd':
130  break;
131 
132  default:
133  usage(argv[0], optarg_, ipath, opath, user);
134  return false;
135  break;
136  }
137  }
138 
139  if ((c == 1) || (c == -1)) {
140  // standalone param or error
141  usage(argv[0], NULL, ipath, opath, user);
142  std::cerr << "ERROR: " << std::endl;
143  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
144  return false;
145  }
146 
147  return true;
148 }
149 
150 int main(int argc, const char **argv)
151 {
152  try {
153  std::string env_ipath;
154  std::string opt_ipath;
155  std::string opt_opath;
156  std::string ipath;
157  std::string opath;
158  std::string filename;
159  std::string username;
160 
161  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
162  // environment variable value
163  env_ipath = vpIoTools::getViSPImagesDataPath();
164 
165  // Set the default input path
166  if (!env_ipath.empty())
167  ipath = env_ipath;
168 
169 // Set the default output path
170 #if defined(_WIN32)
171  opt_opath = "C:/temp";
172 #else
173  opt_opath = "/tmp";
174 #endif
175 
176  // Get the user login name
177  vpIoTools::getUserName(username);
178 
179  // Read the command line options
180  if (getOptions(argc, argv, opt_ipath, opt_opath, username) == false) {
181  exit(EXIT_FAILURE);
182  }
183 
184  // Get the option values
185  if (!opt_ipath.empty())
186  ipath = opt_ipath;
187  if (!opt_opath.empty())
188  opath = opt_opath;
189 
190  // Append to the output path string, the login name of the user
191  opath = vpIoTools::createFilePath(opath, username);
192 
193  // Test if the output path exist. If no try to create it
194  if (vpIoTools::checkDirectory(opath) == false) {
195  try {
196  // Create the dirname
198  } catch (...) {
199  usage(argv[0], NULL, ipath, opt_opath, username);
200  std::cerr << std::endl << "ERROR:" << std::endl;
201  std::cerr << " Cannot create " << opath << std::endl;
202  std::cerr << " Check your -o " << opt_opath << " option " << std::endl;
203  exit(EXIT_FAILURE);
204  }
205  }
206 
207  // Compare ipath and env_ipath. If they differ, we take into account
208  // the input path comming from the command line option
209  if (!opt_ipath.empty() && !env_ipath.empty()) {
210  if (ipath != env_ipath) {
211  std::cout << std::endl << "WARNING: " << std::endl;
212  std::cout << " Since -i <visp image path=" << ipath << "> "
213  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
214  << " we skip the environment variable." << std::endl;
215  }
216  }
217 
218  // Test if an input path is set
219  if (opt_ipath.empty() && env_ipath.empty()) {
220  usage(argv[0], NULL, ipath, opt_opath, username);
221  std::cerr << std::endl << "ERROR:" << std::endl;
222  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
223  << " environment variable to specify the location of the " << std::endl
224  << " image path where test images are located." << std::endl
225  << std::endl;
226  exit(EXIT_FAILURE);
227  }
228 
229  //
230  // Here starts really the test
231  //
232 
233  filename = vpIoTools::createFilePath(ipath, "calibration/grid36-03.pgm");
235  vpImageIo::read(I, filename);
236  std::cout << "Read: " << filename << " (" << I.getWidth() << "x" << I.getHeight() << ")" << std::endl;
237 
238  vpImage<unsigned char> I_thresh = I;
239 
240  // Huang
241  double t = vpTime::measureTimeMs();
242  double threshold = vp::autoThreshold(I_thresh, vp::AUTO_THRESHOLD_HUANG);
243  t = vpTime::measureTimeMs() - t;
244  std::cout << "\nAutomatic thresholding (Huang): " << threshold << " ; t=" << t << " ms" << std::endl;
245 
246  filename = vpIoTools::createFilePath(opath, "grid36-03_auto_thresh_huang.pgm");
247  vpImageIo::write(I_thresh, filename);
248  std::cout << "Write: " << filename << std::endl;
249 
250  // Intermodes
251  I_thresh = I;
252  t = vpTime::measureTimeMs();
253  threshold = vp::autoThreshold(I_thresh, vp::AUTO_THRESHOLD_INTERMODES);
254  t = vpTime::measureTimeMs() - t;
255  std::cout << "\nAutomatic thresholding (Intermodes): " << threshold << " ; t=" << t << " ms" << std::endl;
256 
257  filename = vpIoTools::createFilePath(opath, "grid36-03_auto_thresh_intermodes.pgm");
258  vpImageIo::write(I_thresh, filename);
259  std::cout << "Write: " << filename << std::endl;
260 
261  // IsoData
262  I_thresh = I;
263  t = vpTime::measureTimeMs();
264  threshold = vp::autoThreshold(I_thresh, vp::AUTO_THRESHOLD_ISODATA);
265  t = vpTime::measureTimeMs() - t;
266  std::cout << "\nAutomatic thresholding (IsoData): " << threshold << " ; t=" << t << " ms" << std::endl;
267 
268  filename = vpIoTools::createFilePath(opath, "grid36-03_auto_thresh_isodata.pgm");
269  vpImageIo::write(I_thresh, filename);
270  std::cout << "Write: " << filename << std::endl;
271 
272  // Mean
273  I_thresh = I;
274  t = vpTime::measureTimeMs();
275  threshold = vp::autoThreshold(I_thresh, vp::AUTO_THRESHOLD_MEAN);
276  t = vpTime::measureTimeMs() - t;
277  std::cout << "\nAutomatic thresholding (Mean): " << threshold << " ; t=" << t << " ms" << std::endl;
278 
279  filename = vpIoTools::createFilePath(opath, "grid36-03_auto_thresh_mean.pgm");
280  vpImageIo::write(I_thresh, filename);
281  std::cout << "Write: " << filename << std::endl;
282 
283  // Otsu
284  I_thresh = I;
285  t = vpTime::measureTimeMs();
286  threshold = vp::autoThreshold(I_thresh, vp::AUTO_THRESHOLD_OTSU);
287  t = vpTime::measureTimeMs() - t;
288  std::cout << "\nAutomatic thresholding (Otsu): " << threshold << " ; t=" << t << " ms" << std::endl;
289 
290  filename = vpIoTools::createFilePath(opath, "grid36-03_auto_thresh_otsu.pgm");
291  vpImageIo::write(I_thresh, filename);
292  std::cout << "Write: " << filename << std::endl;
293 
294  // Triangle
295  I_thresh = I;
296  t = vpTime::measureTimeMs();
297  threshold = vp::autoThreshold(I_thresh, vp::AUTO_THRESHOLD_TRIANGLE);
298  t = vpTime::measureTimeMs() - t;
299  std::cout << "\nAutomatic thresholding (Triangle): " << threshold << " ; t=" << t << " ms" << std::endl;
300 
301  filename = vpIoTools::createFilePath(opath, "grid36-03_auto_thresh_Triangle.pgm");
302  vpImageIo::write(I_thresh, filename);
303  std::cout << "Write: " << filename << std::endl;
304 
305  return EXIT_SUCCESS;
306  } catch (const vpException &e) {
307  std::cerr << "Catch an exception: " << e.what() << std::endl;
308  return EXIT_FAILURE;
309  }
310 }
static void makeDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:482
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1202
unsigned int getWidth() const
Definition: vpImage.h:246
error that can be emited by ViSP classes.
Definition: vpException.h:71
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:126
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69
static bool checkDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:332
static void write(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:445
const char * what() const
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1446
static std::string getUserName()
Definition: vpIoTools.cpp:228
VISP_EXPORT unsigned char autoThreshold(vpImage< unsigned char > &I, const vp::vpAutoThresholdMethod &method, const unsigned char backgroundValue=0, const unsigned char foregroundValue=255)
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:244
unsigned int getHeight() const
Definition: vpImage.h:188