15 #define NPY_NO_DEPRECATED_API NPY_API_VERSION
16 #include <numpy/arrayobject.h>
22 const std::string & pythonMatcherPath,
26 const std::string &
model) :
29 matchThreshold_(matchThreshold),
30 iterations_(iterations),
40 UERROR(
"Cannot initialize Python matcher, the path is not valid: \"%s\"",
path_.c_str());
44 pybind11::gil_scoped_acquire acquire;
47 if(!matcherPythonDir.empty())
49 PyRun_SimpleString(
"import sys");
50 PyRun_SimpleString(
uFormat(
"sys.path.append(\"%s\")", matcherPythonDir.c_str()).c_str());
63 UERROR(
"Module \"%s\" could not be imported! (File=\"%s\")", scriptName.c_str(),
path_.c_str());
70 pybind11::gil_scoped_acquire acquire;
82 const cv::Mat & descriptorsQuery,
83 const cv::Mat & descriptorsTrain,
84 const std::vector<cv::KeyPoint> & keypointsQuery,
85 const std::vector<cv::KeyPoint> & keypointsTrain,
86 const cv::Size & imageSize)
89 std::vector<cv::DMatch>
matches;
93 UERROR(
"Python matcher module not loaded!");
97 if(!descriptorsQuery.empty() &&
98 descriptorsQuery.cols == descriptorsTrain.cols &&
99 descriptorsQuery.type() == CV_32F &&
100 descriptorsTrain.type() == CV_32F &&
101 descriptorsQuery.rows == (
int)keypointsQuery.size() &&
102 descriptorsTrain.rows == (
int)keypointsTrain.size() &&
103 imageSize.width>0 && imageSize.height>0)
106 pybind11::gil_scoped_acquire acquire;
112 PyObject * pFunc = PyObject_GetAttrString(
pModule_,
"init");
115 if(PyCallable_Check(pFunc))
121 UERROR(
"Call to \"init(...)\" in \"%s\" failed!",
path_.c_str());
134 UERROR(
"Cannot find method \"match(...)\" in %s",
path_.c_str());
146 UERROR(
"Cannot call method \"init(...)\" in %s",
path_.c_str());
154 UERROR(
"Cannot find method \"init(...)\"");
163 std::vector<float> descriptorsQueryV(descriptorsQuery.rows * descriptorsQuery.cols);
164 memcpy(descriptorsQueryV.data(), descriptorsQuery.data, descriptorsQuery.total()*
sizeof(
float));
165 npy_intp dimsFrom[2] = {descriptorsQuery.rows, descriptorsQuery.cols};
166 PyObject* pDescriptorsQuery = PyArray_SimpleNewFromData(2, dimsFrom, NPY_FLOAT, (
void*)descriptorsQueryV.data());
169 npy_intp dimsTo[2] = {descriptorsTrain.rows, descriptorsTrain.cols};
170 std::vector<float> descriptorsTrainV(descriptorsTrain.rows * descriptorsTrain.cols);
171 memcpy(descriptorsTrainV.data(), descriptorsTrain.data, descriptorsTrain.total()*
sizeof(
float));
172 PyObject* pDescriptorsTrain = PyArray_SimpleNewFromData(2, dimsTo, NPY_FLOAT, (
void*)descriptorsTrainV.data());
175 std::vector<float> keypointsQueryV(keypointsQuery.size()*2);
176 std::vector<float> scoresQuery(keypointsQuery.size());
177 for(
size_t i=0;
i<keypointsQuery.size(); ++
i)
179 keypointsQueryV[
i*2] = keypointsQuery[
i].pt.x;
180 keypointsQueryV[
i*2+1] = keypointsQuery[
i].pt.y;
181 scoresQuery[
i] = keypointsQuery[
i].response;
184 std::vector<float> keypointsTrainV(keypointsTrain.size()*2);
185 std::vector<float> scoresTrain(keypointsTrain.size());
186 for(
size_t i=0;
i<keypointsTrain.size(); ++
i)
188 keypointsTrainV[
i*2] = keypointsTrain[
i].pt.x;
189 keypointsTrainV[
i*2+1] = keypointsTrain[
i].pt.y;
190 scoresTrain[
i] = keypointsTrain[
i].response;
193 npy_intp dimsKpQuery[2] = {(
int)keypointsQuery.size(), 2};
194 PyObject* pKeypointsQuery = PyArray_SimpleNewFromData(2, dimsKpQuery, NPY_FLOAT, (
void*)keypointsQueryV.data());
197 npy_intp dimsKpTrain[2] = {(
int)keypointsTrain.size(), 2};
198 PyObject* pkeypointsTrain = PyArray_SimpleNewFromData(2, dimsKpTrain, NPY_FLOAT, (
void*)keypointsTrainV.data());
201 npy_intp dimsScoresQuery[1] = {(
int)keypointsQuery.size()};
202 PyObject* pScoresQuery = PyArray_SimpleNewFromData(1, dimsScoresQuery, NPY_FLOAT, (
void*)scoresQuery.data());
205 npy_intp dimsScoresTrain[1] = {(
int)keypointsTrain.size()};
206 PyObject* pScoresTrain = PyArray_SimpleNewFromData(1, dimsScoresTrain, NPY_FLOAT, (
void*)scoresTrain.data());
209 PyObject * pImageWidth = PyLong_FromLong(imageSize.width);
210 PyObject * pImageHeight = PyLong_FromLong(imageSize.height);
212 UDEBUG(
"Preparing data time = %fs",
timer.ticks());
214 PyObject *pReturn = PyObject_CallFunctionObjArgs(
pFunc_, pKeypointsQuery, pkeypointsTrain, pScoresQuery, pScoresTrain, pDescriptorsQuery, pDescriptorsTrain, pImageWidth, pImageHeight,
NULL);
217 UERROR(
"Failed to call match() function!");
222 UDEBUG(
"Python matching time = %fs",
timer.ticks());
224 PyArrayObject *np_ret =
reinterpret_cast<PyArrayObject*
>(pReturn);
227 int len1 = PyArray_SHAPE(np_ret)[0];
228 int len2 = PyArray_SHAPE(np_ret)[1];
229 int type = PyArray_TYPE(np_ret);
230 UDEBUG(
"Matches array %dx%d (type=%d)", len1, len2,
type);
234 long* c_out =
reinterpret_cast<long*
>(PyArray_DATA(np_ret));
235 for (
int i = 0;
i < len1*len2;
i+=2)
237 matches.push_back(cv::DMatch(c_out[
i], c_out[
i+1], 0));
242 int* c_out =
reinterpret_cast<int*
>(PyArray_DATA(np_ret));
243 for (
int i = 0;
i < len1*len2;
i+=2)
245 matches.push_back(cv::DMatch(c_out[
i], c_out[
i+1], 0));
251 Py_DECREF(pDescriptorsQuery);
252 Py_DECREF(pDescriptorsTrain);
253 Py_DECREF(pKeypointsQuery);
254 Py_DECREF(pkeypointsTrain);
255 Py_DECREF(pScoresQuery);
256 Py_DECREF(pScoresTrain);
257 Py_DECREF(pImageWidth);
258 Py_DECREF(pImageHeight);
260 UDEBUG(
"Fill matches (%d/%d) and cleanup time = %fs",
matches.size(),
std::min(descriptorsQuery.rows, descriptorsTrain.rows),
timer.ticks());
265 UERROR(
"Invalid inputs! Supported python matchers require float descriptors.");