42#include <visp3/core/vpImageTools.h>
43#include <visp3/core/vpIoTools.h>
44#include <visp3/imgproc/vpImgproc.h>
45#include <visp3/io/vpImageIo.h>
46#include <visp3/io/vpParseArgv.h>
49#define GETOPTARGS "cdi:o:h"
51#ifdef ENABLE_VISP_NAMESPACE
55void usage(
const char *name,
const char *badparam,
const std::string &ipath,
const std::string &opath,
const std::string &user);
56bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &opath, std::string user);
67void usage(
const char *name,
const char *badparam,
const std::string &ipath,
const std::string &opath,
const std::string &user)
70Test contours extraction.\n\
73 %s [-i <input image path>] [-o <output image path>]\n\
80 -i <input image path> %s\n\
81 Set image input path.\n\
82 From this path read \"Klimt/Klimt.pgm\"\n\
84 Setting the VISP_INPUT_IMAGE_PATH environment\n\
85 variable produces the same behaviour than using\n\
88 -o <output image path> %s\n\
89 Set image output path.\n\
90 From this directory, creates the \"%s\"\n\
91 subdirectory depending on the username, where \n\
92 output result images are written.\n\
96 ipath.c_str(), opath.c_str(), user.c_str());
99 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
113bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &opath, std::string user)
127 usage(argv[0],
nullptr, ipath, opath, user);
135 usage(argv[0], optarg_, ipath, opath, user);
140 if ((c == 1) || (c == -1)) {
142 usage(argv[0],
nullptr, ipath, opath, user);
143 std::cerr <<
"ERROR: " << std::endl;
144 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
153 std::cout <<
"\n" << name <<
":" << std::endl;
156 for (
unsigned int j = 0;
j < I.getWidth();
j++) {
157 std::cout << std::setfill(
' ') << std::setw(2) <<
j <<
" ";
159 std::cout << std::endl;
161 for (
unsigned int i = 0;
i < I.getHeight();
i++) {
162 std::cout << std::setfill(
' ') << std::setw(2) <<
i <<
" ";
164 for (
unsigned int j = 0;
j < I.getWidth();
j++) {
165 std::cout << std::setfill(' ') << std::setw(2) << static_cast<unsigned int>(I[i][j]) <<
" ";
168 std::cout << std::endl;
174 std::cout <<
"\nContour:" << std::endl;
175 std::cout <<
"\tlevel: " <<
level << std::endl;
178 std::cout <<
"\tnb children: " << contour.
m_children.size() << std::endl;
180 for (std::vector<VISP_NAMESPACE_NAME::vpContour *>::const_iterator it = contour.
m_children.begin(); it != contour.
m_children.end();
182 displayContourInfo(**it, level + 1);
186int main(
int argc,
const char **argv)
189 std::string env_ipath;
190 std::string opt_ipath;
191 std::string opt_opath;
195 std::string username;
202 if (!env_ipath.empty())
207 opt_opath =
"C:/temp";
216 if (getOptions(argc, argv, opt_ipath, opt_opath, username) ==
false) {
221 if (!opt_ipath.empty())
223 if (!opt_opath.empty())
236 usage(argv[0],
nullptr, ipath, opt_opath, username);
237 std::cerr << std::endl <<
"ERROR:" << std::endl;
238 std::cerr <<
" Cannot create " << opath << std::endl;
239 std::cerr <<
" Check your -o " << opt_opath <<
" option " << std::endl;
246 if (!opt_ipath.empty() && !env_ipath.empty()) {
247 if (ipath != env_ipath) {
248 std::cout << std::endl <<
"WARNING: " << std::endl;
249 std::cout <<
" Since -i <visp image path=" << ipath <<
"> "
250 <<
" is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
251 <<
" we skip the environment variable." << std::endl;
256 if (opt_ipath.empty() && env_ipath.empty()) {
257 usage(argv[0],
nullptr, ipath, opt_opath, username);
258 std::cerr << std::endl <<
"ERROR:" << std::endl;
259 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
260 <<
" environment variable to specify the location of the " << std::endl
261 <<
" image path where test images are located." << std::endl
270 unsigned char image_data[14 * 10] = {
271 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,
272 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,
273 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,
274 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 };
277 std::cout <<
"Test with image data:" << std::endl;
278 printImage(I_test_data,
"I_test_data");
281 std::vector<std::vector<vpImagePoint> > contours;
286 displayContourInfo(vp_contours, 0);
287 std::cout <<
"ViSP: nb contours=" << contours.size() <<
" ; t=" <<
t <<
" ms" << std::endl;
292 std::cout <<
"Read image: " <<
filename << std::endl;
298 for (
unsigned int cpt = 0; cpt < I2.getSize(); cpt++) {
299 I2.bitmap[cpt] = 255 * I.bitmap[cpt];
308 displayContourInfo(vp_contours, 0);
309 std::cout <<
"\nTest with Klimt image:" << std::endl;
310 std::cout <<
"ViSP: nb contours=" << contours.size() <<
" ; t=" <<
t <<
" ms" << std::endl;
333 for (std::vector<VISP_NAMESPACE_NAME::vpContour *>::const_iterator it = vp_contours.
m_children.begin();
335 contours.push_back((*it)->m_points);
339 std::cout <<
"(I_tmp_list == I_draw_contours_list)? " << (I_tmp_list == I_draw_contours_list) << std::endl;
352 for (std::vector<VISP_NAMESPACE_NAME::vpContour *>::const_iterator it = vp_contours.
m_children.begin();
354 contours.push_back((*it)->m_points);
358 std::cout <<
"(I_tmp_external == I_draw_contours_external)? " << (I_tmp_external == I_draw_contours_external)
366 vpImageTools::binarise(I_holes, (
unsigned char)127, (
unsigned char)255, (
unsigned char)0, (
unsigned char)255,
372 std::cout <<
"\nFill Holes: " <<
t <<
" ms" << std::endl;
377#if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGPROC)
381 std::vector<std::vector<cv::Point> > contours_opencv;
383 cv::findContours(matImg, contours_opencv, cv::RETR_TREE, cv::CHAIN_APPROX_NONE);
385 std::cout <<
"\nOpenCV: nb contours=" << contours_opencv.size() <<
" ; t_opencv=" << t_opencv <<
" ms" << std::endl;
388 for (std::vector<std::vector<cv::Point> >::const_iterator it1 = contours_opencv.begin();
389 it1 != contours_opencv.end(); ++it1) {
390 for (std::vector<cv::Point>::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2) {
391 I_draw_contours_opencv[it2->y][it2->x] = 255;
395 std::cout <<
"(I_draw_contours_opencv == I_drawContours)? " << (I_draw_contours_opencv == I_draw_contours)
403 contours_opencv.clear();
404 cv::findContours(matImg, contours_opencv, cv::RETR_LIST, cv::CHAIN_APPROX_NONE);
406 I_draw_contours_opencv = 0;
407 for (std::vector<std::vector<cv::Point> >::const_iterator it1 = contours_opencv.begin();
408 it1 != contours_opencv.end(); ++it1) {
409 for (std::vector<cv::Point>::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2) {
410 I_draw_contours_opencv[it2->y][it2->x] = 255;
414 std::cout <<
"(I_draw_contours_opencv == I_draw_contours_list)? "
415 << (I_draw_contours_opencv == I_draw_contours_list) << std::endl;
419 contours_opencv.clear();
420 cv::findContours(matImg, contours_opencv, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
422 I_draw_contours_opencv = 0;
423 for (std::vector<std::vector<cv::Point> >::const_iterator it1 = contours_opencv.begin();
424 it1 != contours_opencv.end(); ++it1) {
425 for (std::vector<cv::Point>::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2) {
426 I_draw_contours_opencv[it2->y][it2->x] = 255;
430 std::cout <<
"(I_draw_contours_opencv == I_draw_contours_external)? "
431 << (I_draw_contours_opencv == I_draw_contours_external) << std::endl;
437 std::cerr <<
"Catch an exception: " <<
e.what() << std::endl;
error that can be emitted 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)
Definition of the vpImage class member functions.
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
VISP_EXPORT void findContours(const VISP_NAMESPACE_ADDRESSING vpImage< unsigned char > &I_original, vpContour &contours, std::vector< std::vector< VISP_NAMESPACE_ADDRESSING vpImagePoint > > &contourPts, const vpContourRetrievalType &retrievalMode=CONTOUR_RETR_TREE)
VISP_EXPORT void drawContours(VISP_NAMESPACE_ADDRESSING vpImage< unsigned char > &I, const std::vector< std::vector< VISP_NAMESPACE_ADDRESSING vpImagePoint > > &contours, unsigned char grayValue=255)
VISP_EXPORT void fillHoles(VISP_NAMESPACE_ADDRESSING vpImage< unsigned char > &I)
VISP_EXPORT double measureTimeMs()
std::vector< vpContour * > m_children
Children contour.
vpContourType m_contourType
Contour type.