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 flood fill algorithm.\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);
112bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &opath, std::string user)
126 usage(argv[0],
nullptr, ipath, opath, user);
134 usage(argv[0], optarg_, ipath, opath, user);
139 if ((c == 1) || (c == -1)) {
141 usage(argv[0],
nullptr, ipath, opath, user);
142 std::cerr <<
"ERROR: " << std::endl;
143 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
152 std::cout <<
"\n" << name <<
":" << std::endl;
155 for (
unsigned int j = 0;
j < I.getWidth();
j++) {
156 std::cout << std::setfill(
' ') << std::setw(2) <<
j <<
" ";
158 std::cout << std::endl;
160 std::cout << std::setfill(
' ') << std::setw(3) <<
"+";
161 for (
unsigned int j = 0;
j < I.getWidth();
j++) {
162 std::cout << std::setw(3) <<
"---";
164 std::cout << std::endl;
166 for (
unsigned int i = 0;
i < I.getHeight();
i++) {
167 std::cout << std::setfill(
' ') << std::setw(2) <<
i <<
"|";
169 for (
unsigned int j = 0;
j < I.getWidth();
j++) {
170 std::cout << std::setfill(' ') << std::setw(2) << static_cast<unsigned int>(I[i][j]) <<
" ";
173 std::cout << std::endl;
177int main(
int argc,
const char **argv)
179#if defined(HAVE_OPENCV_IMGPROC)
181 std::string env_ipath;
182 std::string opt_ipath;
183 std::string opt_opath;
187 std::string username;
194 if (!env_ipath.empty())
199 opt_opath =
"C:/temp";
208 if (getOptions(argc, argv, opt_ipath, opt_opath, username) ==
false) {
213 if (!opt_ipath.empty())
215 if (!opt_opath.empty())
228 usage(argv[0],
nullptr, ipath, opt_opath, username);
229 std::cerr << std::endl <<
"ERROR:" << std::endl;
230 std::cerr <<
" Cannot create " << opath << std::endl;
231 std::cerr <<
" Check your -o " << opt_opath <<
" option " << std::endl;
238 if (!opt_ipath.empty() && !env_ipath.empty()) {
239 if (ipath != env_ipath) {
240 std::cout << std::endl <<
"WARNING: " << std::endl;
241 std::cout <<
" Since -i <visp image path=" << ipath <<
"> "
242 <<
" is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
243 <<
" we skip the environment variable." << std::endl;
248 if (opt_ipath.empty() && env_ipath.empty()) {
249 usage(argv[0],
nullptr, ipath, opt_opath, username);
250 std::cerr << std::endl <<
"ERROR:" << std::endl;
251 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
252 <<
" environment variable to specify the location of the " << std::endl
253 <<
" image path where test images are located." << std::endl
262 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,
263 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1,
264 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0 };
267 printImage(I_test_flood_fill_4_connexity,
"Test image data");
269 unsigned char image_data_check_4_connexity[8 * 8] = {
270 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,
271 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 };
274 unsigned char image_data_check_8_connexity[8 * 8] = {
275 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,
276 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 };
281 printImage(I_test_flood_fill_4_connexity,
"I_test_flood_fill_4_connexity");
283 if (I_test_flood_fill_4_connexity != I_check_4_connexity) {
286 std::cout <<
"\n(I_test_flood_fill_4_connexity == I_check_4_connexity)? "
287 << (I_test_flood_fill_4_connexity == I_check_4_connexity) << std::endl;
291 printImage(I_test_flood_fill_8_connexity,
"I_test_flood_fill_8_connexity");
293 if (I_test_flood_fill_8_connexity != I_check_8_connexity) {
296 std::cout <<
"\n(I_test_flood_fill_8_connexity == I_check_8_connexity)? "
297 << (I_test_flood_fill_8_connexity == I_check_8_connexity) << std::endl;
306 vpImageTools::binarise(I_klimt, (
unsigned char)127, (
unsigned char)255, (
unsigned char)0, (
unsigned char)255,
316 std::cout <<
"Flood fill on Klimt image (4-connexity): " <<
t <<
" ms" << std::endl;
325 std::cout <<
"Flood fill on Klimt image (8-connexity): " <<
t <<
" ms" << std::endl;
329 cv::Mat matImg_klimt_4_connexity, matImg_klimt_8_connexity;
335 cv::floodFill(matImg_klimt_4_connexity, cv::Point(seed_x, seed_y), cv::Scalar(255), 0, cv::Scalar(), cv::Scalar(),
338 std::cout <<
"OpenCV flood fill on Klimt image (4-connexity): " <<
t <<
" ms" << std::endl;
348 cv::floodFill(matImg_klimt_8_connexity, cv::Point(seed_x, seed_y), cv::Scalar(255), 0, cv::Scalar(), cv::Scalar(),
351 std::cout <<
"OpenCV flood fill on Klimt image (8-connexity): " <<
t <<
" ms" << std::endl;
360 std::cout <<
"\n(I_klimt_flood_fill_4_connexity == "
361 "I_klimt_flood_fill_4_connexity_check)? "
362 << (I_klimt_flood_fill_4_connexity == I_klimt_flood_fill_4_connexity_check) << std::endl;
363 std::cout <<
"(I_klimt_flood_fill_8_connexity == "
364 "I_klimt_flood_fill_8_connexity_check)? "
365 << (I_klimt_flood_fill_8_connexity == I_klimt_flood_fill_8_connexity_check) << std::endl;
367 if (I_klimt_flood_fill_4_connexity != I_klimt_flood_fill_4_connexity_check) {
369 "I_klimt_flood_fill_4_connexity_check)");
371 if (I_klimt_flood_fill_8_connexity != I_klimt_flood_fill_8_connexity_check) {
373 "I_klimt_flood_fill_8_connexity_check)");
376 std::cout <<
"\nTest flood fill is ok!" << std::endl;
380 std::cerr <<
"Catch an exception: " <<
e.what() << std::endl;
386 std::cout <<
"Install OpenCV imgproc module required by this test" << 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)
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(VISP_NAMESPACE_ADDRESSING vpImage< unsigned char > &I, const VISP_NAMESPACE_ADDRESSING vpImagePoint &seedPoint, const unsigned char oldValue, const unsigned char newValue, const VISP_NAMESPACE_ADDRESSING vpImageMorphology::vpConnexityType &connexity=VISP_NAMESPACE_ADDRESSING vpImageMorphology::CONNEXITY_4)
VISP_EXPORT double measureTimeMs()