39 #include <visp3/core/vpDisplay.h>
40 #include <visp3/core/vpException.h>
41 #include <visp3/core/vpMeterPixelConversion.h>
42 #include <visp3/core/vpPolygon.h>
43 #include <visp3/core/vpUniRand.h>
46 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
48 #include <opencv2/imgproc/imgproc.hpp>
56 template <
typename IpContainer> std::vector<VISP_NAMESPACE_ADDRESSING vpImagePoint> convexHull(
const IpContainer &ips)
58 #ifdef ENABLE_VISP_NAMESPACE
61 if (ips.size() == 0) {
63 "Convex Hull can not be computed as the input does not contain any image point.");
67 std::vector<cv::Point> cv_pts;
68 #if ((__cplusplus >= 201402L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201402L)))
69 std::transform(cbegin(ips), cend(ips), std::back_inserter(cv_pts), [](
const vpImagePoint &ip) {
70 return cv::Point(
static_cast<int>(ip.
get_u()),
static_cast<int>(ip.
get_v()));
72 #elif ((__cplusplus >= 201103L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)))
73 std::transform(begin(ips), end(ips), std::back_inserter(cv_pts), [](
const vpImagePoint &ip) {
74 return cv::Point(
static_cast<int>(ip.
get_u()),
static_cast<int>(ip.
get_v()));
77 for (
typename IpContainer::const_iterator it = ips.begin(); it != ips.end(); ++it) {
78 cv_pts.push_back(cv::Point(
static_cast<int>(it->get_u()),
static_cast<int>(it->get_v())));
83 std::vector<cv::Point> cv_conv_hull_corners;
84 cv::convexHull(cv_pts, cv_conv_hull_corners);
87 std::vector<vpImagePoint> conv_hull_corners;
88 #if ((__cplusplus >= 201402L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201402L)))
89 std::transform(cbegin(cv_conv_hull_corners), cend(cv_conv_hull_corners), std::back_inserter(conv_hull_corners),
90 [](
const cv::Point &pt) {
91 return vpImagePoint {
static_cast<double>(pt.y),
static_cast<double>(pt.x) };
93 #elif ((__cplusplus >= 201103L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)))
94 std::transform(begin(cv_conv_hull_corners), end(cv_conv_hull_corners), std::back_inserter(conv_hull_corners),
95 [](
const cv::Point &pt) {
96 return vpImagePoint {
static_cast<double>(pt.y),
static_cast<double>(pt.x) };
99 for (std::vector<cv::Point>::const_iterator it = cv_conv_hull_corners.begin(); it != cv_conv_hull_corners.end();
101 conv_hull_corners.push_back(
vpImagePoint(
static_cast<double>(it->y),
static_cast<double>(it->x)));
105 return conv_hull_corners;
115 : _corners(), _center(), _area(0.), _goodPoly(true), _bbox(), m_PnPolyConstants(), m_PnPolyMultiples()
127 : _corners(), _center(), _area(0.), _goodPoly(true), _bbox(), m_PnPolyConstants(), m_PnPolyMultiples()
129 if (corners.size() < 3) {
144 : _corners(), _center(), _area(0.), _goodPoly(true), _bbox(), m_PnPolyConstants(), m_PnPolyMultiples()
146 if (corners.size() < 3) {
158 : _corners(poly._corners), _center(poly._center), _area(poly._area), _goodPoly(poly._goodPoly), _bbox(poly._bbox),
159 m_PnPolyConstants(poly.m_PnPolyConstants), m_PnPolyMultiples(poly.m_PnPolyMultiples)
179 m_PnPolyConstants = poly.m_PnPolyConstants;
180 m_PnPolyMultiples = poly.m_PnPolyMultiples;
184 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
197 build(corners, create_convex_hull);
212 build(corners, create_convex_hull);
229 const bool create_convex_hull)
231 build(corners, cam, create_convex_hull);
246 if (create_convex_hull) {
247 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
248 init(convexHull(corners));
270 if (create_convex_hull) {
271 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
272 init(convexHull(corners));
296 const bool &create_convex_hull)
298 std::vector<vpImagePoint> ipCorners(corners.size());
299 size_t corners_size = corners.size();
300 for (
size_t i = 0; i < corners_size; ++i) {
303 build(ipCorners, create_convex_hull);
317 unsigned int thickness)
322 std::vector<vpImagePoint> cornersClick;
328 cornersClick.push_back(ip);
350 std::vector<vpImagePoint> cornersClick;
356 cornersClick.push_back(ip);
381 precalcValuesPnPoly();
401 precalcValuesPnPoly();
424 double denominator = (di1 * dj2) - (dj1 * di2);
426 if (fabs(denominator) < std::numeric_limits<double>::epsilon()) {
430 double alpha = -(((ip1.
get_i() - ip3.
get_i()) * dj2) + (di2 * (ip3.
get_j() - ip1.
get_j()))) / denominator;
431 if ((alpha < 0) || (alpha >= 1)) {
435 double beta = -((di1 * (ip3.
get_j() - ip1.
get_j())) + (dj1 * (ip1.
get_i() - ip3.
get_i()))) / denominator;
436 if ((beta < 0) || (beta >= 1)) {
465 infPoint.
set_i(infPoint.
get_i() + (1000 * generator()));
466 infPoint.
set_j(infPoint.
get_j() + (1000 * generator()));
468 bool oddNbIntersections =
false;
469 size_t v_corners_size =
_corners.size();
470 for (
size_t i = 0; i < v_corners_size; ++i) {
473 bool intersection =
false;
482 intersection = testIntersectionSegments(ip1, ip2, ip, infPoint);
489 oddNbIntersections = !oddNbIntersections;
494 test = oddNbIntersections;
500 bool oddNodes =
false;
501 size_t v_corners_size =
_corners.size();
502 size_t j = v_corners_size - 1;
503 for (
size_t i = 0; i < v_corners_size; ++i) {
506 oddNodes ^= (ip.
get_v() * m_PnPolyMultiples[i] + m_PnPolyConstants[i] < ip.
get_u());
520 void vpPolygon::precalcValuesPnPoly()
526 m_PnPolyConstants.resize(
_corners.size());
527 m_PnPolyMultiples.resize(
_corners.size());
529 size_t v_corners_size =
_corners.size();
530 size_t j = v_corners_size - 1;
531 for (
size_t i = 0; i < v_corners_size; ++i) {
533 m_PnPolyConstants[i] =
_corners[i].get_u();
534 m_PnPolyMultiples[i] = 0.0;
537 m_PnPolyConstants[i] = (
_corners[i].get_u() -
565 size_t v_corners_size =
_corners.size();
566 for (
size_t i = 0; i < v_corners_size; ++i) {
567 size_t i_p_1 = (i + 1) %
_corners.size();
598 size_t v_corners_size =
_corners.size();
599 for (
size_t i = 0; i < v_corners_size; ++i) {
600 size_t i_p_1 = (i + 1) %
_corners.size();
632 std::set<double> setI;
633 std::set<double> setJ;
634 unsigned int v_corners_size =
static_cast<unsigned int>(
_corners.size());
635 for (
unsigned int i = 0; i < v_corners_size; ++i) {
640 std::set<double>::const_iterator iterI = setI.end();
641 std::set<double>::const_iterator iterJ = setJ.end();
664 for (
size_t i = 0; i < N; ++i) {
692 return (
static_cast<unsigned int>(
_corners.size()));
Generic class defining intrinsic camera parameters.
Class to define RGB colors available for display functionalities.
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
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)
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
@ notImplementedError
Not implemented.
@ divideByZeroError
Division by zero.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static bool equal(double x, double y, double threshold=0.001)
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
Defines a generic 2D polygon.
void display(const vpImage< unsigned char > &I, const vpColor &color, unsigned int thickness=1) const
void init(const std::vector< vpImagePoint > &corners)
vpPolygon & build(const std::vector< vpImagePoint > &corners, const bool &create_convex_hull=false)
vpRect _bbox
Bounding box containing the polygon.
@ PnPolySegmentIntersection
VP_DEPRECATED void buildFrom(const std::vector< vpImagePoint > &corners, const bool create_convex_hull=false)
unsigned int getSize() const
std::vector< vpImagePoint > _corners
Collection of image points containing the corners.
vpPolygon & operator=(const vpPolygon &poly)
double _area
Area of the polygon.
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
void setBottomRight(const vpImagePoint &bottomRight)
void setTopLeft(const vpImagePoint &topLeft)
Class for generating random numbers with uniform probability density.