Visual Servoing Platform  version 3.6.1 under development (2024-10-15)
vpMegaPose.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  * MegaPose wrapper.
33  *
34 *****************************************************************************/
35 
36 #include <visp3/core/vpConfig.h>
37 
38 #if defined(VISP_HAVE_NLOHMANN_JSON) && defined(VISP_HAVE_THREADS)
39 
40 #include <visp3/dnn_tracker/vpMegaPose.h>
41 
42 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
43 #include <arpa/inet.h>
44 #include <netdb.h>
45 #include <netinet/in.h>
46 #include <sys/socket.h>
47 #include <unistd.h>
48 #else
49 #include <io.h>
50 #include <winsock2.h>
51 #include <ws2tcpip.h> // for inet_pton()
52 #endif
53 #include <stdexcept>
54 #include <mutex>
55 #include <thread>
56 using json = nlohmann::json;
57 
58 BEGIN_VISP_NAMESPACE
59 
61 
62 /*Encode elements to a buffer of bytes*/
63 
64 /*End of template recursion*/
65 void encode(std::vector<uint8_t> &)
66 {
67 
68 }
69 
70 /*
71 Append the byte representation of an object to the byte buffer.
72 By default a generic object cannot be encoded.
73 */
74 template<typename T>
75 void encode(std::vector<uint8_t> &buffer, const T &object) = delete;
76 
77 
78 /*Single object specializations*/
79 template<>
80 void encode(std::vector<uint8_t> &buffer, const int &object)
81 {
82  const uint32_t v = htonl(object);
83  const uint8_t *varr = (uint8_t *)&v;
84  buffer.insert(buffer.end(), varr, varr + 4);
85 }
86 
87 template<>
88 void encode(std::vector<uint8_t> &buffer, const float &object)
89 {
90  assert((sizeof(uint32_t) == sizeof(float)));
91  const uint32_t *pointer = reinterpret_cast<const uint32_t *>(&object);
92  const uint32_t v = htonl(*pointer);
93  const uint8_t *varr = (uint8_t *)&v;
94  buffer.insert(buffer.end(), varr, varr + 4);
95 }
96 
97 template<>
98 void encode(std::vector<uint8_t> &buffer, const std::string &object)
99 {
100  const int size = static_cast<int>(object.size());
101  encode(buffer, size);
102  const uint8_t *chars = (uint8_t *)&object[0];
103  buffer.insert(buffer.end(), chars, chars + size);
104 }
105 
106 template<typename T>
107 void encode(std::vector<uint8_t> &buffer, const std::vector<T> &object)
108 {
109  const int size = static_cast<int>(object.size());
110  encode(buffer, size);
111  for (const T &value : object) {
112  encode(buffer, value);
113  }
114 }
115 
116 /*Multiple arguments are processed one by one*/
117 template<typename T, typename ...Rest>
118 void encode(std::vector<uint8_t> &buffer, const T &object, const Rest& ...rest)
119 {
120  encode(buffer, object);
121  encode(buffer, rest...);
122 }
123 
124 template<>
125 void encode(std::vector<uint8_t> &buffer, const vpImage<vpRGBa> &object)
126 {
127  const int height = object.getHeight(), width = object.getWidth();
128  encode(buffer, height, width, 4);
129  const uint32_t sentSize = height * width * 4;
130 
131  buffer.reserve(buffer.size() + sentSize); // Avoid resizing multiple times as we iterate on pixels
132  const uint8_t *const bitmap = (uint8_t *)object.bitmap;
133  buffer.insert(buffer.end(), bitmap, bitmap + sentSize);
134  //std::copy(bitmap, bitmap + sentSize, buffer.end());
135 }
136 
137 template<>
138 void encode(std::vector<uint8_t> &buffer, const vpImage<uint16_t> &object)
139 {
140  const int height = object.getHeight(), width = object.getWidth();
141  encode(buffer, height, width);
142  //test endianness
143  const uint16_t hostTest = 1;
144  const uint16_t netTest = htons(hostTest); // network is big endian
145  const uint8_t endianness = hostTest == netTest ? '>' : '<';
146  const uint32_t sentSize = height * width * 2;
147 
148  buffer.reserve(buffer.size() + sentSize + 1);
149  buffer.push_back(endianness);
150  const uint8_t *const bitmap = (uint8_t *)object.bitmap;
151  buffer.insert(buffer.end(), bitmap, bitmap + sentSize);
152 }
153 
154 template<>
155 void encode(std::vector<uint8_t> &buffer, const vpCameraParameters &object)
156 {
157  encode(buffer, (float)object.get_px(), (float)object.get_py(),
158  (float)object.get_u0(), (float)object.get_v0());
159 }
160 
161 template<>
162 void encode(std::vector<uint8_t> &buffer, const vpHomogeneousMatrix &object)
163 {
164  std::vector<float> array;
165  array.reserve(16);
166  const double *const data = object.data;
167  for (unsigned i = 0; i < 16; ++i) {
168  array.push_back((float)data[i]);
169  }
170  encode(buffer, array);
171 }
172 
173 /*Decode elements (passed as references), given a buffer of bytes and an index (modified)*/
174 
175 void decode(const std::vector<uint8_t> &, unsigned int &)
176 { }
177 
178 /*
179  Modify an object, given a byte array and an index reading into the byte array.
180  The byte array is not modified. But the index should be modified once the object is read.
181  After calling this function, the index should indicate the position of the next object to be read.
182 
183  There is no default decoding behaviour. As such, specializations must be written.
184 */
185 template<typename T>
186 void decode(const std::vector<uint8_t> &buffer, unsigned int &index, T &t) = delete;
187 
188 template<>
189 void decode(const std::vector<uint8_t> &buffer, unsigned int &index, int &value)
190 {
191  const uint8_t *ptr = &buffer[index];
192  value = ntohl(*((uint32_t *)ptr)); // Convert from network (big endian) representation to this machine's representation.
193  index += sizeof(int);
194 }
195 template<>
196 void decode(const std::vector<uint8_t> &buffer, unsigned int &index, float &value)
197 {
198  const uint8_t *ptr = &buffer[index];
199  const uint32_t v = ntohl(*((uint32_t *)ptr));
200  memcpy(&value, &v, sizeof(uint32_t));
201  index += sizeof(float);
202 }
203 template<>
204 void decode(const std::vector<uint8_t> &buffer, unsigned int &index, std::string &value)
205 {
206  int size;
207  decode(buffer, index, size);
208  value.resize(size);
209  value.replace(0, size, (char *)&buffer[index], size);
210  index += size;
211 }
212 
213 template<typename T>
214 void decode(const std::vector<uint8_t> &buffer, unsigned int &index, std::vector<T> &value)
215 {
216  int size;
217  decode(buffer, index, size);
218  value.resize(size);
219  for (int i = 0; i < size; ++i) {
220  T t;
221  decode(buffer, index, t);
222  value[i] = t;
223  }
224 }
225 
226 template<>
227 void decode(const std::vector<uint8_t> &buffer, unsigned int &index, vpHomogeneousMatrix &value)
228 {
229  std::vector<float> values;
230  decode(buffer, index, values);
231  assert(values.size() == 16);
232  for (int i = 0; i < 16; ++i) {
233  value.data[i] = values[i];
234  }
235 }
236 
237 /*
238  Decode multiple objects from a byte array.
239  These objects can have different types. They are read from the buffer in the order that they are given to the function.
240 */
241 template<typename T, typename ...Rest>
242 void decode(const std::vector<uint8_t> &buffer, unsigned int &index, T &object, Rest& ...rest)
243 {
244  decode(buffer, index, object);
245  decode(buffer, index, rest...);
246 }
247 
248 template<>
249 void decode(const std::vector<uint8_t> &buffer, unsigned int &index, vpImage<vpRGBa> &value)
250 {
251  int height, width, channels;
252  decode(buffer, index, height, width, channels);
253  value.resize(height, width);
254  if (channels == 3) {
255  for (int i = 0; i < height; ++i) {
256  for (int j = 0; j < width; ++j) {
257  value.bitmap[i * width + j] = vpRGBa(buffer[index], buffer[index + 1], buffer[index + 2], 255);
258  index += 3;
259  }
260  }
261  }
262  else if (channels == 4) { // Despite having 4 channels, this is faster
263  const unsigned copySize = height * width * channels;
264  memcpy((uint8_t *)value.bitmap, &buffer[index], copySize);
265  index += copySize;
266  }
267 }
268 
269 
270 #define MEGAPOSE_CODE_SIZE 4
271 void handleWrongReturnMessage(const vpMegaPose::ServerMessage code, std::vector<uint8_t> &buffer)
272 {
273  if (code != vpMegaPose::ServerMessage::ERR) {
274  throw vpException(vpException::fatalError, "MegaPose: got an unexpected message from the server: " + std::to_string(code));
275  }
276  std::string message;
277  unsigned index = 0;
278  decode(buffer, index, message);
279  throw vpException(vpException::badValue, "Server error : " + message);
280 }
281 
282 const std::unordered_map<vpMegaPose::ServerMessage, std::string> vpMegaPose::m_codeMap =
283 {
284  {ServerMessage::ERR, "RERR"},
285  {ServerMessage::OK, "OKOK"},
286  {ServerMessage::GET_POSE, "GETP"},
287  {ServerMessage::RET_POSE, "RETP"},
288  {ServerMessage::SET_INTR, "INTR"},
289  {ServerMessage::GET_VIZ, "GETV"},
290  {ServerMessage::RET_VIZ, "RETV"},
291  {ServerMessage::GET_SCORE, "GSCO"},
292  {ServerMessage::RET_SCORE, "RSCO"},
293  {ServerMessage::SET_SO3_GRID_SIZE, "SO3G"},
294  {ServerMessage::GET_LIST_OBJECTS, "GLSO"},
295  {ServerMessage::RET_LIST_OBJECTS, "RLSO"},
296  {ServerMessage::EXIT, "EXIT"},
297 };
298 
299 std::string vpMegaPose::messageToString(const vpMegaPose::ServerMessage messageType)
300 {
301  return m_codeMap.at(messageType);
302 }
303 
304 vpMegaPose::ServerMessage vpMegaPose::stringToMessage(const std::string &s)
305 {
306  for (auto it : m_codeMap) {
307  if (it.second == s) {
308  return it.first;
309  }
310  }
311  return UNKNOWN;
312 }
313 
314 void vpMegaPose::makeMessage(const vpMegaPose::ServerMessage messageType, std::vector<uint8_t> &data) const
315 {
316  const uint32_t size = htonl(static_cast<uint32_t>(data.size()));
317  const std::string code = messageToString(messageType);
318  uint8_t arr[sizeof(size) + MEGAPOSE_CODE_SIZE];
319  memcpy(arr, (uint8_t *)&size, sizeof(size));
320 
321  memcpy(arr + sizeof(size), (uint8_t *)code.c_str(), MEGAPOSE_CODE_SIZE);
322 
323  std::vector<uint8_t> header(arr, arr + sizeof(size) + MEGAPOSE_CODE_SIZE);
324  data.insert(data.begin(), header.begin(), header.end());
325 }
326 
327 std::pair<vpMegaPose::ServerMessage, std::vector<uint8_t>> vpMegaPose::readMessage() const
328 {
329  uint32_t size;
330 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
331  size_t readCount = read(m_serverSocket, &size, sizeof(uint32_t));
332 #else
333  size_t readCount = recv(m_serverSocket, reinterpret_cast<char *>(&size), sizeof(uint32_t), 0);
334 #endif
335  if (readCount != sizeof(uint32_t)) {
336  throw vpException(vpException::ioError, "MegaPose: Error while reading data from socket");
337  }
338  size = ntohl(size);
339 
340  unsigned char code[MEGAPOSE_CODE_SIZE];
341 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
342  readCount = read(m_serverSocket, code, MEGAPOSE_CODE_SIZE);
343 #else
344  readCount = recv(m_serverSocket, reinterpret_cast<char *>(code), MEGAPOSE_CODE_SIZE, 0);
345 #endif
346  if (readCount != MEGAPOSE_CODE_SIZE) {
347  throw vpException(vpException::ioError, "MegaPose: Error while reading data from socket");
348  }
349 
350  std::vector<uint8_t> data;
351  data.resize(size);
352  unsigned read_size = 4096;
353  unsigned read_total = 0;
354  while (read_total < size) {
355 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
356  int actually_read = read(m_serverSocket, &data[read_total], read_size);
357 #else
358  int actually_read = recv(m_serverSocket, reinterpret_cast<char *>(&data[read_total]), read_size, 0);
359 #endif
360  if (actually_read <= 0) {
361  throw vpException(vpException::ioError, "MegaPose: Error while reading data from socket");
362  }
363  read_total += actually_read;
364  }
365  std::string codeStr(code, code + MEGAPOSE_CODE_SIZE);
366  vpMegaPose::ServerMessage c = stringToMessage(codeStr);
367  return std::make_pair(c, data);
368 }
369 
370 vpMegaPose::vpMegaPose(const std::string &host, int port, const vpCameraParameters &cam, unsigned height, unsigned width)
371 {
372 #if defined(_WIN32)
373  WSADATA WSAData;
374  if (WSAStartup(MAKEWORD(2, 0), &WSAData) != 0) {
375  throw vpException(vpException::ioError, "Could not perform WSAStartup");
376  }
377 #endif
378  struct sockaddr_in serv_addr;
379 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
380  if ((m_serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
381 #else
382  if ((m_serverSocket = static_cast<int>(socket(AF_INET, SOCK_STREAM, 0))) < 0) {
383 #endif
384  throw vpException(vpException::ioError, "Could not create socket to connect to MegaPose server");
385  }
386  serv_addr.sin_family = AF_INET;
387  serv_addr.sin_port = htons(port);
388  // Convert string to a binary address representation
389  if (inet_pton(AF_INET, host.c_str(), &serv_addr.sin_addr) <= 0) {
390  throw vpException(vpException::badValue, "Invalid ip address: " + host);
391  }
392  //Initiate connection
393  if ((m_fd = connect(m_serverSocket, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) < 0) {
394  throw vpException(vpException::ioError, "Could not connect to server at " + host + ":" + std::to_string(port));
395  }
396  setIntrinsics(cam, height, width);
397 }
398 
400 {
401  std::vector<uint8_t> data;
402  makeMessage(ServerMessage::EXIT, data);
403  send(m_serverSocket, reinterpret_cast<const char *>(data.data()), static_cast<int>(data.size()), 0);
404 
405 #if defined(_WIN32)
406  WSACleanup();
407 #else
408  close(m_fd);
409 #endif
410 }
411 
412 std::vector<vpMegaPoseEstimate>
413 vpMegaPose::estimatePoses(const vpImage<vpRGBa>&image, const std::vector<std::string>&labels,
414  const vpImage<uint16_t>*const depth, const double depth_to_m,
415  const std::vector<vpRect>*const detections, const std::vector<vpHomogeneousMatrix>*const initial_cTos,
416  int refinerIterations)
417 {
418  const std::lock_guard<std::mutex> lock(m_mutex);
419  std::vector<uint8_t> data;
420  encode(data, image);
421  json parametersJson;
422  parametersJson["labels"] = labels;
423 
424  if (detections == nullptr && initial_cTos == nullptr) {
425  throw vpException(vpException::badValue, "You must either provide detections (bounding boxes) or initial pose estimates for MegaPose to work.");
426  }
427 
428  if (detections != nullptr) {
429  if (detections->size() != labels.size()) {
430  throw vpException(vpException::badValue, "Same number of bounding boxes and labels must be provided.");
431  }
432  json detectionsJson = json::array();
433  for (const vpRect &bb : *detections) {
434  json j;
435  to_megapose_json(j, bb);
436  detectionsJson.push_back(j);
437  }
438  parametersJson["detections"] = detectionsJson;
439  }
440 
441  if (initial_cTos != nullptr) {
442  if (initial_cTos->size() != labels.size()) {
443  throw vpException(vpException::badValue, "An initial estimate should be given for each detected object in the image");
444  }
445  json cToJson = json::array();
446  for (const vpHomogeneousMatrix &cTo : *initial_cTos) {
447  json j;
448  to_megapose_json(j, cTo);
449  cToJson.push_back(j);
450  }
451  parametersJson["initial_cTos"] = cToJson;
452  }
453  if (refinerIterations >= 0) {
454  parametersJson["refiner_iterations"] = refinerIterations;
455  }
456  if (depth != nullptr) {
457  if (depth_to_m <= 0.0) {
458  throw vpException(vpException::badValue, "When using depth, the scale factor should be specified.");
459  }
460  parametersJson["use_depth"] = true;
461  parametersJson["depth_scale_to_m"] = depth_to_m;
462  }
463  else {
464  parametersJson["use_depth"] = false;
465  }
466  encode(data, parametersJson.dump());
467  if (depth != nullptr) {
468  encode(data, *depth);
469  }
470  makeMessage(ServerMessage::GET_POSE, data);
471  send(m_serverSocket, reinterpret_cast<const char *>(data.data()), static_cast<int>(data.size()), 0);
472  //std::cout<< "Encoding time = " << (vpTime::measureTimeMs() - beforeEncoding) << std::endl;
473 
474  ServerMessage code;
475  std::vector<uint8_t> data_result;
476  std::tie(code, data_result) = readMessage();
477 
478  unsigned int index = 0;
479  if (code != ServerMessage::RET_POSE) {
480  handleWrongReturnMessage(code, data_result);
481  }
482  std::string jsonStr;
483  decode(data_result, index, jsonStr);
484  json jsonValue = json::parse(jsonStr);
485  std::vector<vpMegaPoseEstimate> result = jsonValue;
486  return result;
487 }
488 
489 std::vector<double> vpMegaPose::scorePoses(const vpImage<vpRGBa>&image,
490  const std::vector<std::string>&labels, const std::vector<vpHomogeneousMatrix>&cTos)
491 {
492  const std::lock_guard<std::mutex> lock(m_mutex);
493  std::vector<uint8_t> data;
494  if (cTos.size() != labels.size()) {
495  throw vpException(vpException::generalExceptionEnum::badValue, "The number of poses should be the same as the number of object labels");
496  }
497  encode(data, image);
498  json parametersJson;
499  json cToJson = json::array();
500  for (const vpHomogeneousMatrix &cTo : cTos) {
501  json j;
502  to_megapose_json(j, cTo);
503  cToJson.push_back(j);
504  }
505  parametersJson["cTos"] = cToJson;
506  parametersJson["labels"] = labels;
507 
508  encode(data, parametersJson.dump());
509  makeMessage(ServerMessage::GET_SCORE, data);
510  send(m_serverSocket, reinterpret_cast<const char *>(data.data()), static_cast<int>(data.size()), 0);
511 
512  ServerMessage code;
513  std::vector<uint8_t> data_result;
514  std::tie(code, data_result) = readMessage();
515 
516  if (code != ServerMessage::RET_SCORE) {
517  handleWrongReturnMessage(code, data_result);
518  }
519  unsigned int index = 0;
520  std::string jsonStr;
521  decode(data_result, index, jsonStr);
522  json jsonValue = json::parse(jsonStr);
523  std::vector<double> result = jsonValue;
524  return result;
525 }
526 
527 
528 void vpMegaPose::setIntrinsics(const vpCameraParameters& cam, unsigned height, unsigned width)
529 {
530  const std::lock_guard<std::mutex> lock(m_mutex);
531  std::vector<uint8_t> data;
532 
533  json message;
534  message["px"] = cam.get_px();
535  message["py"] = cam.get_py();
536  message["u0"] = cam.get_u0();
537  message["v0"] = cam.get_v0();
538  message["h"] = height;
539  message["w"] = width;
540 
541  encode(data, message.dump());
542  makeMessage(ServerMessage::SET_INTR, data);
543 
544  send(m_serverSocket, reinterpret_cast<const char *>(data.data()), static_cast<int>(data.size()), 0);
545  ServerMessage code;
546  std::vector<uint8_t> data_result;
547  std::tie(code, data_result) = readMessage();
548  if (code != ServerMessage::OK) {
549  handleWrongReturnMessage(code, data_result);
550  }
551 }
552 
553 vpImage<vpRGBa> vpMegaPose::viewObjects(const std::vector<std::string>&objectNames,
554  const std::vector<vpHomogeneousMatrix>&poses, const std::string& viewType)
555 {
556  const std::lock_guard<std::mutex> lock(m_mutex);
557  std::vector<uint8_t> data;
558  json j;
559  j["labels"] = objectNames;
560  json cToJson = json::array();
561  for (const vpHomogeneousMatrix &cTo : poses) {
562  json j;
563  to_megapose_json(j, cTo);
564  cToJson.push_back(j);
565  }
566  j["poses"] = cToJson;
567  j["type"] = viewType;
568  encode(data, j.dump());
569  makeMessage(ServerMessage::GET_VIZ, data);
570  send(m_serverSocket, reinterpret_cast<const char *>(data.data()), static_cast<int>(data.size()), 0);
571  ServerMessage code;
572  std::vector<uint8_t> data_result;
573  std::tie(code, data_result) = readMessage();
574 
575  if (code != ServerMessage::RET_VIZ) {
576  handleWrongReturnMessage(code, data_result);
577  }
578  vpImage<vpRGBa> result;
579  unsigned int index = 0;
580  decode(data_result, index, result);
581  return result;
582 }
583 
584 void vpMegaPose::setCoarseNumSamples(const unsigned num)
585 {
586  const std::lock_guard<std::mutex> lock(m_mutex);
587  std::vector<uint8_t> data;
588  json j;
589  j["so3_grid_size"] = num;
590  encode(data, j.dump());
591  makeMessage(ServerMessage::SET_SO3_GRID_SIZE, data);
592  send(m_serverSocket, reinterpret_cast<const char *>(data.data()), static_cast<int>(data.size()), 0);
593  ServerMessage code;
594  std::vector<uint8_t> data_result;
595  std::tie(code, data_result) = readMessage();
596  if (code != ServerMessage::OK) {
597  handleWrongReturnMessage(code, data_result);
598  }
599 }
600 
601 std::vector<std::string> vpMegaPose::getObjectNames()
602 {
603  const std::lock_guard<std::mutex> lock(m_mutex);
604  std::vector<uint8_t> data;
605  makeMessage(ServerMessage::GET_LIST_OBJECTS, data);
606  send(m_serverSocket, reinterpret_cast<const char *>(data.data()), static_cast<int>(data.size()), 0);
607  ServerMessage code;
608  std::vector<uint8_t> data_result;
609  std::tie(code, data_result) = readMessage();
610  if (code != ServerMessage::RET_LIST_OBJECTS) {
611  handleWrongReturnMessage(code, data_result);
612  }
613  unsigned int index = 0;
614  std::string jsonStr;
615  decode(data_result, index, jsonStr);
616  json jsonValue = json::parse(jsonStr);
617  std::vector<std::string> result = jsonValue;
618  return result;
619 }
620 END_VISP_NAMESPACE
621 #else
622 
623 // Work around to avoid libvisp_dnn_tracker library empty when threads are not used
624 class VISP_EXPORT dummy_vpMegaPose
625 {
626 public:
627  dummy_vpMegaPose() { };
628 };
629 
630 #if !defined(VISP_BUILD_SHARED_LIBS)
631 // Work around to avoid warning: libvisp_dnn_tracker.a(vpMegaPose.cpp.o) has no symbols
632 void dummy_vpMegaPose_fct() { };
633 #endif
634 
635 #endif
Type * data
Address of the first element of the data array.
Definition: vpArray2D.h:148
Generic class defining intrinsic camera parameters.
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
@ fatalError
Fatal error.
Definition: vpException.h:72
Implementation of an homogeneous matrix and operations on such kind of matrices.
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:542
Type * bitmap
points toward the bitmap
Definition: vpImage.h:135
void setIntrinsics(const vpCameraParameters &cam, unsigned height, unsigned width)
Definition: vpMegaPose.cpp:528
vpImage< vpRGBa > viewObjects(const std::vector< std::string > &objectNames, const std::vector< vpHomogeneousMatrix > &poses, const std::string &viewType)
Definition: vpMegaPose.cpp:553
std::vector< vpMegaPoseEstimate > estimatePoses(const vpImage< vpRGBa > &image, const std::vector< std::string > &objectNames, const vpImage< uint16_t > *const depth=nullptr, const double depthToM=0.f, const std::vector< vpRect > *const detections=nullptr, const std::vector< vpHomogeneousMatrix > *const initial_cTos=nullptr, int refinerIterations=-1)
Definition: vpMegaPose.cpp:413
std::vector< std::string > getObjectNames()
Query the server to find the name of all of the objects it knows.
Definition: vpMegaPose.cpp:601
void setCoarseNumSamples(const unsigned num)
Definition: vpMegaPose.cpp:584
std::vector< double > scorePoses(const vpImage< vpRGBa > &image, const std::vector< std::string > &objectNames, const std::vector< vpHomogeneousMatrix > &cTos)
Definition: vpMegaPose.cpp:489
vpMegaPose(const std::string &host, int port, const vpCameraParameters &cam, unsigned height, unsigned width)
Definition: vpMegaPose.cpp:370
Definition: vpRGBa.h:65
Defines a rectangle in the plane.
Definition: vpRect.h:79