cv2.cuda.reprojectImageTo3D(dispcu,Q) error : (-5:Bad argument)

Hello, I would like to ask that how to pass arguments to cuda function reprojectImageTo3D?

The no cuda version works fine xyz = cv2.reprojectImageTo3D(disp.astype(np.float32), self.Q), but I want to improve the calculation speed with the cuda version function. However whatever the arguments I passed, there all has an error.

For example, I pass the GpuMat of disp and numpy array of Q, and the error is:

cv2.cuda.reprojectImageTo3D(disp=dispcu_resize, Q=self.Q)
Traceback (most recent call last):
  File "<string>", line 1, in <module>
cv2.error: OpenCV(4.5.3-openvino) :-1: error: (-5:Bad argument) in function 'reprojectImageTo3D'
> Overload resolution failed:
>  - disp is not a numpy array, neither a scalar
>  - Expected Ptr<cv::cuda::GpuMat> for argument 'Q'
>  - Expected Ptr<cv::UMat> for argument 'disp'

Thanks for your help!!

it should accept disp being a GpuMat, and not be that particular about one small 4x4 matrix of coefficients.

error says that the types have to be the other way around (almost)… which I find odd.

It could be that the python wrapper’s type resolution is in the way, checking/enforcing the wrong things. the function itself, as far as I can see, would agree with how you call it

please check the types of your arguments explicitly yourself, i.e. look at type(dispcu_resize) and type(self.Q)

here’s the code:

Passing disp as a GpuMat does not work for me and causes the following error, that I’m not sure how to interpret:

error: OpenCV(4.5.4) /home/massimo/Downloads/opencv-4.5.4/modules/core/src/matrix_wrap.cpp:111: error: (-213:The function/feature is not implemented) You should explicitly call download method for cuda::GpuMat object in function 'getMat_'

Is it really not implemented in Python?

I’m using OpenCV 4.5.4 and the following minimal working example to understand how to use cv2.cuda.reprojectImageTo3D():

import numpy as np
import cv2

np_disparity = np.random.randint(0, 64, (128, 128), dtype=np.int16)
cu_disparity = cv2.cuda_GpuMat(np_disparity)
np_q = np.random.randint(0, 100, (4, 4)).astype(np.float32)
cu_q = cv2.cuda_GpuMat(4, 4, cv2.CV_32F)
cu_q = cv2.cuda.createContinuous(4, 4, cv2.CV_32FC1, cu_q)
cu_q.upload(np_q)

cu_xyz = cv2.cuda.reprojectImageTo3D(cu_disparity, cu_q)

I even tried to make cu_q continuous according to the specifications in the source code of cv::cuda::reprojectImageTo3D():

CV_Assert( disp.type() == CV_8U || disp.type() == CV_16S || disp.type() == CV_32S || disp.type() == CV_32F );
CV_Assert( Q.type() == CV_32F && Q.rows == 4 && Q.cols == 4 && Q.isContinuous() );
CV_Assert( dst_cn == 3 || dst_cn == 4 );

And also tried to pass all combinations of cu/np versions of disparity and q, but everything ends up in an error, either -5:Bad argument or -213:The function/feature is not implemented.

Any help would be much appreciated.
Thanks in advance!

1 Like

The python bindings are not generated correctly. Change

CV_EXPORTS_W void reprojectImageTo3D(InputArray disp, OutputArray xyzw, InputArray Q, int dst_cn = 4, Stream& stream = Stream::Null());

to

CV_EXPORTS void reprojectImageTo3D(InputArray disp, OutputArray xyzw, InputArray Q, int dst_cn = 4, Stream& stream = Stream::Null());
CV_EXPORTS_W inline void reprojectImageTo3D(GpuMat disp, CV_OUT GpuMat& xyzw, Mat Q, int dst_cn = 4, Stream& stream = Stream::Null()) {
    reprojectImageTo3D((InputArray)disp, (OutputArray)xyzw, (InputArray)Q, dst_cn, stream);
}

in cudastero.hpp.

The below is now working for me

np_disparity = np.random.randint(0, 64, (128, 128), dtype=np.int16)
cu_disparity = cv2.cuda_GpuMat(np_disparity)
np_q = np.random.randint(0, 100, (4, 4)).astype(np.float32)
cu_xyz = cv2.cuda.reprojectImageTo3D(cu_disparity, np_q)
2 Likes

Thanks @cudawarped!
Recompiling OpenCV with the suggested changes to modules/cudastereo/include/opencv2/cudastereo.hpp fixed cv2.cuda.reprojectImageTo3D() for me as well.

P.S. Have you considered submitting a pull request to opencv_contrib?

1 Like

Funny I was going to ask you the same question. I’m a bit busy at the moment it was just by chance I had time yesterday to look into your post. Let me know if u don’t have time either and I’ll submit one in a couple of weeks.