Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
testPolygon.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
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 https://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
37#include <visp3/core/vpConfig.h>
38#include <visp3/core/vpImagePoint.h>
39#include <visp3/core/vpPolygon.h>
40#include <visp3/io/vpParseArgv.h>
41
42#include <visp3/core/vpDisplay.h>
43#include <visp3/gui/vpDisplayGDI.h>
44#include <visp3/gui/vpDisplayGTK.h>
45#include <visp3/gui/vpDisplayX.h>
46
47#include <math.h>
48
49#include <iostream>
50#include <string>
51#include <vector>
52
54#define GETOPTARGS "cdm:h"
55
56void usage(const char *name, const char *badparam);
57bool getOptions(int argc, const char **argv, bool &opt_display, bool &opt_click, int &method);
58
67void usage(const char *name, const char *badparam)
68{
69 fprintf(stdout, "\n\
70test the generic 2D polygons.\n\
71\n\
72SYNOPSIS\n\
73 %s [-c] [-d] [-h]\n\
74",
75name);
76
77 fprintf(stdout, "\n\
78OPTIONS: \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
106bool getOptions(int argc, const char **argv, bool &opt_display, bool &opt_click, int &method)
107{
108#ifdef ENABLE_VISP_NAMESPACE
109 using namespace VISP_NAMESPACE_NAME;
110#endif
111 const char *optarg_;
112 int c;
113 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
114
115 switch (c) {
116 case 'c':
117 opt_click = false;
118 break;
119 case 'd':
120 opt_display = false;
121 break;
122 case 'm':
123 method = atoi(optarg_);
124 break;
125 case 'h':
126 usage(argv[0], nullptr);
127 return false;
128
129 default:
130 usage(argv[0], optarg_);
131 return false;
132 }
133 }
134
135 if ((c == 1) || (c == -1)) {
136 // standalone param or error
137 usage(argv[0], nullptr);
138 std::cerr << "ERROR: " << std::endl;
139 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
140 return false;
141 }
142
143 return true;
144}
145
146/* --------------------------------------------------------------------------
147 */
148 /* MAIN FUNCTION */
149 /* --------------------------------------------------------------------------
150 */
151
152int main(int argc, const char **argv)
153{
154#ifdef ENABLE_VISP_NAMESPACE
155 using namespace VISP_NAMESPACE_NAME;
156#endif
157 try {
158 bool opt_display = true;
159 bool opt_click = true;
161 vpImage<unsigned char> I(480, 640, 255);
162
163 // Read the command line options
164 if (getOptions(argc, argv, opt_display, opt_click, method) == false) {
165 return EXIT_FAILURE;
166 }
167
168 std::vector<vpImagePoint> vec1;
169 vec1.push_back(vpImagePoint(200, 200));
170 vec1.push_back(vpImagePoint(200, 400));
171 vec1.push_back(vpImagePoint(320, 400));
172 vec1.push_back(vpImagePoint(380, 300));
173 vec1.push_back(vpImagePoint(280, 280));
174 vpPolygon p1;
175 p1.buildFrom(vec1);
176
177 std::vector<vpImagePoint> vec2;
178 vec2.push_back(vpImagePoint(20, 20));
179 vec2.push_back(vpImagePoint(100, 20));
180 vec2.push_back(vpImagePoint(100, 100));
181 vec2.push_back(vpImagePoint(20, 100));
182 vpPolygon p2(vec2);
183
184 std::vector<vpImagePoint> vec3;
185 vpPolygon p3(vec3);
186
187#if defined(VISP_HAVE_X11)
188 vpDisplayX display;
189#elif defined(VISP_HAVE_GTK)
190 vpDisplayGTK display;
191#elif defined(VISP_HAVE_GDI)
192 vpDisplayGDI display;
193#else
194 opt_display = false;
195#endif
196
197 std::cout << " Polygon 1 : " << std::endl;
198 std::cout << " area : " << p1.getArea() << std::endl;
199 std::cout << " center : " << p1.getCenter() << std::endl << std::endl;
200
201 std::cout << " Polygon 2 : " << std::endl;
202 std::cout << " area : " << p2.getArea() << std::endl;
203 std::cout << " center : " << p2.getCenter() << std::endl << std::endl;
204
205 std::cout << " Polygon 3 : " << std::endl;
206 std::cout << " area : " << p3.getArea() << std::endl;
207 std::cout << " center : " << p3.getCenter() << std::endl;
208
209 if (opt_display) {
210#if (defined VISP_HAVE_X11) || (defined VISP_HAVE_GTK) || (defined VISP_HAVE_GDI)
211 display.init(I, 10, 10, "Test vpPolygon");
212#endif
214 p1.display(I, vpColor::green, 1);
216 p2.display(I, vpColor::red, 1);
217 vpDisplay::displayCross(I, p2.getCenter(), 5, vpColor::red);
218 p3.display(I, vpColor::blue, 1);
219 vpDisplay::displayCross(I, p3.getCenter(), 5, vpColor::lightBlue);
220 vpDisplay::displayText(I, vpImagePoint(10, 10), "Click to finish", vpColor::red);
222
223 if (opt_click)
225
227 vpDisplay::displayText(I, vpImagePoint(10, 10), "Left click to add a point", vpColor::red);
228 vpDisplay::displayText(I, vpImagePoint(20, 10), "Right click to build the polygon", vpColor::red);
230 if (opt_click) {
231 vpPolygon p4;
232 p4.initClick(I);
233 p4.display(I, vpColor::green, 1);
234 std::cout << std::endl;
235 std::cout << " Polygon 4 : " << std::endl;
236 std::cout << " area : " << p4.getArea() << std::endl;
237 std::cout << " center : " << p4.getCenter() << std::endl;
238 std::cout << "Click to continue." << std::endl;
241
242 vpRect bbox = p4.getBoundingBox();
243 for (unsigned int i = static_cast<unsigned int>(floor(bbox.getTop())); i < static_cast<unsigned int>(ceil(bbox.getBottom())); ++i) {
244 for (unsigned int j = static_cast<unsigned int>(floor(bbox.getLeft())); j < static_cast<unsigned int>(ceil(bbox.getRight())); ++j) {
247 }
248 }
249 }
251
252 std::cout << "Click to continue." << std::endl;
254 for (unsigned int i = 0; i < I.getHeight(); ++i) {
255 for (unsigned int j = 0; j < I.getWidth(); ++j) {
258 }
259 }
260 }
262
263 std::cout << "Click to finish." << std::endl;
264
267
268 // Benchmark Point In Polygon test method
269 std::vector<vpImagePoint> corners = p4.getCorners();
270 std::cout << "Nb polygon corners=" << corners.size() << std::endl;
271
272 vpPolygon polygon_benchmark(corners);
273 vpImage<unsigned char> I_segmentIntersection(480, 640, 0);
274 vpImage<unsigned char> I_rayCasting(480, 640, 0);
275
276 double t_benchmark = vpTime::measureTimeMs();
277 for (unsigned int i = 0; i < I_segmentIntersection.getHeight(); i++) {
278 for (unsigned int j = 0; j < I_segmentIntersection.getWidth(); j++) {
279 if (polygon_benchmark.isInside(vpImagePoint(i, j), vpPolygon::PnPolySegmentIntersection)) {
280 I_segmentIntersection[i][j] = 255;
281 }
282 }
283 }
284 t_benchmark = vpTime::measureTimeMs() - t_benchmark;
285 std::cout << "PnPolySegmentIntersection: " << t_benchmark << " ms" << std::endl;
286
287 t_benchmark = vpTime::measureTimeMs();
288 for (unsigned int i = 0; i < I_rayCasting.getHeight(); i++) {
289 for (unsigned int j = 0; j < I_rayCasting.getWidth(); j++) {
290 if (polygon_benchmark.isInside(vpImagePoint(i, j), vpPolygon::PnPolyRayCasting)) {
291 I_rayCasting[i][j] = 255;
292 }
293 }
294 }
295 t_benchmark = vpTime::measureTimeMs() - t_benchmark;
296 std::cout << "PnPolyRayCasting: " << t_benchmark << " ms" << std::endl;
297
298#if defined(VISP_HAVE_X11)
299 vpDisplayX display1, display2;
300#elif defined(VISP_HAVE_GTK)
301 vpDisplayGTK display1, display2;
302#elif defined(VISP_HAVE_GDI)
303 vpDisplayGDI display1, display2;
304#endif
305
306#if (defined VISP_HAVE_X11) || (defined VISP_HAVE_GTK) || (defined VISP_HAVE_GDI)
307 display1.init(I_segmentIntersection, 10, 10, "Segment Intersection test");
308 display2.init(I_rayCasting, static_cast<int>(I_segmentIntersection.getWidth()) + 10, 10, "Ray Casting test");
309#endif
310
311 vpDisplay::display(I_segmentIntersection);
312 vpDisplay::display(I_rayCasting);
313 vpDisplay::displayText(I_rayCasting, 20, 20, "Click to quit.", vpColor::red);
314 vpDisplay::flush(I_segmentIntersection);
315 vpDisplay::flush(I_rayCasting);
316
317 vpDisplay::getClick(I_rayCasting);
318 }
319 }
320
321 return EXIT_SUCCESS;
322 }
323 catch (const vpException &e) {
324 std::cout << "Catch an exception: " << e << std::endl;
325 return EXIT_FAILURE;
326 }
327}
static const vpColor red
Definition vpColor.h:198
static const vpColor orange
Definition vpColor.h:208
static const vpColor blue
Definition vpColor.h:204
static const vpColor lightBlue
Definition vpColor.h:203
static const vpColor green
Definition vpColor.h:201
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:135
void init(vpImage< unsigned char > &I, int win_x=-1, int win_y=-1, const std::string &win_title="") VP_OVERRIDE
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 close(vpImage< unsigned char > &I)
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:60
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:131
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Defines a generic 2D polygon.
Definition vpPolygon.h:103
void display(const vpImage< unsigned char > &I, const vpColor &color, unsigned int thickness=1) const
vpRect getBoundingBox() const
Definition vpPolygon.h:164
vpPolygon & buildFrom(const std::vector< vpImagePoint > &corners, const bool &create_convex_hull=false)
vpImagePoint getCenter() const
Definition vpPolygon.h:156
const std::vector< vpImagePoint > & getCorners() const
Definition vpPolygon.h:140
double getArea() const
Definition vpPolygon.h:148
PointInPolygonMethod
Definition vpPolygon.h:106
@ PnPolyRayCasting
Definition vpPolygon.h:108
@ PnPolySegmentIntersection
Definition vpPolygon.h:107
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:79
double getLeft() const
Definition vpRect.h:173
double getRight() const
Definition vpRect.h:179
double getBottom() const
Definition vpRect.h:97
double getTop() const
Definition vpRect.h:192
VISP_EXPORT double measureTimeMs()