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 flood fill algorithm.\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);
108bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &opath, std::string user)
122 usage(argv[0], NULL, ipath, opath, user);
131 usage(argv[0], optarg_, ipath, opath, user);
137 if ((c == 1) || (c == -1)) {
139 usage(argv[0], NULL, ipath, opath, user);
140 std::cerr <<
"ERROR: " << std::endl;
141 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
150 std::cout <<
"\n" << name <<
":" << std::endl;
153 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
154 std::cout << std::setfill(
' ') << std::setw(2) << j <<
" ";
156 std::cout << std::endl;
158 std::cout << std::setfill(
' ') << std::setw(3) <<
"+";
159 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
160 std::cout << std::setw(3) <<
"---";
162 std::cout << std::endl;
164 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
165 std::cout << std::setfill(
' ') << std::setw(2) << i <<
"|";
167 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
168 std::cout << std::setfill(' ') << std::setw(2) << static_cast<unsigned int>(I[i][j]) <<
" ";
171 std::cout << std::endl;
175int main(
int argc,
const char **argv)
177#if defined(HAVE_OPENCV_IMGPROC)
179 std::string env_ipath;
180 std::string opt_ipath;
181 std::string opt_opath;
184 std::string filename;
185 std::string username;
192 if (!env_ipath.empty())
197 opt_opath =
"C:/temp";
206 if (getOptions(argc, argv, opt_ipath, opt_opath, username) ==
false) {
211 if (!opt_ipath.empty())
213 if (!opt_opath.empty())
225 usage(argv[0], NULL, ipath, opt_opath, username);
226 std::cerr << std::endl <<
"ERROR:" << std::endl;
227 std::cerr <<
" Cannot create " << opath << std::endl;
228 std::cerr <<
" Check your -o " << opt_opath <<
" option " << std::endl;
235 if (!opt_ipath.empty() && !env_ipath.empty()) {
236 if (ipath != env_ipath) {
237 std::cout << std::endl <<
"WARNING: " << std::endl;
238 std::cout <<
" Since -i <visp image path=" << ipath <<
"> "
239 <<
" is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
240 <<
" we skip the environment variable." << std::endl;
245 if (opt_ipath.empty() && env_ipath.empty()) {
246 usage(argv[0], NULL, ipath, opt_opath, username);
247 std::cerr << std::endl <<
"ERROR:" << std::endl;
248 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
249 <<
" environment variable to specify the location of the " << std::endl
250 <<
" image path where test images are located." << std::endl
259 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,
260 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1,
261 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0};
264 printImage(I_test_flood_fill_4_connexity,
"Test image data");
266 unsigned char image_data_check_4_connexity[8 * 8] = {
267 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,
268 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};
271 unsigned char image_data_check_8_connexity[8 * 8] = {
272 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,
273 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};
278 printImage(I_test_flood_fill_4_connexity,
"I_test_flood_fill_4_connexity");
280 if (I_test_flood_fill_4_connexity != I_check_4_connexity) {
283 std::cout <<
"\n(I_test_flood_fill_4_connexity == I_check_4_connexity)? "
284 << (I_test_flood_fill_4_connexity == I_check_4_connexity) << std::endl;
288 printImage(I_test_flood_fill_8_connexity,
"I_test_flood_fill_8_connexity");
290 if (I_test_flood_fill_8_connexity != I_check_8_connexity) {
293 std::cout <<
"\n(I_test_flood_fill_8_connexity == I_check_8_connexity)? "
294 << (I_test_flood_fill_8_connexity == I_check_8_connexity) << std::endl;
300 std::cout <<
"\nRead image: " << filename <<
" (" << I_klimt.
getWidth() <<
"x" << I_klimt.
getHeight() <<
")"
303 vpImageTools::binarise(I_klimt, (
unsigned char)127, (
unsigned char)255, (
unsigned char)0, (
unsigned char)255,
313 std::cout <<
"Flood fill on Klimt image (4-connexity): " << t <<
" ms" << std::endl;
322 std::cout <<
"Flood fill on Klimt image (8-connexity): " << t <<
" ms" << std::endl;
326 cv::Mat matImg_klimt_4_connexity, matImg_klimt_8_connexity;
332 cv::floodFill(matImg_klimt_4_connexity, cv::Point(seed_x, seed_y), cv::Scalar(255), 0, cv::Scalar(), cv::Scalar(),
335 std::cout <<
"OpenCV flood fill on Klimt image (4-connexity): " << t <<
" ms" << std::endl;
345 cv::floodFill(matImg_klimt_8_connexity, cv::Point(seed_x, seed_y), cv::Scalar(255), 0, cv::Scalar(), cv::Scalar(),
348 std::cout <<
"OpenCV flood fill on Klimt image (8-connexity): " << t <<
" ms" << std::endl;
357 std::cout <<
"\n(I_klimt_flood_fill_4_connexity == "
358 "I_klimt_flood_fill_4_connexity_check)? "
359 << (I_klimt_flood_fill_4_connexity == I_klimt_flood_fill_4_connexity_check) << std::endl;
360 std::cout <<
"(I_klimt_flood_fill_8_connexity == "
361 "I_klimt_flood_fill_8_connexity_check)? "
362 << (I_klimt_flood_fill_8_connexity == I_klimt_flood_fill_8_connexity_check) << std::endl;
364 if (I_klimt_flood_fill_4_connexity != I_klimt_flood_fill_4_connexity_check) {
366 "I_klimt_flood_fill_4_connexity_check)");
368 if (I_klimt_flood_fill_8_connexity != I_klimt_flood_fill_8_connexity_check) {
370 "I_klimt_flood_fill_8_connexity_check)");
373 std::cout <<
"\nTest flood fill is ok!" << std::endl;
376 std::cerr <<
"Catch an exception: " << e.
what() << std::endl;
382 std::cout <<
"Install OpenCV imgproc module required by this test" << 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)
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()