35#include <visp3/core/vpImageTools.h>
36#include <visp3/core/vpIoTools.h>
37#include <visp3/imgproc/vpImgproc.h>
38#include <visp3/io/vpImageIo.h>
39#include <visp3/io/vpParseArgv.h>
48#define GETOPTARGS "cdi:o:h"
50void usage(
const char *name,
const char *badparam, std::string ipath, std::string opath, std::string user);
51bool 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 connected components.\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;
154 std::map<int, std::vector<vpImagePoint> > map_label1, map_label2;
155 for (
unsigned int i = 0; i < label1.
getHeight(); i++) {
156 for (
unsigned int j = 0; j < label1.
getWidth(); j++) {
157 if ((label1[i][j] > 0 && label2[i][j] == 0) || (label1[i][j] == 0 && label2[i][j] > 0)) {
158 std::cerr <<
"label1[i][j] > 0 && label2[i][j] == 0 || label1[i][j] "
159 "== 0 && label2[i][j] > 0"
172 if (map_label1.size() != map_label2.size()) {
173 std::cerr <<
"map_label1.size() != map_label2.size()" << std::endl;
177 for (std::map<
int, std::vector<vpImagePoint> >::const_iterator it1 = map_label1.begin(); it1 != map_label1.end();
180 unsigned int i = (
unsigned int)it1->second.front().get_i(), j = (
unsigned int)it1->second.front().get_j();
181 int lab2 = label2[i][j];
183 std::vector<vpImagePoint>::const_iterator it_pt1 = it1->second.begin();
184 for (; it_pt1 != it1->second.end(); ++it_pt1) {
185 i = (
unsigned int)it_pt1->get_i();
186 j = (
unsigned int)it_pt1->get_j();
187 if (label2[i][j] != lab2) {
188 std::cerr <<
"label2[i][j] != lab2" << std::endl;
197int main(
int argc,
const char **argv)
200 std::string env_ipath;
201 std::string opt_ipath;
202 std::string opt_opath;
205 std::string filename;
206 std::string username;
213 if (!env_ipath.empty())
218 opt_opath =
"C:/temp";
227 if (getOptions(argc, argv, opt_ipath, opt_opath, username) ==
false) {
232 if (!opt_ipath.empty())
234 if (!opt_opath.empty())
246 usage(argv[0], NULL, ipath, opt_opath, username);
247 std::cerr << std::endl <<
"ERROR:" << std::endl;
248 std::cerr <<
" Cannot create " << opath << std::endl;
249 std::cerr <<
" Check your -o " << opt_opath <<
" option " << std::endl;
256 if (!opt_ipath.empty() && !env_ipath.empty()) {
257 if (ipath != env_ipath) {
258 std::cout << std::endl <<
"WARNING: " << std::endl;
259 std::cout <<
" Since -i <visp image path=" << ipath <<
"> "
260 <<
" is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
261 <<
" we skip the environment variable." << std::endl;
266 if (opt_ipath.empty() && env_ipath.empty()) {
267 usage(argv[0], NULL, ipath, opt_opath, username);
268 std::cerr << std::endl <<
"ERROR:" << std::endl;
269 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
270 <<
" environment variable to specify the location of the " << std::endl
271 <<
" image path where test images are located." << std::endl
283 std::cout <<
"Read image: " << filename << std::endl;
290 int nbComponents = 0;
294 std::cout <<
"\n4-connexity connected components:" << std::endl;
295 std::cout <<
"Time: " << t <<
" ms" << std::endl;
296 std::cout <<
"nbComponents=" << nbComponents << std::endl;
302 std::cout <<
"\n8-connexity connected components:" << std::endl;
303 std::cout <<
"Time: " << t <<
" ms" << std::endl;
304 std::cout <<
"nbComponents=" << nbComponents << std::endl;
308 for (
unsigned int i = 0; i < labels_connex4.
getHeight(); i++) {
309 for (
unsigned int j = 0; j < labels_connex4.
getWidth(); j++) {
310 if (labels_connex4[i][j] != 0) {
322 for (
unsigned int i = 0; i < labels_connex8.
getHeight(); i++) {
323 for (
unsigned int j = 0; j < labels_connex8.
getWidth(); j++) {
324 if (labels_connex8[i][j] != 0) {
335#if (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGPROC)
341 cv::connectedComponents(matImg, matLabels_4, 4);
344 std::set<int> set_labels_connex4_opencv;
345 vpImage<int> labels_connex4_opencv((
unsigned int)matLabels_4.rows, (
unsigned int)matLabels_4.cols);
346 for (
int i = 0; i < matLabels_4.rows; i++) {
347 for (
int j = 0; j < matLabels_4.cols; j++) {
348 labels_connex4_opencv[i][j] = matLabels_4.at<
int>(i, j);
350 if (matLabels_4.at<
int>(i, j))
351 set_labels_connex4_opencv.insert(matLabels_4.at<
int>(i, j));
355 std::cout <<
"\n4-connexity connected components (OpenCV):" << std::endl;
356 std::cout <<
"Time: " << t_opencv <<
" ms" << std::endl;
357 std::cout <<
"nb components: " << set_labels_connex4_opencv.size() << std::endl;
358 bool check_label = checkLabels(labels_connex4_opencv, labels_connex4);
359 std::cout <<
"checkLabels(labels_connex4_opencv, labels_connex4): " << check_label << std::endl;
368 cv::connectedComponents(matImg, matLabels_8, 8);
371 std::set<int> set_labels_connex8_opencv;
372 vpImage<int> labels_connex8_opencv((
unsigned int)matLabels_8.rows, (
unsigned int)matLabels_8.cols);
373 for (
int i = 0; i < matLabels_8.rows; i++) {
374 for (
int j = 0; j < matLabels_8.cols; j++) {
375 labels_connex8_opencv[i][j] = matLabels_8.at<
int>(i, j);
377 if (matLabels_8.at<
int>(i, j))
378 set_labels_connex8_opencv.insert(matLabels_8.at<
int>(i, j));
382 std::cout <<
"\n8-connexity connected components (OpenCV):" << std::endl;
383 std::cout <<
"nb components: " << set_labels_connex8_opencv.size() << std::endl;
384 std::cout <<
"Time: " << t_opencv <<
" ms" << std::endl;
385 check_label = checkLabels(labels_connex8_opencv, labels_connex8);
386 std::cout <<
"checkLabels(labels_connex8_opencv, labels_connex8): " << check_label << std::endl;
397 std::cerr <<
"Catch an exception: " << e.
what() << std::endl;
static vpColor getColor(const unsigned int &i)
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 connectedComponents(const vpImage< unsigned char > &I, vpImage< int > &labels, int &nbComponents, const vpImageMorphology::vpConnexityType &connexity=vpImageMorphology::CONNEXITY_4)
VISP_EXPORT double measureTimeMs()