43 #include <visp3/core/vpConfig.h>
44 #include <visp3/core/vpDebug.h>
45 #include <visp3/core/vpHistogram.h>
46 #include <visp3/core/vpImage.h>
47 #include <visp3/core/vpIoTools.h>
48 #include <visp3/io/vpImageIo.h>
49 #include <visp3/io/vpParseArgv.h>
57 #define GETOPTARGS "i:o:h"
59 #ifdef ENABLE_VISP_NAMESPACE
81 void usage(
const char *name,
const char *badparam, std::string ipath, std::string opath, std::string user)
84 Read an image on the disk, display it using X11, display some\n\
85 features (line, circle, characters) in overlay and finally write \n\
86 the image and the overlayed features in an image on the disk.\n\
89 %s [-i <input image path>] [-o <output histogram path>]\n\
96 -i <input image path> %s\n\
97 Set image input path.\n\
98 From this path read \"Klimt/Klimt.pgm\"\n\
100 Setting the VISP_INPUT_IMAGE_PATH environment\n\
101 variable produces the same behaviour than using\n\
104 -o <output histogram path> %s\n\
105 From this directory, creates the \"%s\"\n\
106 subdirectory depending on the username, where \n\
107 \"histogram.txt\" is saved.\n\
110 Print the help.\n\n",
111 ipath.c_str(), opath.c_str(), user.c_str());
114 fprintf(stderr,
"ERROR: \n");
115 fprintf(stderr,
"\nBad parameter [%s]\n", badparam);
131 bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &opath,
const std::string &user)
145 usage(argv[0],
nullptr, ipath, opath, user);
150 usage(argv[0], optarg_, ipath, opath, user);
156 if ((c == 1) || (c == -1)) {
158 usage(argv[0],
nullptr, ipath, opath, user);
159 std::cerr <<
"ERROR: " << std::endl;
160 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
167 int main(
int argc,
const char **argv)
170 std::string env_ipath;
171 std::string opt_ipath;
172 std::string opt_opath;
175 std::string filename;
176 std::string username;
183 if (!env_ipath.empty())
188 opt_opath =
"C:/temp";
197 if (getOptions(argc, argv, opt_ipath, opt_opath, username) ==
false) {
202 if (!opt_ipath.empty())
204 if (!opt_opath.empty())
217 usage(argv[0],
nullptr, ipath, opath, username);
218 std::cerr << std::endl <<
"ERROR:" << std::endl;
219 std::cerr <<
" Cannot create " << dirname << std::endl;
220 std::cerr <<
" Check your -o " << opath <<
" option " << std::endl;
227 if (opt_ipath.empty()) {
228 if (ipath != env_ipath) {
229 std::cout << std::endl <<
"WARNING: " << std::endl;
230 std::cout <<
" Since -i <visp image path=" << ipath <<
"> "
231 <<
" is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
232 <<
" we skip the environment variable." << std::endl;
237 if (opt_ipath.empty() && env_ipath.empty()) {
238 usage(argv[0],
nullptr, ipath, opath, username);
239 std::cerr << std::endl <<
"ERROR:" << std::endl;
240 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
241 <<
" environment variable to specify the location of the " << std::endl
242 <<
" image path where test images are located." << std::endl
252 if (opt_ipath.empty())
255 std::cout <<
"Read: " << filename << std::endl;
258 unsigned char distance = 60;
266 std::cout <<
"Save the histogram in: " << filename << std::endl;
273 std::cout <<
"Save the smoothed histogram in: " << filename << std::endl;
276 std::list<vpHistogramPeak> peaks;
277 unsigned int nbpeaks = 0;
282 vpTRACE(
"List of peaks");
283 vpTRACE(
"Nb peaks: %d", nbpeaks);
285 for (std::list<vpHistogramPeak>::const_iterator it = peaks.begin(); it != peaks.end(); ++it) {
293 nbpeaks = h.
sort(peaks);
295 vpTRACE(
"Sorted list of peaks");
296 vpTRACE(
"Nb peaks: %d", nbpeaks);
298 for (std::list<vpHistogramPeak>::const_iterator it = peaks.begin(); it != peaks.end(); ++it) {
306 nbpeaks = h.
getPeaks(distance, peak1, peak2);
308 std::cout <<
"Not a bimodal histogram..." << std::endl;
311 vpTRACE(
"Bimodal histogram: main peak1: %d-%d second peak2: %d-%d", peak1.
getLevel(), peak1.
getValue(),
317 if (h.
getValey(peak1, peak2, valey) ==
false) {
318 vpTRACE(
"No valey found...");
328 unsigned ret = h.
getValey(distance, peak1, valeyl, valeyr);
330 vpTRACE(
"No left and right valey for peak %d-%d...", peak1.
getLevel(), peak1.
getValue());
332 else if (ret == 0x10) {
333 vpTRACE(
"No right valey for peak %d-%d...", peak1.
getLevel(), peak1.
getValue());
336 else if (ret == 0x01) {
337 vpTRACE(
"No left valey for peak %d-%d...", peak1.
getLevel(), peak1.
getValue());
340 else if (ret == 0x11) {
347 unsigned ret = h.
getValey(distance, peak2, valeyl, valeyr);
349 vpTRACE(
"No left and right valey for peak %d-%d...", peak2.
getLevel(), peak2.
getValue());
351 else if (ret == 0x10) {
352 vpTRACE(
"No right valey for peak %d-%d...", peak2.
getLevel(), peak2.
getValue());
355 else if (ret == 0x01) {
356 vpTRACE(
"No left valey for peak %d-%d...", peak2.
getLevel(), peak2.
getValue());
359 else if (ret == 0x11) {
369 if (h.
getPeaks(distance, peakl, peakr, valey) ==
false) {
370 std::cout <<
"Not a bimodal histogram..." << std::endl;
373 vpTRACE(
"Bimodal histogram: valey %d-%d for peakl: %d-%d peakr: %d-%d", valey.
getLevel(), valey.
getValue(),
379 std::cout <<
"Catch an exception: " << e << std::endl;
error that can be emitted by ViSP classes.
Declaration of the peak (maximum value) in a gray level image histogram.
unsigned getValue() const
unsigned char getLevel() const
Declaration of the valey (minimum value) in a gray level image histogram.
unsigned char getLevel() const
unsigned getValue() const
Class to compute a gray level image histogram.
unsigned getPeaks(std::list< vpHistogramPeak > &peaks)
void smooth(unsigned int fsize=3)
void calculate(const vpImage< unsigned char > &I, unsigned int nbins=256, unsigned int nbThreads=1)
unsigned sort(std::list< vpHistogramPeak > &peaks)
unsigned getValey(std::list< vpHistogramValey > &valey)
bool write(const std::string &filename)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)