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