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