36#include <visp3/core/vpImageTools.h>
37#include <visp3/core/vpIoTools.h>
38#include <visp3/imgproc/vpImgproc.h>
39#include <visp3/io/vpImageIo.h>
40#include <visp3/io/vpParseArgv.h>
49#define GETOPTARGS "cdi:o:h"
51void usage(
const char *name,
const char *badparam, std::string ipath, std::string opath, std::string user);
52bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &opath, std::string user);
63void usage(
const char *name,
const char *badparam, std::string ipath, std::string opath, std::string user)
66Test contours extraction.\n\
69 %s [-i <input image path>] [-o <output image path>]\n\
76 -i <input image path> %s\n\
77 Set image input path.\n\
78 From this path read \"Klimt/Klimt.pgm\"\n\
80 Setting the VISP_INPUT_IMAGE_PATH environment\n\
81 variable produces the same behaviour than using\n\
84 -o <output image path> %s\n\
85 Set image output path.\n\
86 From this directory, creates the \"%s\"\n\
87 subdirectory depending on the username, where \n\
88 output result images are written.\n\
92 ipath.c_str(), opath.c_str(), user.c_str());
95 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
109bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &opath, std::string user)
123 usage(argv[0], NULL, ipath, opath, user);
132 usage(argv[0], optarg_, ipath, opath, user);
138 if ((c == 1) || (c == -1)) {
140 usage(argv[0], NULL, ipath, opath, user);
141 std::cerr <<
"ERROR: " << std::endl;
142 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
151 std::cout <<
"\n" << name <<
":" << std::endl;
154 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
155 std::cout << std::setfill(
' ') << std::setw(2) << j <<
" ";
157 std::cout << std::endl;
159 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
160 std::cout << std::setfill(
' ') << std::setw(2) << i <<
" ";
162 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
163 std::cout << std::setfill(' ') << std::setw(2) << static_cast<unsigned int>(I[i][j]) <<
" ";
166 std::cout << std::endl;
170void displayContourInfo(
const vp::vpContour &contour,
int level)
172 std::cout <<
"\nContour:" << std::endl;
173 std::cout <<
"\tlevel: " << level << std::endl;
176 std::cout <<
"\tnb children: " << contour.
m_children.size() << std::endl;
178 for (std::vector<vp::vpContour *>::const_iterator it = contour.
m_children.begin(); it != contour.
m_children.end();
180 displayContourInfo(**it, level + 1);
184int main(
int argc,
const char **argv)
187 std::string env_ipath;
188 std::string opt_ipath;
189 std::string opt_opath;
192 std::string filename;
193 std::string username;
200 if (!env_ipath.empty())
205 opt_opath =
"C:/temp";
214 if (getOptions(argc, argv, opt_ipath, opt_opath, username) ==
false) {
219 if (!opt_ipath.empty())
221 if (!opt_opath.empty())
233 usage(argv[0], NULL, ipath, opt_opath, username);
234 std::cerr << std::endl <<
"ERROR:" << std::endl;
235 std::cerr <<
" Cannot create " << opath << std::endl;
236 std::cerr <<
" Check your -o " << opt_opath <<
" option " << std::endl;
243 if (!opt_ipath.empty() && !env_ipath.empty()) {
244 if (ipath != env_ipath) {
245 std::cout << std::endl <<
"WARNING: " << std::endl;
246 std::cout <<
" Since -i <visp image path=" << ipath <<
"> "
247 <<
" is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
248 <<
" we skip the environment variable." << std::endl;
253 if (opt_ipath.empty() && env_ipath.empty()) {
254 usage(argv[0], NULL, ipath, opt_opath, username);
255 std::cerr << std::endl <<
"ERROR:" << std::endl;
256 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
257 <<
" environment variable to specify the location of the " << std::endl
258 <<
" image path where test images are located." << std::endl
267 unsigned char image_data[14 * 10] = {
268 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
269 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
270 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
271 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
274 std::cout <<
"Test with image data:" << std::endl;
275 printImage(I_test_data,
"I_test_data");
278 std::vector<std::vector<vpImagePoint> > contours;
283 displayContourInfo(vp_contours, 0);
284 std::cout <<
"ViSP: nb contours=" << contours.size() <<
" ; t=" << t <<
" ms" << std::endl;
289 std::cout <<
"Read image: " << filename << std::endl;
295 for (
unsigned int cpt = 0; cpt < I2.getSize(); cpt++) {
296 I2.bitmap[cpt] = 255 * I.
bitmap[cpt];
305 displayContourInfo(vp_contours, 0);
306 std::cout <<
"\nTest with Klimt image:" << std::endl;
307 std::cout <<
"ViSP: nb contours=" << contours.size() <<
" ; t=" << t <<
" ms" << std::endl;
330 for (std::vector<vp::vpContour *>::const_iterator it = vp_contours.
m_children.begin();
332 contours.push_back((*it)->m_points);
336 std::cout <<
"(I_tmp_list == I_draw_contours_list)? " << (I_tmp_list == I_draw_contours_list) << std::endl;
349 for (std::vector<vp::vpContour *>::const_iterator it = vp_contours.
m_children.begin();
351 contours.push_back((*it)->m_points);
355 std::cout <<
"(I_tmp_external == I_draw_contours_external)? " << (I_tmp_external == I_draw_contours_external)
363 vpImageTools::binarise(I_holes, (
unsigned char)127, (
unsigned char)255, (
unsigned char)0, (
unsigned char)255,
369 std::cout <<
"\nFill Holes: " << t <<
" ms" << std::endl;
374#if (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGPROC)
378 std::vector<std::vector<cv::Point> > contours_opencv;
380 cv::findContours(matImg, contours_opencv, cv::RETR_TREE, cv::CHAIN_APPROX_NONE);
382 std::cout <<
"\nOpenCV: nb contours=" << contours_opencv.size() <<
" ; t_opencv=" << t_opencv <<
" ms" << std::endl;
385 for (std::vector<std::vector<cv::Point> >::const_iterator it1 = contours_opencv.begin();
386 it1 != contours_opencv.end(); ++it1) {
387 for (std::vector<cv::Point>::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2) {
388 I_draw_contours_opencv[it2->y][it2->x] = 255;
392 std::cout <<
"(I_draw_contours_opencv == I_drawContours)? " << (I_draw_contours_opencv == I_draw_contours)
400 contours_opencv.clear();
401 cv::findContours(matImg, contours_opencv, cv::RETR_LIST, cv::CHAIN_APPROX_NONE);
403 I_draw_contours_opencv = 0;
404 for (std::vector<std::vector<cv::Point> >::const_iterator it1 = contours_opencv.begin();
405 it1 != contours_opencv.end(); ++it1) {
406 for (std::vector<cv::Point>::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2) {
407 I_draw_contours_opencv[it2->y][it2->x] = 255;
411 std::cout <<
"(I_draw_contours_opencv == I_draw_contours_list)? "
412 << (I_draw_contours_opencv == I_draw_contours_list) << std::endl;
416 contours_opencv.clear();
417 cv::findContours(matImg, contours_opencv, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
419 I_draw_contours_opencv = 0;
420 for (std::vector<std::vector<cv::Point> >::const_iterator it1 = contours_opencv.begin();
421 it1 != contours_opencv.end(); ++it1) {
422 for (std::vector<cv::Point>::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2) {
423 I_draw_contours_opencv[it2->y][it2->x] = 255;
427 std::cout <<
"(I_draw_contours_opencv == I_draw_contours_external)? "
428 << (I_draw_contours_opencv == I_draw_contours_external) << std::endl;
433 std::cerr <<
"Catch an exception: " << e.
what() << std::endl;
error that can be emitted by ViSP classes.
const char * what() const
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)
Definition of the vpImage class member functions.
unsigned int getWidth() const
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
VISP_EXPORT void findContours(const vpImage< unsigned char > &I_original, vpContour &contours, std::vector< std::vector< vpImagePoint > > &contourPts, const vpContourRetrievalType &retrievalMode=vp::CONTOUR_RETR_TREE)
VISP_EXPORT void drawContours(vpImage< unsigned char > &I, const std::vector< std::vector< vpImagePoint > > &contours, unsigned char grayValue=255)
VISP_EXPORT void fillHoles(vpImage< unsigned char > &I)
VISP_EXPORT double measureTimeMs()
vpContourType m_contourType
Contour type.
std::vector< vpContour * > m_children
Children contour.