stereolabs / zed-opencv

ZED SDK interface sample for OpenCV
https://www.stereolabs.com/docs/opencv/
MIT License
139 stars 79 forks source link

How to pass sl::mat with MEM_GPU to opencv gpumat #60

Closed Kevin0602 closed 6 years ago

Kevin0602 commented 6 years ago

Hi, Im using zed camera with jetson tx2,and i wanna pass the gpu mat directly to opencv gpumat for the further process. I create a function be similar with the slmat2cvmat function in the example as follows:

cv::cuda::GpuMat slGpuMat2cvGpuMat(sl::Mat& input) { // Mapping between MAT_TYPE and CV_TYPE int cv_type = -1; switch (input.getDataType()) { case MAT_TYPE_32F_C1: cv_type = CV_32FC1; break; case MAT_TYPE_32F_C2: cv_type = CV_32FC2; break; case MAT_TYPE_32F_C3: cv_type = CV_32FC3; break; case MAT_TYPE_32F_C4: cv_type = CV_32FC4; break; case MAT_TYPE_8U_C1: cv_type = CV_8UC1; break; case MAT_TYPE_8U_C2: cv_type = CV_8UC2; break; case MAT_TYPE_8U_C3: cv_type = CV_8UC3; break; case MAT_TYPE_8U_C4: cv_type = CV_8UC4; break; default: break; }

// Since cv::Mat data requires a uchar* pointer, we get the uchar1 pointer from sl::Mat (getPtr<T>())
// cv::Mat and sl::Mat will share a single memory structure
return cv::cuda::GpuMat(input.getHeight(), input.getWidth(), cv_type, input.getPtr<sl::uchar1>(MEM_GPU),input.getStep(MEM_GPU));

}

But,when i call the copyTo menber function of this gpumat i got a error like this: Opencv Error: Gpu API call (invalid argument) in copyTo and there is a simliar error when i call the download menber function,like: Opencv Error: Gpu API call (invalid argument) in download

Would you please help me to figure out this problem?

SimonEbner commented 6 years ago

@Kevin0602 we use the following code successfully, maybe it may help you

cv::cuda::GpuMat to_gpu_mat(const sl::Mat& input)
{
    return cv::cuda::GpuMat(
        static_cast<int>(input.getHeight()), static_cast<int>(input.getWidth()),
        decode_mat_type(input.getDataType()),
        input.getPtr<sl::uchar1>(sl::MEM_GPU), input.getStepBytes(sl::MEM_GPU));
}

and

auto decode_mat_type(sl::MAT_TYPE in)
{
    switch (in) {
    case sl::MAT_TYPE_32F_C1:
        return cv_32fc1;
    case sl::MAT_TYPE_32F_C2:
        return cv_32fc2;
    case sl::MAT_TYPE_32F_C3:
        return cv_32fc3;
    case sl::MAT_TYPE_32F_C4:
        return cv_32fc4;
    case sl::MAT_TYPE_8U_C1:
        return cv_8uc1;
    case sl::MAT_TYPE_8U_C2:
        return cv_8uc2;
    case sl::MAT_TYPE_8U_C3:
        return cv_8uc3;
    case sl::MAT_TYPE_8U_C4:
        return cv_8uc4;
    default:
        throw std::logic_error("default MAT_TYPE");
    }
}
Kevin0602 commented 6 years ago

thanks~