Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testPolygon.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Example which test the polygon.
32  *
33  * Author:
34  * Romain Tallonneau
35  *
36  *****************************************************************************/
37 #include <visp3/core/vpConfig.h>
38 #include <visp3/core/vpPolygon.h>
39 #include <visp3/io/vpParseArgv.h>
40 #include <visp3/core/vpImagePoint.h>
41 
42 #include <visp3/core/vpDisplay.h>
43 #include <visp3/gui/vpDisplayX.h>
44 #include <visp3/gui/vpDisplayGTK.h>
45 #include <visp3/gui/vpDisplayGDI.h>
46 
47 
48 #include <math.h>
49 
50 #include <iostream>
51 #include <string>
52 #include <vector>
53 
55 #define GETOPTARGS "cdm:h"
56 
57 void usage(const char *name, const char *badparam);
58 bool getOptions(int argc, const char **argv, bool& opt_display, bool& opt_click, int &method);
59 
68 void usage(const char *name, const char *badparam)
69 {
70  fprintf(stdout, "\n\
71 test the generic 2D polygons.\n\
72 \n\
73 SYNOPSIS\n\
74  %s [-c] [-d] [-h]\n \
75 ", name);
76 
77  fprintf(stdout, "\n\
78 OPTIONS: \n\
79  -c \n\
80  Disable mouse click.\n\
81 \n\
82  -d \n\
83  Turn off display.\n\
84 \n\
85  -m \n\
86  Point in polygon test method.\n\
87 \n\
88  -h\n\
89  Print the help.\n\n");
90 
91  if (badparam) {
92  fprintf(stderr, "ERROR: \n" );
93  fprintf(stderr, "\nBad parameter [%s]\n", badparam);
94  }
95 }
96 
106 bool getOptions(int argc, const char **argv, bool& opt_display, bool& opt_click, int &method)
107 {
108  const char *optarg_;
109  int c;
110  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
111 
112  switch (c) {
113  case 'c': opt_click = false; break;
114  case 'd': opt_display = false; break;
115  case 'm': method = atoi(optarg_); break;
116  case 'h': usage(argv[0], NULL); return false; break;
117 
118  default:
119  usage(argv[0], optarg_); return false; break;
120  }
121  }
122 
123  if ((c == 1) || (c == -1)) {
124  // standalone param or error
125  usage(argv[0], NULL);
126  std::cerr << "ERROR: " << std::endl;
127  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
128  return false;
129  }
130 
131  return true;
132 }
133 
134 /* -------------------------------------------------------------------------- */
135 /* MAIN FUNCTION */
136 /* -------------------------------------------------------------------------- */
137 
138 int
139 main(int argc, const char** argv)
140 {
141  try {
142  bool opt_display = true;
143  bool opt_click = true;
145  vpImage<unsigned char> I(480, 640, 255);
146 
147  // Read the command line options
148  if (getOptions(argc, argv, opt_display, opt_click, method) == false) {
149  return (-1);
150  }
151 
152  std::vector <vpImagePoint> vec1;
153  vec1.push_back(vpImagePoint(200, 200));
154  vec1.push_back(vpImagePoint(200, 400));
155  vec1.push_back(vpImagePoint(320, 400));
156  vec1.push_back(vpImagePoint(380, 300));
157  vec1.push_back(vpImagePoint(280, 280));
158  vpPolygon p1;
159  p1.buildFrom(vec1);
160 
161  std::vector <vpImagePoint> vec2;
162  vec2.push_back(vpImagePoint(20, 20));
163  vec2.push_back(vpImagePoint(100, 20));
164  vec2.push_back(vpImagePoint(100, 100));
165  vec2.push_back(vpImagePoint(20, 100));
166  vpPolygon p2(vec2);
167 
168 
169  std::vector <vpImagePoint> vec3;
170  vpPolygon p3(vec3);
171 
172 #if defined VISP_HAVE_X11
173  vpDisplayX display;
174 #elif defined VISP_HAVE_GTK
175  vpDisplayGTK display;
176 #elif defined VISP_HAVE_GDI
177  vpDisplayGDI display;
178 #else
179  opt_display = false;
180 #endif
181 
182  std::cout << " Polygon 1 : " << std::endl;
183  std::cout << " area : " << p1.getArea() << std::endl;
184  std::cout << " center : " << p1.getCenter() << std::endl << std::endl;
185 
186  std::cout << " Polygon 2 : " << std::endl;
187  std::cout << " area : " << p2.getArea() << std::endl;
188  std::cout << " center : " << p2.getCenter() << std::endl << std::endl;
189 
190  std::cout << " Polygon 3 : " << std::endl;
191  std::cout << " area : " << p3.getArea() << std::endl;
192  std::cout << " center : " << p3.getCenter() << std::endl;
193 
194 
195  if(opt_display) {
196 #if (defined VISP_HAVE_X11) || (defined VISP_HAVE_GTK) || (defined VISP_HAVE_GDI)
197  display.init(I, 10, 10, "Test vpPolygon");
198 #endif
200  p1.display(I, vpColor::green, 1);
202  p2.display(I, vpColor::red, 1);
203  vpDisplay::displayCross(I, p2.getCenter(), 5, vpColor::red);
204  p3.display(I, vpColor::blue, 1);
205  vpDisplay::displayCross(I, p3.getCenter(), 5, vpColor::lightBlue);
206  vpDisplay::displayText(I, vpImagePoint(10, 10), "Click to finish", vpColor::red);
207  vpDisplay::flush(I);
208 
209  if (opt_click)
211 
212 
214  vpDisplay::displayText(I, vpImagePoint(10, 10), "Left click to add a point", vpColor::red);
215  vpDisplay::displayText(I, vpImagePoint(20, 10), "Right click to build the polygon", vpColor::red);
216  vpDisplay::flush(I);
217  if (opt_click) {
218  vpPolygon p4;
219  p4.initClick(I);
220  p4.display(I, vpColor::green, 1);
221  std::cout << std::endl;
222  std::cout << " Polygon 4 : " << std::endl;
223  std::cout << " area : " << p4.getArea() << std::endl;
224  std::cout << " center : " << p4.getCenter() << std::endl;
225  std::cout << "Click to continue." << std::endl;
226  vpDisplay::flush(I);
228 
229  vpRect bbox = p4.getBoundingBox();
230  for(unsigned int i= (unsigned int)floor(bbox.getTop()); i<(unsigned int)ceil(bbox.getBottom()); ++i){
231  for(unsigned int j=(unsigned int)floor(bbox.getLeft()); j<(unsigned int)ceil(bbox.getRight()); ++j){
232  if(p4.isInside(vpImagePoint(i, j), (vpPolygon::PointInPolygonMethod) method)){
234  }
235  }
236  }
237  vpDisplay::flush(I);
238 
239  std::cout << "Click to continue." << std::endl;
241  for(unsigned int i= 0; i<I.getHeight(); ++i){
242  for(unsigned int j=0; j<I.getWidth(); ++j){
245  }
246  }
247  }
248  vpDisplay::flush(I);
249 
250  std::cout << "Click to finish." << std::endl;
251 
253  vpDisplay::close(I);
254 
255  //Benchmark Point In Polygon test method
256  std::vector<vpImagePoint> corners = p4.getCorners();
257  std::cout << "Nb polygon corners=" << corners.size() << std::endl;
258 
259  vpPolygon polygon_benchmark(corners);
260  vpImage<unsigned char> I_segmentIntersection(480, 640, 0);
261  vpImage<unsigned char> I_rayCasting(480, 640, 0);
262 
263  double t_benchmark = vpTime::measureTimeMs();
264  for (unsigned int i = 0; i < I_segmentIntersection.getHeight(); i++) {
265  for (unsigned int j = 0; j < I_segmentIntersection.getWidth(); j++) {
266  if (polygon_benchmark.isInside(vpImagePoint(i, j), vpPolygon::PnPolySegmentIntersection)) {
267  I_segmentIntersection[i][j] = 255;
268  }
269  }
270  }
271  t_benchmark = vpTime::measureTimeMs() - t_benchmark;
272  std::cout << "PnPolySegmentIntersection: " << t_benchmark << " ms" << std::endl;
273 
274  t_benchmark = vpTime::measureTimeMs();
275  for (unsigned int i = 0; i < I_rayCasting.getHeight(); i++) {
276  for (unsigned int j = 0; j < I_rayCasting.getWidth(); j++) {
277  if (polygon_benchmark.isInside(vpImagePoint(i, j), vpPolygon::PnPolyRayCasting)) {
278  I_rayCasting[i][j] = 255;
279  }
280  }
281  }
282  t_benchmark = vpTime::measureTimeMs() - t_benchmark;
283  std::cout << "PnPolyRayCasting: " << t_benchmark << " ms" << std::endl;
284 
285 #if defined VISP_HAVE_X11
286  vpDisplayX display1, display2;
287 #elif defined VISP_HAVE_GTK
288  vpDisplayGTK display1, display2;
289 #elif defined VISP_HAVE_GDI
290  vpDisplayGDI display1, display2;
291 #endif
292 
293 #if (defined VISP_HAVE_X11) || (defined VISP_HAVE_GTK) || (defined VISP_HAVE_GDI)
294  display1.init(I_segmentIntersection, 10, 10, "Segment Intersection test");
295  display2.init(I_rayCasting, (int)I_segmentIntersection.getWidth() + 10, 10, "Ray Casting test");
296 #endif
297 
298  vpDisplay::display(I_segmentIntersection);
299  vpDisplay::display(I_rayCasting);
300  vpDisplay::displayText(I_rayCasting, 20, 20, "Click to quit.", vpColor::red);
301  vpDisplay::flush(I_segmentIntersection);
302  vpDisplay::flush(I_rayCasting);
303 
304  vpDisplay::getClick(I_rayCasting);
305  }
306  }
307 
308  return 0;
309  }
310  catch(vpException &e) {
311  std::cout << "Catch an exception: " << e << std::endl;
312  return 1;
313  }
314 }
315 
316 
double getTop() const
Definition: vpRect.h:178
const std::vector< vpImagePoint > & getCorners() const
Definition: vpPolygon.h:143
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void close(vpImage< unsigned char > &I)
unsigned int getWidth() const
Definition: vpImage.h:226
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:153
error that can be emited by ViSP classes.
Definition: vpException.h:73
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
double getRight() const
Definition: vpRect.h:165
static const vpColor green
Definition: vpColor.h:166
static void flush(const vpImage< unsigned char > &I)
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:93
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:76
static const vpColor red
Definition: vpColor.h:163
static const vpColor orange
Definition: vpColor.h:173
bool isInside(const vpImagePoint &iP, const PointInPolygonMethod &method=PnPolyRayCasting) const
Definition: vpPolygon.cpp:303
Defines a generic 2D polygon.
Definition: vpPolygon.h:99
double getBottom() const
Definition: vpRect.h:100
vpRect getBoundingBox() const
Definition: vpPolygon.h:174
PointInPolygonMethod
Definition: vpPolygon.h:114
static void display(const vpImage< unsigned char > &I)
double getArea() const
Definition: vpPolygon.h:154
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:138
vpImagePoint getCenter() const
Definition: vpPolygon.h:164
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
void initClick(const vpImage< unsigned char > &I)
Definition: vpPolygon.cpp:193
unsigned int getHeight() const
Definition: vpImage.h:175
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
Defines a rectangle in the plane.
Definition: vpRect.h:82
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
static const vpColor lightBlue
Definition: vpColor.h:168
double getLeft() const
Definition: vpRect.h:159
void buildFrom(const std::vector< vpImagePoint > &corners)
Definition: vpPolygon.cpp:147
static const vpColor blue
Definition: vpColor.h:169
void display(const vpImage< unsigned char > &I, const vpColor &color, unsigned int thickness=1) const
Definition: vpPolygon.cpp:517