Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
catchLineFitting.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 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 * Test line fitting.
32 */
33
39#include <visp3/core/vpConfig.h>
40
41#if defined(VISP_HAVE_CATCH2)
42
43#include <visp3/core/vpGaussRand.h>
44#include <visp3/core/vpMath.h>
45
46#include <catch_amalgamated.hpp>
47
48#ifdef ENABLE_VISP_NAMESPACE
49using namespace VISP_NAMESPACE_NAME;
50#endif
51
52namespace
53{
54void convertLineEquation(double A, double B, double C, double &a, double &b)
55{
56 a = -A / B;
57 b = C / B;
58}
59} // namespace
60
61TEST_CASE("Line fitting - Horizontal", "[line_fitting]")
62{
63 std::cout << "\nLine fitting - Horizontal" << std::endl;
64 double a = 0, b = 10;
65 std::vector<vpImagePoint> imPts;
66 for (int i = 0; i < 3; i++) {
67 double x = i * 10;
68 imPts.push_back(vpImagePoint(a * x + b, x));
69 std::cout << "imPts: (" << imPts.back().get_u() << ", " << imPts.back().get_v() << ")" << std::endl;
70 }
71
72 double A = 0, B = 0, C = 0;
73 double error = vpMath::lineFitting(imPts, A, B, C);
74 std::cout << "error: " << error << std::endl;
75 std::cout << "a: " << a << " ; b: " << b << std::endl;
76 std::cout << "A: " << A << " ; B: " << B << " ; C: " << C << std::endl;
77 double a_est = 0, b_est = 0;
78 convertLineEquation(A, B, C, a_est, b_est);
79 std::cout << "-A/B: " << a_est << " ; -C/B: " << b_est << std::endl;
80
81 CHECK(a == Catch::Approx(a_est).margin(1e-6));
82 CHECK(b == Catch::Approx(b_est).epsilon(1e-6));
83}
84
85TEST_CASE("Line fitting", "[line_fitting]")
86{
87 std::cout << "\nLine fitting" << std::endl;
88 double a = -4.68, b = 21.456;
89 std::vector<vpImagePoint> imPts;
90 const int nbPoints = 10;
91 for (int i = 0; i < nbPoints; i++) {
92 double x = i * 10;
93 double y = a * x + b;
94 imPts.push_back(vpImagePoint(y, x));
95 std::cout << "imPts: (" << imPts.back().get_u() << ", " << imPts.back().get_v() << ")" << std::endl;
96 }
97
98 double A = 0, B = 0, C = 0;
99 double error = vpMath::lineFitting(imPts, A, B, C);
100 std::cout << "error: " << error << std::endl;
101 std::cout << "a: " << a << " ; b: " << b << std::endl;
102 std::cout << "A: " << A << " ; B: " << B << " ; C: " << C << std::endl;
103 double a_est = 0, b_est = 0;
104 convertLineEquation(A, B, C, a_est, b_est);
105 std::cout << "-A/B: " << a_est << " ; -C/B: " << b_est << std::endl;
106
107 CHECK(a == Catch::Approx(a_est).epsilon(1e-6));
108 CHECK(b == Catch::Approx(b_est).epsilon(1e-6));
109}
110
111TEST_CASE("Line fitting - Gaussian noise", "[line_fitting]")
112{
113 std::cout << "\nLine fitting - Gaussian noise" << std::endl;
114 const double sigma = 3, mean = 0;
115 vpGaussRand gauss(sigma, mean);
116
117 double a = -4.68, b = 21.456;
118 std::vector<vpImagePoint> imPts;
119 const int nbPoints = 10;
120 for (int i = 0; i < nbPoints; i++) {
121 double x = i * 10;
122 double y = a * x + b;
123 imPts.push_back(vpImagePoint(y + gauss(), x + gauss()));
124 std::cout << "x: " << x << " ; y: " << y << " ; imPts: (" << imPts.back().get_u() << ", " << imPts.back().get_v()
125 << ")" << std::endl;
126 }
127
128 double A = 0, B = 0, C = 0;
129 double error = vpMath::lineFitting(imPts, A, B, C);
130 std::cout << "error: " << error << std::endl;
131 std::cout << "a: " << a << " ; b: " << b << std::endl;
132 std::cout << "A: " << A << " ; B: " << B << " ; C: " << C << std::endl;
133 double a_est = 0, b_est = 0;
134 convertLineEquation(A, B, C, a_est, b_est);
135 std::cout << "-A/B: " << a_est << " ; -C/B: " << b_est << std::endl;
136
137 REQUIRE(error < sigma);
138}
139
140int main(int argc, char *argv[])
141{
142 Catch::Session session;
143 session.applyCommandLine(argc, argv);
144 int numFailed = session.run();
145 return numFailed;
146}
147#else
148#include <iostream>
149
150int main() { return EXIT_SUCCESS; }
151#endif
Class for generating random number with normal probability density.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static double lineFitting(const std::vector< vpImagePoint > &imPts, double &a, double &b, double &c)
Definition vpMath.cpp:411