13 #define NPY_NO_DEPRECATED_API NPY_API_VERSION 14 #include <numpy/arrayobject.h> 20 const std::string & pythonMatcherPath,
24 const std::string &
model) :
27 matchThreshold_(matchThreshold),
28 iterations_(iterations),
38 UERROR(
"Cannot initialize Python matcher, the path is not valid: \"%s\"",
path_.c_str());
45 if(!matcherPythonDir.empty())
47 PyRun_SimpleString(
"import sys");
48 PyRun_SimpleString(
uFormat(
"sys.path.append(\"%s\")", matcherPythonDir.c_str()).c_str());
61 UERROR(
"Module \"%s\" could not be imported! (File=\"%s\")", scriptName.c_str(),
path_.c_str());
83 const cv::Mat & descriptorsQuery,
84 const cv::Mat & descriptorsTrain,
85 const std::vector<cv::KeyPoint> & keypointsQuery,
86 const std::vector<cv::KeyPoint> & keypointsTrain,
87 const cv::Size & imageSize)
90 std::vector<cv::DMatch>
matches;
94 UERROR(
"Python matcher module not loaded!");
98 if(!descriptorsQuery.empty() &&
99 descriptorsQuery.cols == descriptorsTrain.cols &&
100 descriptorsQuery.type() == CV_32F &&
101 descriptorsTrain.type() == CV_32F &&
102 descriptorsQuery.rows == (int)keypointsQuery.size() &&
103 descriptorsTrain.rows == (int)keypointsTrain.size() &&
104 imageSize.width>0 && imageSize.height>0)
113 PyObject * pFunc = PyObject_GetAttrString(
pModule_,
"init");
116 if(PyCallable_Check(pFunc))
122 UERROR(
"Call to \"init(...)\" in \"%s\" failed!",
path_.c_str());
135 UERROR(
"Cannot find method \"match(...)\" in %s",
path_.c_str());
147 UERROR(
"Cannot call method \"init(...)\" in %s",
path_.c_str());
155 UERROR(
"Cannot find method \"init(...)\"");
164 std::vector<float> descriptorsQueryV(descriptorsQuery.rows * descriptorsQuery.cols);
165 memcpy(descriptorsQueryV.data(), descriptorsQuery.data, descriptorsQuery.total()*
sizeof(float));
166 npy_intp dimsFrom[2] = {descriptorsQuery.rows, descriptorsQuery.cols};
167 PyObject* pDescriptorsQuery = PyArray_SimpleNewFromData(2, dimsFrom, NPY_FLOAT, (
void*)descriptorsQueryV.data());
170 npy_intp dimsTo[2] = {descriptorsTrain.rows, descriptorsTrain.cols};
171 std::vector<float> descriptorsTrainV(descriptorsTrain.rows * descriptorsTrain.cols);
172 memcpy(descriptorsTrainV.data(), descriptorsTrain.data, descriptorsTrain.total()*
sizeof(float));
173 PyObject* pDescriptorsTrain = PyArray_SimpleNewFromData(2, dimsTo, NPY_FLOAT, (
void*)descriptorsTrainV.data());
176 std::vector<float> keypointsQueryV(keypointsQuery.size()*2);
177 std::vector<float> scoresQuery(keypointsQuery.size());
178 for(
size_t i=0; i<keypointsQuery.size(); ++i)
180 keypointsQueryV[i*2] = keypointsQuery[i].pt.x;
181 keypointsQueryV[i*2+1] = keypointsQuery[i].pt.y;
182 scoresQuery[i] = keypointsQuery[i].response;
185 std::vector<float> keypointsTrainV(keypointsTrain.size()*2);
186 std::vector<float> scoresTrain(keypointsTrain.size());
187 for(
size_t i=0; i<keypointsTrain.size(); ++i)
189 keypointsTrainV[i*2] = keypointsTrain[i].pt.x;
190 keypointsTrainV[i*2+1] = keypointsTrain[i].pt.y;
191 scoresTrain[i] = keypointsTrain[i].response;
194 npy_intp dimsKpQuery[2] = {(int)keypointsQuery.size(), 2};
195 PyObject* pKeypointsQuery = PyArray_SimpleNewFromData(2, dimsKpQuery, NPY_FLOAT, (
void*)keypointsQueryV.data());
198 npy_intp dimsKpTrain[2] = {(int)keypointsTrain.size(), 2};
199 PyObject* pkeypointsTrain = PyArray_SimpleNewFromData(2, dimsKpTrain, NPY_FLOAT, (
void*)keypointsTrainV.data());
202 npy_intp dimsScoresQuery[1] = {(int)keypointsQuery.size()};
203 PyObject* pScoresQuery = PyArray_SimpleNewFromData(1, dimsScoresQuery, NPY_FLOAT, (
void*)scoresQuery.data());
206 npy_intp dimsScoresTrain[1] = {(int)keypointsTrain.size()};
207 PyObject* pScoresTrain = PyArray_SimpleNewFromData(1, dimsScoresTrain, NPY_FLOAT, (
void*)scoresTrain.data());
210 PyObject * pImageWidth = PyLong_FromLong(imageSize.width);
211 PyObject * pImageHeight = PyLong_FromLong(imageSize.height);
213 UDEBUG(
"Preparing data time = %fs", timer.
ticks());
215 PyObject *pReturn = PyObject_CallFunctionObjArgs(
pFunc_, pKeypointsQuery, pkeypointsTrain, pScoresQuery, pScoresTrain, pDescriptorsQuery, pDescriptorsTrain, pImageWidth, pImageHeight,
NULL);
218 UERROR(
"Failed to call match() function!");
223 UDEBUG(
"Python matching time = %fs", timer.
ticks());
225 PyArrayObject *np_ret =
reinterpret_cast<PyArrayObject*
>(pReturn);
228 int len1 = PyArray_SHAPE(np_ret)[0];
229 int len2 = PyArray_SHAPE(np_ret)[1];
230 int type = PyArray_TYPE(np_ret);
231 UDEBUG(
"Matches array %dx%d (type=%d)", len1, len2, type);
232 UASSERT_MSG(type == NPY_LONG || type == NPY_INT,
uFormat(
"Returned matches should type INT=5 or LONG=7, received type=%d", type).c_str());
235 long* c_out =
reinterpret_cast<long*
>(PyArray_DATA(np_ret));
236 for (
int i = 0; i < len1*len2; i+=2)
238 matches.push_back(cv::DMatch(c_out[i], c_out[i+1], 0));
243 int* c_out =
reinterpret_cast<int*
>(PyArray_DATA(np_ret));
244 for (
int i = 0; i < len1*len2; i+=2)
246 matches.push_back(cv::DMatch(c_out[i], c_out[i+1], 0));
252 Py_DECREF(pDescriptorsQuery);
253 Py_DECREF(pDescriptorsTrain);
254 Py_DECREF(pKeypointsQuery);
255 Py_DECREF(pkeypointsTrain);
256 Py_DECREF(pScoresQuery);
257 Py_DECREF(pScoresTrain);
258 Py_DECREF(pImageWidth);
259 Py_DECREF(pImageHeight);
261 UDEBUG(
"Fill matches (%d/%d) and cleanup time = %fs", matches.size(),
std::min(descriptorsQuery.rows, descriptorsTrain.rows), timer.
ticks());
267 UERROR(
"Invalid inputs! Supported python matchers require float descriptors.");
static std::string homeDir()
GLM_FUNC_DECL genType min(genType const &x, genType const &y)
static std::string getDir(const std::string &filePath)
Some conversion functions.
std::string getExtension()
std::string getTraceback()
#define UASSERT(condition)
Wrappers of STL for convenient functions.
std::list< std::string > uSplit(const std::string &str, char separator=' ')
#define UASSERT_MSG(condition, msg_str)
PyMatcher(const std::string &pythonMatcherPath, float matchThreshold=0.2f, int iterations=20, bool cuda=true, const std::string &model="indoor")
std::string UTILITE_EXP uReplaceChar(const std::string &str, char before, char after)
ULogger class and convenient macros.
#define PyUnicode_FromString
std::string UTILITE_EXP uFormat(const char *fmt,...)
std::vector< cv::DMatch > match(const cv::Mat &descriptorsQuery, const cv::Mat &descriptorsTrain, const std::vector< cv::KeyPoint > &keypointsQuery, const std::vector< cv::KeyPoint > &keypointsTrain, const cv::Size &imageSize)