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