Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpRBInitializationHelper.cpp
1#include <visp3/rbt/vpRBInitializationHelper.h>
2#include <visp3/rbt/vpRBTracker.h>
3
4#include <visp3/vision/vpPose.h>
5#include <visp3/core/vpDisplay.h>
6#include <visp3/core/vpImage.h>
7#include <visp3/io/vpImageIo.h>
8#include <visp3/core/vpIoTools.h>
9
10#ifdef VISP_HAVE_MODULE_GUI
11#include <visp3/gui/vpDisplayFactory.h>
12#endif
13
15
21{
22 char c;
23
24 fileId.get(c);
25 while (!fileId.fail() && ((c == '#') || (c == '\n') || (c == '\r'))) {
26 if (c == '#') {
27 fileId.ignore(std::numeric_limits<std::streamsize>::max(), fileId.widen('\n'));
28 }
29 fileId.get(c);
30 }
31 if (fileId.fail()) {
32 throw(vpException(vpException::ioError, "Reached end of file"));
33 }
34 fileId.unget();
35}
36
37void vpRBInitializationHelper::savePose(const std::string &filename) const
38{
39 vpPoseVector init_pos;
40 std::fstream finitpos;
41 finitpos.open(filename.c_str(), std::ios::out);
42
43 init_pos.buildFrom(m_cMo);
44 finitpos << init_pos;
45 finitpos.close();
46}
47
48#ifdef VISP_HAVE_MODULE_GUI
49
50template <typename T>
51void vpRBInitializationHelper::initClick(const vpImage<T> &I, const std::string &initFile, bool displayHelp, vpRBTracker &tracker)
52{
53 std::cout << "Starting init click!" << std::endl;
54 vpHomogeneousMatrix last_cMo;
55 vpPoseVector init_pos;
56 vpImagePoint ip;
58
59 std::string ext = ".init";
60 std::string str_pose = "";
61 size_t pos = initFile.rfind(ext);
62
63 // Load the last poses from files
64 std::fstream finitpos;
65 std::ifstream finit;
66 std::stringstream ss;
67 std::string poseSavingFilename;
68 if (poseSavingFilename.empty()) {
69 if (pos != std::string::npos)
70 str_pose = initFile.substr(0, pos) + ".0.pos";
71 else
72 str_pose = initFile + ".0.pos";
73
74 finitpos.open(str_pose.c_str(), std::ios::in);
75 ss << str_pose;
76 }
77 else {
78 finitpos.open(poseSavingFilename.c_str(), std::ios::in);
79 ss << poseSavingFilename;
80 }
81 if (finitpos.fail()) {
82 std::cout << "Cannot read " << ss.str() << std::endl << "cMo set to identity" << std::endl;
83 last_cMo.eye();
84 }
85 else {
86 for (unsigned int i = 0; i < 6; i += 1) {
87 finitpos >> init_pos[i];
88 }
89
90 finitpos.close();
91 last_cMo.buildFrom(init_pos);
92
93 std::cout << "Tracker initial pose read from " << ss.str() << ": " << std::endl << last_cMo << std::endl;
94
96 vpDisplay::displayFrame(I, last_cMo, m_cam, 0.05, vpColor::green);
98
99
100 std::cout << "No modification : left click " << std::endl;
101 std::cout << "Modify initial pose : right click " << std::endl;
102
103
104 vpDisplay::displayText(I, 15, 10, "left click to validate, right click to modify initial pose", vpColor::red);
105
107
108 while (!vpDisplay::getClick(I, ip, button)) {
109 vpTime::sleepMs(10);
110 }
111 }
112
113 if (!finitpos.fail() && button == vpMouseButton::button1) {
114 m_cMo = last_cMo;
115 }
116 else {
117 vpDisplay *d_help = nullptr;
118
121
122 vpPose pose;
123
124 pose.clearPoint();
125
126 // Clear string stream that previously contained the path to the "object.0.pos" file.
127 ss.str(std::string());
128
129 // file parser
130 // number of points
131 // X Y Z
132 // X Y Z
133 if (pos != std::string::npos) {
134 ss << initFile;
135 }
136 else {
137 ss << initFile;
138 ss << ".init";
139 }
140
141 std::cout << "Load 3D points from: " << ss.str() << std::endl;
142#if (VISP_CXX_STANDARD > VISP_CXX_STANDARD_98)
143 finit.open(ss.str());
144#else
145 finit.open(ss.str().c_str());
146#endif
147 if (finit.fail()) {
148 std::cout << "Cannot read " << ss.str() << std::endl;
149 throw vpException(vpException::ioError, "Cannot open model-based tracker init file %s", ss.str().c_str());
150 }
151
152#ifdef VISP_HAVE_MODULE_IO
153 // Display window creation and initialisation
154 try {
155 if (displayHelp) {
156 const std::string imgExtVec[] = { ".ppm", ".pgm", ".jpg", ".jpeg", ".png" };
157 std::string dispF;
158 bool foundHelpImg = false;
159 if (pos != std::string::npos) {
160 for (size_t i = 0; i < 5 && !foundHelpImg; i++) {
161 dispF = initFile.substr(0, pos) + imgExtVec[i];
162 foundHelpImg = vpIoTools::checkFilename(dispF);
163 }
164 }
165 else {
166 for (size_t i = 0; i < 5 && !foundHelpImg; i++) {
167 dispF = initFile + imgExtVec[i];
168 foundHelpImg = vpIoTools::checkFilename(dispF);
169 }
170 }
171
172 if (foundHelpImg) {
173 std::cout << "Load image to help initialization: " << dispF << std::endl;
174
176
177 vpImage<vpRGBa> Iref;
178 vpImageIo::read(Iref, dispF);
179#if defined(VISP_HAVE_DISPLAY)
180 const int winXPos = I.display->getWindowXPosition();
181 const int winYPos = I.display->getWindowYPosition();
182 unsigned int width = I.getWidth();
183 d_help->init(Iref, winXPos +static_cast<int>(width) + 80, winYPos, "Where to initialize...");
184 vpDisplay::display(Iref);
185 vpDisplay::flush(Iref);
186#endif
187 }
188 }
189 }
190 catch (...) {
191 if (d_help != nullptr) {
192 delete d_help;
193 d_help = nullptr;
194 }
195 }
196#else //#ifdef VISP_HAVE_MODULE_IO
197 (void)(displayHelp);
198#endif //#ifdef VISP_HAVE_MODULE_IO
199 // skip lines starting with # as comment
201
202 unsigned int n3d;
203 finit >> n3d;
204 finit.ignore(256, '\n'); // skip the rest of the line
205 std::cout << "Number of 3D points " << n3d << std::endl;
206 if (n3d > 100000) {
207 throw vpException(vpException::badValue, "In %s file, the number of 3D points exceed the max allowed",
208 ss.str().c_str());
209 }
210
211 std::vector<vpPoint> P(n3d);
212 for (unsigned int i = 0; i < n3d; i++) {
213 // skip lines starting with # as comment
215
216 vpColVector pt_3d(4, 1.0);
217 finit >> pt_3d[0];
218 finit >> pt_3d[1];
219 finit >> pt_3d[2];
220 finit.ignore(256, '\n'); // skip the rest of the line
221
222 vpColVector pt_3d_tf = pt_3d;
223 std::cout << "Point " << i + 1 << " with 3D coordinates: " << pt_3d_tf[0] << " " << pt_3d_tf[1] << " "
224 << pt_3d_tf[2] << std::endl;
225
226 P[i].setWorldCoordinates(pt_3d_tf[0], pt_3d_tf[1], pt_3d_tf[2]); // (X,Y,Z)
227 }
228
229 finit.close();
230
231 bool isWellInit = false;
232 while (!isWellInit) {
233 std::vector<vpImagePoint> mem_ip;
234 for (unsigned int i = 0; i < n3d; i++) {
235 std::ostringstream text;
236 text << "Click on point " << i + 1;
237
239 vpDisplay::displayText(I, 15, 10, text.str(), vpColor::red);
240 for (unsigned int k = 0; k < mem_ip.size(); k++) {
241 vpDisplay::displayCross(I, mem_ip[k], 10, vpColor::green, 2);
242 }
244
245 std::cout << "Click on point " << i + 1 << " ";
246 double x = 0, y = 0;
247
248 vpDisplay::getClick(I, ip);
249 mem_ip.push_back(ip);
251
253 P[i].set_x(x);
254 P[i].set_y(y);
255
256 std::cout << "with 2D coordinates: " << ip << std::endl;
257
258 pose.addPoint(P[i]); // and added to the pose computation point list
259 }
262
263 std::cout << "Before optim: " << m_cam << std::endl;
265 std::cout << "Pose computation from points failed!" << std::endl;
266 for (unsigned int i = 0; i < n3d; ++i) {
267 std::cout << "Point " << i << ": " << std::endl;
268 std::cout << " 3D: " << pose.getPoints()[i].get_oP().t() << std::endl;
269 std::cout << "2D: " << pose.getPoints()[i].get_x() << ", " << pose.getPoints()[i].get_y() << std::endl;
270 }
271 }
272
273 vpRBFeatureTrackerInput frame;
274 tracker.updateRender(frame, m_cMo);
275 tracker.displaySilhouette(I, frame);
276
277 vpDisplay::displayText(I, 15, 10, "left click to validate, right click to re initialize object", vpColor::red);
278
280
281 button = vpMouseButton::button1;
282 while (!vpDisplay::getClick(I, ip, button)) {
283 }
284
285 if (button == vpMouseButton::button1) {
286 isWellInit = true;
287 }
288 else {
289 pose.clearPoint();
292 }
293
294 }
295 vpDisplay::displayFrame(I, m_cMo, m_cam, 0.05, vpColor::red);
296
297 // save the pose into file
298 if (poseSavingFilename.empty())
299 savePose(str_pose);
300 else
301 savePose(poseSavingFilename);
302
303 if (d_help != nullptr) {
304 delete d_help;
305 d_help = nullptr;
306 }
307 }
308
309}
310template VISP_EXPORT void vpRBInitializationHelper::initClick<unsigned char>(const vpImage<unsigned char> &I, const std::string &initFile, bool displayHelp, vpRBTracker &tracker);
311template VISP_EXPORT void vpRBInitializationHelper::initClick<vpRGBa>(const vpImage<vpRGBa> &I, const std::string &initFile, bool displayHelp, vpRBTracker &tracker);
312#endif
313
314END_VISP_NAMESPACE
static const vpColor red
Definition vpColor.h:198
static const vpColor green
Definition vpColor.h:201
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
int getWindowXPosition() const
Definition vpDisplay.h:234
static void displayFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color=vpColor::none, unsigned int thickness=1, const vpImagePoint &offset=vpImagePoint(0, 0), const std::string &frameName="", const vpColor &textColor=vpColor::black, const vpImagePoint &textOffset=vpImagePoint(15, 15))
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
int getWindowYPosition() const
Definition vpDisplay.h:239
static void flush(const vpImage< unsigned char > &I)
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
@ ioError
I/O error.
Definition vpException.h:67
@ badValue
Used to indicate that a value is not in the allowed range.
Definition vpException.h:73
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix & buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
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
unsigned int getWidth() const
Definition vpImage.h:242
vpDisplay * display
Definition vpImage.h:136
static bool checkFilename(const std::string &filename)
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
Implementation of a pose vector and operations on poses.
vpPoseVector & buildFrom(const double &tx, const double &ty, const double &tz, const double &tux, const double &tuy, const double &tuz)
std::vector< vpPoint > getPoints() const
Definition vpPose.h:507
void addPoint(const vpPoint &P)
Definition vpPose.cpp:96
@ DEMENTHON_LAGRANGE_VIRTUAL_VS
Definition vpPose.h:103
bool computePose(vpPoseMethodType method, vpHomogeneousMatrix &cMo, FuncCheckValidityPose func=nullptr)
Definition vpPose.cpp:385
void clearPoint()
Definition vpPose.cpp:89
void removeCommentsAndEmptyLines(std::ifstream &fileId)
void savePose(const std::string &filename) const
Class implementing the Render-Based Tracker (RBT).
Definition vpRBTracker.h:87
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.
VISP_EXPORT void sleepMs(double t)