PyDetector.cpp
Go to the documentation of this file.
1 
5 #include "PyDetector.h"
9 #include <rtabmap/utilite/UStl.h>
11 #include <rtabmap/utilite/UTimer.h>
12 
13 #include <pybind11/embed.h>
14 
15 #define NPY_NO_DEPRECATED_API NPY_API_VERSION
16 #include <numpy/arrayobject.h>
17 
18 namespace rtabmap
19 {
20 
22  pModule_(0),
23  pFunc_(0),
24  path_(Parameters::defaultPyDetectorPath()),
25  cuda_(Parameters::defaultPyDetectorCuda())
26 {
27  this->parseParameters(parameters);
28 
29  UDEBUG("path = %s", path_.c_str());
31  {
32  UERROR("Cannot initialize Python detector, the path is not valid: \"%s\"=\"%s\"",
33  Parameters::kPyDetectorPath().c_str(), path_.c_str());
34  return;
35  }
36 
37  pybind11::gil_scoped_acquire acquire;
38 
39  std::string matcherPythonDir = UDirectory::getDir(path_);
40  if(!matcherPythonDir.empty())
41  {
42  PyRun_SimpleString("import sys");
43  PyRun_SimpleString(uFormat("sys.path.append(\"%s\")", matcherPythonDir.c_str()).c_str());
44  }
45 
46  _import_array();
47 
48  std::string scriptName = uSplit(UFile::getName(path_), '.').front();
49  PyObject * pName = PyUnicode_FromString(scriptName.c_str());
50  UDEBUG("PyImport_Import() beg");
51  pModule_ = PyImport_Import(pName);
52  UDEBUG("PyImport_Import() end");
53 
54  Py_DECREF(pName);
55 
56  if(!pModule_)
57  {
58  UERROR("Module \"%s\" could not be imported! (File=\"%s\")", scriptName.c_str(), path_.c_str());
59  UERROR("%s", getPythonTraceback().c_str());
60  }
61 }
62 
64 {
65  pybind11::gil_scoped_acquire acquire;
66 
67  if(pFunc_)
68  {
69  Py_DECREF(pFunc_);
70  }
71  if(pModule_)
72  {
73  Py_DECREF(pModule_);
74  }
75 }
76 
78 {
79  Feature2D::parseParameters(parameters);
80 
81  Parameters::parse(parameters, Parameters::kPyDetectorPath(), path_);
82  Parameters::parse(parameters, Parameters::kPyDetectorCuda(), cuda_);
83 
85 }
86 
87 std::vector<cv::KeyPoint> PyDetector::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask)
88 {
89  UDEBUG("");
90  descriptors_ = cv::Mat();
91  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
92  std::vector<cv::KeyPoint> keypoints;
93  cv::Mat imgRoi(image, roi);
94 
95  UTimer timer;
96 
97  if(!pModule_)
98  {
99  UERROR("Python detector module not loaded!");
100  return keypoints;
101  }
102 
103  pybind11::gil_scoped_acquire acquire;
104 
105  if(!pFunc_)
106  {
107  PyObject * pFunc = PyObject_GetAttrString(pModule_, "init");
108  if(pFunc)
109  {
110  if(PyCallable_Check(pFunc))
111  {
112  PyObject * result = PyObject_CallFunction(pFunc, "i", cuda_?1:0);
113 
114  if(result == NULL)
115  {
116  UERROR("Call to \"init(...)\" in \"%s\" failed!", path_.c_str());
117  UERROR("%s", getPythonTraceback().c_str());
118  return keypoints;
119  }
120  Py_DECREF(result);
121 
122  pFunc_ = PyObject_GetAttrString(pModule_, "detect");
123  if(pFunc_ && PyCallable_Check(pFunc_))
124  {
125  // we are ready!
126  }
127  else
128  {
129  UERROR("Cannot find method \"detect(...)\" in %s", path_.c_str());
130  UERROR("%s", getPythonTraceback().c_str());
131  if(pFunc_)
132  {
133  Py_DECREF(pFunc_);
134  pFunc_ = 0;
135  }
136  return keypoints;
137  }
138  }
139  else
140  {
141  UERROR("Cannot call method \"init(...)\" in %s", path_.c_str());
142  UERROR("%s", getPythonTraceback().c_str());
143  return keypoints;
144  }
145  Py_DECREF(pFunc);
146  }
147  else
148  {
149  UERROR("Cannot find method \"init(...)\"");
150  UERROR("%s", getPythonTraceback().c_str());
151  return keypoints;
152  }
153  UDEBUG("init time = %fs", timer.ticks());
154  }
155 
156  if(pFunc_)
157  {
158  npy_intp dims[2] = {imgRoi.rows, imgRoi.cols};
159  PyObject* pImageBuffer = PyArray_SimpleNewFromData(2, dims, NPY_UBYTE, (void*)imgRoi.data);
160  UASSERT(pImageBuffer);
161 
162  UDEBUG("Preparing data time = %fs", timer.ticks());
163 
164  PyObject *pReturn = PyObject_CallFunctionObjArgs(pFunc_, pImageBuffer, NULL);
165  if(pReturn == NULL)
166  {
167  UERROR("Failed to call match() function!");
168  UERROR("%s", getPythonTraceback().c_str());
169  }
170  else
171  {
172  UDEBUG("Python detector time = %fs", timer.ticks());
173 
174  if (PyTuple_Check(pReturn) && PyTuple_GET_SIZE(pReturn) == 2)
175  {
176  PyObject *kptsPtr = PyTuple_GET_ITEM(pReturn, 0);
177  PyObject *descPtr = PyTuple_GET_ITEM(pReturn, 1);
178  if(PyArray_Check(kptsPtr) && PyArray_Check(descPtr))
179  {
180  PyArrayObject *arrayPtr = reinterpret_cast<PyArrayObject*>(kptsPtr);
181  int nKpts = PyArray_SHAPE(arrayPtr)[0];
182  int kptSize = PyArray_SHAPE(arrayPtr)[1];
183  int type = PyArray_TYPE(arrayPtr);
184  UDEBUG("Kpts array %dx%d (type=%d)", nKpts, kptSize, type);
185  UASSERT(kptSize == 3);
186  UASSERT_MSG(type == NPY_FLOAT, uFormat("Returned matches should type FLOAT=11, received type=%d", type).c_str());
187 
188  float* c_out = reinterpret_cast<float*>(PyArray_DATA(arrayPtr));
189  keypoints.reserve(nKpts);
190  for (int i = 0; i < nKpts*kptSize; i+=kptSize)
191  {
192  cv::KeyPoint kpt(c_out[i], c_out[i+1], 8, -1, c_out[i+2]);
193  keypoints.push_back(kpt);
194  }
195 
196  arrayPtr = reinterpret_cast<PyArrayObject*>(descPtr);
197  int nDesc = PyArray_SHAPE(arrayPtr)[0];
198  UASSERT(nDesc = nKpts);
199  int dim = PyArray_SHAPE(arrayPtr)[1];
200  type = PyArray_TYPE(arrayPtr);
201  UDEBUG("Desc array %dx%d (type=%d)", nDesc, dim, type);
202  UASSERT_MSG(type == NPY_FLOAT, uFormat("Returned matches should type FLOAT=11, received type=%d", type).c_str());
203 
204  c_out = reinterpret_cast<float*>(PyArray_DATA(arrayPtr));
205  for (int i = 0; i < nDesc*dim; i+=dim)
206  {
207  cv::Mat descriptor = cv::Mat(1, dim, CV_32FC1, &c_out[i]).clone();
208  descriptors_.push_back(descriptor);
209  }
210  }
211  }
212  else
213  {
214  UWARN("Expected tuple (Kpts 3 x N, Descriptors dim x N), returning empty features.");
215  }
216  Py_DECREF(pReturn);
217  }
218  Py_DECREF(pImageBuffer);
219  }
220 
221  return keypoints;
222 }
223 
224 cv::Mat PyDetector::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
225 {
226  UASSERT((int)keypoints.size() == descriptors_.rows);
227  return descriptors_;
228 }
229 
230 }
compare
bool compare
rtabmap::PyDetector::pModule_
PyObject * pModule_
Definition: PyDetector.h:34
UFile::getName
std::string getName()
Definition: UFile.h:135
glm::mask
GLM_FUNC_DECL genIType mask(genIType const &count)
timer
rtabmap::PyDetector::generateKeypointsImpl
virtual std::vector< cv::KeyPoint > generateKeypointsImpl(const cv::Mat &image, const cv::Rect &roi, const cv::Mat &mask=cv::Mat())
Definition: PyDetector.cpp:87
rtabmap_netvlad.descriptor
def descriptor
Definition: rtabmap_netvlad.py:81
PyUnicode_FromString
#define PyUnicode_FromString
UDirectory.h
rtabmap::PyDetector::PyDetector
PyDetector(const ParametersMap &parameters=ParametersMap())
Definition: PyDetector.cpp:21
type
rtabmap::ParametersMap
std::map< std::string, std::string > ParametersMap
Definition: Parameters.h:43
UTimer.h
rtabmap::PyDetector::~PyDetector
virtual ~PyDetector()
Definition: PyDetector.cpp:63
rtabmap::Parameters::parse
static bool parse(const ParametersMap &parameters, const std::string &key, bool &value)
Definition: Parameters.cpp:500
rtabmap::getPythonTraceback
std::string getPythonTraceback()
Definition: PythonInterface.cpp:30
UDirectory::homeDir
static std::string homeDir()
Definition: UDirectory.cpp:355
UDirectory::getDir
static std::string getDir(const std::string &filePath)
Definition: UDirectory.cpp:273
UConversion.h
Some conversion functions.
UFile::getExtension
std::string getExtension()
Definition: UFile.h:140
rtabmap::Feature2D::parseParameters
virtual void parseParameters(const ParametersMap &parameters)
Definition: Features2d.cpp:508
UASSERT
#define UASSERT(condition)
rtabmap::Parameters
Definition: Parameters.h:170
rtabmap::PyDetector::generateDescriptorsImpl
virtual cv::Mat generateDescriptorsImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const
Definition: PyDetector.cpp:224
rtabmap::PyDetector::cuda_
bool cuda_
Definition: PyDetector.h:37
UASSERT_MSG
#define UASSERT_MSG(condition, msg_str)
Definition: ULogger.h:67
UWARN
#define UWARN(...)
uFormat
std::string UTILITE_EXPORT uFormat(const char *fmt,...)
Definition: UConversion.cpp:365
uReplaceChar
std::string UTILITE_EXPORT uReplaceChar(const std::string &str, char before, char after)
Definition: UConversion.cpp:33
ULogger.h
ULogger class and convenient macros.
rtabmap::PyDetector::pFunc_
PyObject * pFunc_
Definition: PyDetector.h:35
uSplit
std::list< std::string > uSplit(const std::string &str, char separator=' ')
Definition: UStl.h:564
embed.h
dim
dim
c_str
const char * c_str(Args &&...args)
UStl.h
Wrappers of STL for convenient functions.
rtabmap::PyDetector::descriptors_
cv::Mat descriptors_
Definition: PyDetector.h:38
UDEBUG
#define UDEBUG(...)
UTimer
Definition: UTimer.h:46
NULL
#define NULL
UFile.h
rtabmap
Definition: CameraARCore.cpp:35
rtabmap::PyDetector::parseParameters
virtual void parseParameters(const ParametersMap &parameters)
Definition: PyDetector.cpp:77
UFile::exists
bool exists()
Definition: UFile.h:104
UERROR
#define UERROR(...)
rtabmap::PyDetector::path_
std::string path_
Definition: PyDetector.h:36
i
int i
result
RESULT & result
PyDetector.h


rtabmap
Author(s): Mathieu Labbe
autogenerated on Thu Jul 25 2024 02:50:14