Test flood fill algorithm.
Test flood fill algorithm.
#include <iomanip>
#include <visp3/core/vpImageTools.h>
#include <visp3/core/vpIoTools.h>
#include <visp3/imgproc/vpImgproc.h>
#include <visp3/io/vpImageIo.h>
#include <visp3/io/vpParseArgv.h>
#define GETOPTARGS "cdi:o:h"
void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user);
bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, std::string user);
void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
{
fprintf(stdout, "\n\
Test flood fill algorithm.\n\
\n\
SYNOPSIS\n\
%s [-i <input image path>] [-o <output image path>]\n\
[-h]\n \
",
name);
fprintf(stdout, "\n\
OPTIONS: Default\n\
-i <input image path> %s\n\
Set image input path.\n\
From this path read \"Klimt/Klimt.pgm\"\n\
image.\n\
Setting the VISP_INPUT_IMAGE_PATH environment\n\
variable produces the same behaviour than using\n\
this option.\n\
\n\
-o <output image path> %s\n\
Set image output path.\n\
From this directory, creates the \"%s\"\n\
subdirectory depending on the username, where \n\
output result images are written.\n\
\n\
-h\n\
Print the help.\n\n",
ipath.c_str(), opath.c_str(), user.c_str());
if (badparam)
fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
}
bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, std::string user)
{
const char *optarg_;
int c;
switch (c) {
case 'i':
ipath = optarg_;
break;
case 'o':
opath = optarg_;
break;
case 'h':
usage(argv[0], NULL, ipath, opath, user);
return false;
break;
case 'c':
case 'd':
break;
default:
usage(argv[0], optarg_, ipath, opath, user);
return false;
break;
}
}
if ((c == 1) || (c == -1)) {
usage(argv[0], NULL, ipath, opath, user);
std::cerr << "ERROR: " << std::endl;
std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
return false;
}
return true;
}
{
std::cout << "\n" << name << ":" << std::endl;
std::cout << " ";
for (
unsigned int j = 0; j < I.
getWidth(); j++) {
std::cout << std::setfill(' ') << std::setw(2) << j << " ";
}
std::cout << std::endl;
std::cout << std::setfill(' ') << std::setw(3) << "+";
for (
unsigned int j = 0; j < I.
getWidth(); j++) {
std::cout << std::setw(3) << "---";
}
std::cout << std::endl;
for (
unsigned int i = 0; i < I.
getHeight(); i++) {
std::cout << std::setfill(' ') << std::setw(2) << i << "|";
for (
unsigned int j = 0; j < I.
getWidth(); j++) {
std::cout << std::setfill(' ') << std::setw(2) << static_cast<unsigned int>(I[i][j]) << " ";
}
std::cout << std::endl;
}
}
int main(int argc, const char **argv)
{
#if defined(HAVE_OPENCV_IMGPROC)
try {
std::string env_ipath;
std::string opt_ipath;
std::string opt_opath;
std::string ipath;
std::string opath;
std::string filename;
std::string username;
if (!env_ipath.empty())
ipath = env_ipath;
#if defined(_WIN32)
opt_opath = "C:/temp";
#else
opt_opath = "/tmp";
#endif
if (getOptions(argc, argv, opt_ipath, opt_opath, username) == false) {
exit(EXIT_FAILURE);
}
if (!opt_ipath.empty())
ipath = opt_ipath;
if (!opt_opath.empty())
opath = opt_opath;
try {
} catch (...) {
usage(argv[0], NULL, ipath, opt_opath, username);
std::cerr << std::endl << "ERROR:" << std::endl;
std::cerr << " Cannot create " << opath << std::endl;
std::cerr << " Check your -o " << opt_opath << " option " << std::endl;
exit(EXIT_FAILURE);
}
}
if (!opt_ipath.empty() && !env_ipath.empty()) {
if (ipath != env_ipath) {
std::cout << std::endl << "WARNING: " << std::endl;
std::cout << " Since -i <visp image path=" << ipath << "> "
<< " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
<< " we skip the environment variable." << std::endl;
}
}
if (opt_ipath.empty() && env_ipath.empty()) {
usage(argv[0], NULL, ipath, opt_opath, username);
std::cerr << std::endl << "ERROR:" << std::endl;
std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
<< " environment variable to specify the location of the " << std::endl
<< " image path where test images are located." << std::endl
<< std::endl;
exit(EXIT_FAILURE);
}
unsigned char image_data[8 * 8] = {1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0,
1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1,
1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0};
printImage(I_test_flood_fill_4_connexity, "Test image data");
unsigned char image_data_check_4_connexity[8 * 8] = {
1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0};
unsigned char image_data_check_8_connexity[8 * 8] = {
1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0};
printImage(I_test_flood_fill_4_connexity, "I_test_flood_fill_4_connexity");
if (I_test_flood_fill_4_connexity != I_check_4_connexity) {
}
std::cout << "\n(I_test_flood_fill_4_connexity == I_check_4_connexity)? "
<< (I_test_flood_fill_4_connexity == I_check_4_connexity) << std::endl;
printImage(I_test_flood_fill_8_connexity, "I_test_flood_fill_8_connexity");
if (I_test_flood_fill_8_connexity != I_check_8_connexity) {
}
std::cout << "\n(I_test_flood_fill_8_connexity == I_check_8_connexity)? "
<< (I_test_flood_fill_8_connexity == I_check_8_connexity) << std::endl;
std::cout <<
"\nRead image: " << filename <<
" (" << I_klimt.
getWidth() <<
"x" << I_klimt.
getHeight() <<
")"
<< std::endl
<< std::endl;
(unsigned char)255);
int seed_x = 0;
int seed_y = 0;
std::cout << "Flood fill on Klimt image (4-connexity): " << t << " ms" << std::endl;
std::cout << "Flood fill on Klimt image (8-connexity): " << t << " ms" << std::endl;
cv::Mat matImg_klimt_4_connexity, matImg_klimt_8_connexity;
cv::floodFill(matImg_klimt_4_connexity, cv::Point(seed_x, seed_y), cv::Scalar(255), 0, cv::Scalar(), cv::Scalar(),
4);
std::cout << "OpenCV flood fill on Klimt image (4-connexity): " << t << " ms" << std::endl;
cv::floodFill(matImg_klimt_8_connexity, cv::Point(seed_x, seed_y), cv::Scalar(255), 0, cv::Scalar(), cv::Scalar(),
8);
std::cout << "OpenCV flood fill on Klimt image (8-connexity): " << t << " ms" << std::endl;
std::cout << "\n(I_klimt_flood_fill_4_connexity == "
"I_klimt_flood_fill_4_connexity_check)? "
<< (I_klimt_flood_fill_4_connexity == I_klimt_flood_fill_4_connexity_check) << std::endl;
std::cout << "(I_klimt_flood_fill_8_connexity == "
"I_klimt_flood_fill_8_connexity_check)? "
<< (I_klimt_flood_fill_8_connexity == I_klimt_flood_fill_8_connexity_check) << std::endl;
if (I_klimt_flood_fill_4_connexity != I_klimt_flood_fill_4_connexity_check) {
"I_klimt_flood_fill_4_connexity_check)");
}
if (I_klimt_flood_fill_8_connexity != I_klimt_flood_fill_8_connexity_check) {
"I_klimt_flood_fill_8_connexity_check)");
}
std::cout << "\nTest flood fill is ok!" << std::endl;
return EXIT_SUCCESS;
std::cerr <<
"Catch an exception: " << e.
what() << std::endl;
return EXIT_FAILURE;
}
#else
(void) argc;
(void) argv;
std::cout << "Install OpenCV imgproc module required by this test" << std::endl;
return EXIT_SUCCESS;
#endif
}
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)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition of the vpImage class member functions.
unsigned int getWidth() const
unsigned int getHeight() const
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
VISP_EXPORT void floodFill(vpImage< unsigned char > &I, const vpImagePoint &seedPoint, const unsigned char oldValue, const unsigned char newValue, const vpImageMorphology::vpConnexityType &connexity=vpImageMorphology::CONNEXITY_4)
VISP_EXPORT double measureTimeMs()