-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sfm::reconstruct error with python error: (-215:Assertion failed) k == STD_VECTOR_MAT || k == STD_ARRAY_MAT in function 'getMatRef' #1675
Comments
i don't have the sfm module (or python bindings for that), but: if lcm is your camera Mat, it should go into the 4th argument(K), not the 2nd (Ps).
can you also try a : |
Hey @berak Here is the output of Help on built-in function reconstruct:
reconstruct(...)
reconstruct(points2d, K[, Ps[, points3d[, is_projective]]]) -> Ps, points3d, K
. @brief Reconstruct 3d points from 2d correspondences while performing autocalibration.
. @param points2d Input vector of vectors of 2d points (the inner vector is per image).
. @param Ps Output vector with the 3x4 projections matrices of each image.
. @param points3d Output array with estimated 3d points.
. @param K Input/Output camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$. Input parameters used as initial guess.
. @param is_projective if true, the cameras are supposed to be projective.
.
. This method calls below signature and extracts projection matrices from estimated K, R and t.
.
. @note
. - Tracks must be as precise as possible. It does not handle outliers and is very sensible to them. Changing the input arguments to named arguments resulted in the same error: cv2.sfm.reconstruct(kps_for_recon, K=lcm,is_projective=True)
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-96-c9a12494b6e8> in <module>()
----> 1 cv2.sfm.reconstruct(kps_for_recon, K=lcm,is_projective=True)
error: OpenCV(4.0.0-pre) /Users/<path>/opencv/modules/core/src/matrix_wrap.cpp:1735: error: (-215:Assertion failed) k == STD_VECTOR_MAT || k == STD_ARRAY_MAT in function 'getMatRef' |
oh, thanks for the report ! hmm, you might be the 1st person ever, to try this from python, unfortunately. any chance you still have the opencv build folder ? looking at build/modules/python_bindings_generator/pyopencv_generated_funcs.h (and finding the reconstruct() wrapper) might be helpful. |
Ok found it, it's interesting: static PyObject* pyopencv_cv_sfm_reconstruct(PyObject* , PyObject* args, PyObject* kw)
{
using namespace cv::sfm;
{
PyObject* pyobj_points2d = NULL;
vector_Mat points2d;
PyObject* pyobj_Ps = NULL;
Mat Ps;
PyObject* pyobj_points3d = NULL;
Mat points3d;
PyObject* pyobj_K = NULL;
Mat K;
bool is_projective=false;
const char* keywords[] = { "points2d", "K", "Ps", "points3d", "is_projective", NULL };
if( PyArg_ParseTupleAndKeywords(args, kw, "OO|OOb:reconstruct", (char**)keywords, &pyobj_points2d, &pyobj_K, &pyobj_Ps, &pyobj_points3d, &is_projective) &&
pyopencv_to(pyobj_points2d, points2d, ArgInfo("points2d", 0)) &&
pyopencv_to(pyobj_Ps, Ps, ArgInfo("Ps", 1)) &&
pyopencv_to(pyobj_points3d, points3d, ArgInfo("points3d", 1)) &&
pyopencv_to(pyobj_K, K, ArgInfo("K", 1)) )
{
ERRWRAP2(cv::sfm::reconstruct(points2d, Ps, points3d, K, is_projective));
return Py_BuildValue("(NNN)", pyopencv_from(Ps), pyopencv_from(points3d), pyopencv_from(K));
}
}
PyErr_Clear();
{
PyObject* pyobj_points2d = NULL;
vector_Mat points2d;
PyObject* pyobj_Ps = NULL;
UMat Ps;
PyObject* pyobj_points3d = NULL;
UMat points3d;
PyObject* pyobj_K = NULL;
UMat K;
bool is_projective=false;
const char* keywords[] = { "points2d", "K", "Ps", "points3d", "is_projective", NULL };
if( PyArg_ParseTupleAndKeywords(args, kw, "OO|OOb:reconstruct", (char**)keywords, &pyobj_points2d, &pyobj_K, &pyobj_Ps, &pyobj_points3d, &is_projective) &&
pyopencv_to(pyobj_points2d, points2d, ArgInfo("points2d", 0)) &&
pyopencv_to(pyobj_Ps, Ps, ArgInfo("Ps", 1)) &&
pyopencv_to(pyobj_points3d, points3d, ArgInfo("points3d", 1)) &&
pyopencv_to(pyobj_K, K, ArgInfo("K", 1)) )
{
ERRWRAP2(cv::sfm::reconstruct(points2d, Ps, points3d, K, is_projective));
return Py_BuildValue("(NNN)", pyopencv_from(Ps), pyopencv_from(points3d), pyopencv_from(K));
}
}
return NULL;
} It appears that the order of the keyword arguments in the python wrapper don't align with the order of arguments (passed?) to the C++ I'm wondering if the problem is that I'm using the latest version of OpenCV (4.0.0-pre) and OpenCV contrib modules, and the behavior of some of the core functions is a bit different. |
oh, that is really helpful !
the python wrapper script has an internal rule for this:
i don't think so. imho, there's a bug in the python generator(script), and not much changed there between 3.4 and 4.0 but here's the bug !
remember the errormsg ? it should be you can easily reproduce it with 4 lines of c++:
|
Ok, so how does this get fixed? Which line of code in the |
good one ;) i have no (immediate) idea. we'll have to dive in here: https://github.com/opencv/opencv/tree/master/modules/python/src2 https://docs.opencv.org/master/df/da2/tutorial_py_table_of_contents_bindings.html and again, you seem to be the 1st person to try this from python, aka -- "our man on the moon" ! |
Ok, so based on this issue, I changed the CV_EXPORTS_W //changed to allow python bindings to be built
void
reconstruct(InputArrayOfArrays points2d, OutputArray Ps, OutputArray points3d, InputOutputArray K,bool is_projective = false); Is there another macro that needs to be changed to the I could also try to change which overloaded method of |
hmm, what if you change the c++ sig to:
( OutputArrayOfArrays should generate a vector instead of a single Mat (OutputArray) in python ) ? (and rebuild the whole schlepp) (same might be needed for points3d, idk.) |
@berak well the Once more, unto the breach (of recompiling)! |
yea, true. all i was trying to point out was: if the python generator script encounters an so, well, shift in the diagnosis again: imho, the c++ sig is wrong, so the py generator does the wrong thing (and the Ps prob has to be mended, before going on to pts3d) |
Ok, so I made the changes suggested and rebuilt. There are now modifications to the static PyObject* pyopencv_cv_sfm_reconstruct(PyObject* , PyObject* args, PyObject* kw)
{
using namespace cv::sfm;
{
PyObject* pyobj_points2d = NULL;
vector_Mat points2d;
PyObject* pyobj_Ps = NULL;
vector_Mat Ps;
PyObject* pyobj_points3d = NULL;
Mat points3d;
PyObject* pyobj_K = NULL;
Mat K;
bool is_projective=false;
const char* keywords[] = { "points2d", "K", "Ps", "points3d", "is_projective", NULL };
if( PyArg_ParseTupleAndKeywords(args, kw, "OO|OOb:reconstruct", (char**)keywords, &pyobj_points2d, &pyobj_K, &pyobj_Ps, &pyobj_points3d, &is_projective) &&
pyopencv_to(pyobj_points2d, points2d, ArgInfo("points2d", 0)) &&
pyopencv_to(pyobj_Ps, Ps, ArgInfo("Ps", 1)) &&
pyopencv_to(pyobj_points3d, points3d, ArgInfo("points3d", 1)) &&
pyopencv_to(pyobj_K, K, ArgInfo("K", 1)) )
{
ERRWRAP2(cv::sfm::reconstruct(points2d, Ps, points3d, K, is_projective));
return Py_BuildValue("(NNN)", pyopencv_from(Ps), pyopencv_from(points3d), pyopencv_from(K));
}
}
PyErr_Clear();
{
PyObject* pyobj_points2d = NULL;
vector_Mat points2d;
PyObject* pyobj_Ps = NULL;
vector_Mat Ps;
PyObject* pyobj_points3d = NULL;
UMat points3d;
PyObject* pyobj_K = NULL;
UMat K;
bool is_projective=false;
const char* keywords[] = { "points2d", "K", "Ps", "points3d", "is_projective", NULL };
if( PyArg_ParseTupleAndKeywords(args, kw, "OO|OOb:reconstruct", (char**)keywords, &pyobj_points2d, &pyobj_K, &pyobj_Ps, &pyobj_points3d, &is_projective) &&
pyopencv_to(pyobj_points2d, points2d, ArgInfo("points2d", 0)) &&
pyopencv_to(pyobj_Ps, Ps, ArgInfo("Ps", 1)) &&
pyopencv_to(pyobj_points3d, points3d, ArgInfo("points3d", 1)) &&
pyopencv_to(pyobj_K, K, ArgInfo("K", 1)) )
{
ERRWRAP2(cv::sfm::reconstruct(points2d, Ps, points3d, K, is_projective));
return Py_BuildValue("(NNN)", pyopencv_from(Ps), pyopencv_from(points3d), pyopencv_from(K));
}
}
return NULL;
} And |
The other weird thing I'm now noticing is in the example scene reconstruction bool is_projective = true;
vector<Mat> Rs_est, ts_est, points3d_estimated;
reconstruct(images_paths, Rs_est, ts_est, K, points3d_estimated, is_projective); Here they are creating the The function declaration in the header file CV_EXPORTS
void
reconstruct(const std::vector<String> images, OutputArray Rs, OutputArray Ts,
InputOutputArray K, OutputArray points3d, bool is_projective = false); Additionally the reconstruction example works on my machine. Not sure what the exact issue is here. |
Ok, strange behavior but I got it to work. I had to change the CV_EXPORTS_W //changed to allow python bindings to be built
void
reconstruct(InputArrayOfArrays points2d, OutputArrayOfArrays Ps, OutputArrayOfArrays points3d, InputOutputArray K, bool is_projective = false); Seems like the object type of the input argument wasn't correct, and hence the python bindings were generating the incorrect object types for the function. I've updated the code on my forked version of the repo. @berak are you a maintainer for the |
no, i'm not the maintainer of this, i'm only out for a nice "detective story" , now & then. do you feel apt to make a pr with the changes ? if so, -- please do ! (your bug, your fix, your honour.) (and only 1 overload (the one marked CV_EXPORTS_W) will be wrapped into python/java/matlab, so only that one needs to be fixed, imho.) |
Yeah I don't have a problem making a PR, I have the changes saved on my fork of the repo. Just haven't contributed here before so just want to make sure I that whatever I do is in the style of the people who are maintaining the project. |
https://github.com/opencv/opencv/wiki/How_to_contribute (if you have not found it yet) |
I have been trying to get the same issue sorted out. I am that your fork will do the trick. I do get a warning that coming from your insertion of
in sfm.hpp and reconstruct.hpp. It seems that only when the python bindings are compiled that this flag is not set externally, do you know if there might be a better way around this? I looked on the pull requests, but did not see this issue in there. I certainly would find this fix useful so that the reconstruct function will eventually make it to the masses. |
Python (and other bindings) should use public OpenCV API only. |
Perhaps I don't fully understand the build process. Are there other examples in OpenCV where conditional compilation is done? The main issue with the python bindings seems to be related to the following:
|
@pierslawrence no, i'm not. (as stated before, already :) |
@berak I understand that is the case that you are not the maintainer. Sorry about that, I quoted the whole post. Making the change to OutputArrayOfArrays for Ps and points3d in reconstruct.hpp together with the CV_EXPORTS_W works for me to get the python version correctly working. CV_EXPORTS_W //changed to allow python bindings to be built
void
reconstruct(InputArrayOfArrays points2d, OutputArrayOfArrays Ps, OutputArrayOfArrays points3d,
InputOutputArray K, bool is_projective = false); |
Hi Everyone,
I'm messing around with the
sfm
module and doing a 3D reconstruction from a video file. I've compiled the OpenCV project with the contributed modules on my machine (Mac OS X 10.11.6, python 3.6 Anaconda) with python bindings forsfm
. Compilation was successful, and I am able to successfully run theexample_sfm_scene_reconstruction
program.For the problem I'm having, the general program is as follows:
ORB
features for the first 8 images from the videolist
, where each element of the list is a 2XN (where N is the number of features detected in the image, typically 100 points so 2X100) numpy array.sfm::reconstruct(InputArrayOfArrays points2d, OutputArray Ps, OutputArray points3d, InputOutputArray K, bool is_projective)
via the python binding.Code is as follows
The code starts to run, then I get an error:
error: (-215:Assertion failed) k == STD_VECTOR_MAT || k == STD_ARRAY_MAT in function 'getMatRef'
Based on how I understand the
sfm::reconstruct
function works, I think the error is coming from the line linked below.opencv_contrib/modules/sfm/src/reconstruct.cpp
Line 141 in 21e1c8b
Camera matrix:
Any help much appreciated. I'm really not sure where the error is coming from.
The text was updated successfully, but these errors were encountered: