kyamagu / mexopencv

Collection and a development kit of matlab mex functions for OpenCV library
http://kyamagu.github.io/mexopencv
Other
661 stars 319 forks source link

custom mex function opencv_contrib #405

Closed Nickstaut closed 6 years ago

Nickstaut commented 6 years ago

Hello,

I recently started using mexopencv and it is great. I know several opencv_contrib modules are not supported like the rgbd module. What is not completely clear to me is if this means there are no premade functions but i can still make it using the mexopencv.hpp to make my own or if it is completely impossible.

I attempted to mexcompile a simple function from the rgbd module:

#include "mexopencv.hpp"
#include "opencv2/rgbd.hpp"
using namespace std;
using namespace cv;
using namespace cv::rgbd;

void registerDepth(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    // Check number of arguments
    nargchk(nrhs>=10 && (nrhs%2)==0 && nlhs<=1);

    // Argument vector
    vector<MxArray> rhs(prhs, prhs+nrhs);

    // default depthDilation value
    bool depthDilation=false;

    // assign the variables
    Mat unregisteredDepth, cameraMatrixIR, cameraMatrixRGB;
    Mat distortionCoefficientRGB,transformationMatrix, registeredDepth;
    // Convert mxArrays to cv::Mat and assign other input
    unregisteredDepth = rhs[0].toMat(CV_32FC1);
    const Size& outputImageSize = rhs[1].toSize();
    for (int idx=2; idx < nrhs; idx = idx+2) {
        string key(rhs[idx].toString());
        if (key == "cameraMatrixIR")
            cameraMatrixIR = rhs[idx+1].toMat();
        else if (key == "cameraMatrixRGB")
            cameraMatrixRGB = rhs[idx+1].toMat();
        else if (key == "distortionCoefficientRGB")
            distortionCoefficientRGB = rhs[idx+1].toMat();
        else if (key == "transformationMatrix")
            transformationMatrix = rhs[idx+1].toMat();
        else if (key == "depthDilation")
            depthDilation = rhs[idx+1].toBool();
        else
            mexErrMsgIdAndTxt("mexopencv:error",
                "Unrecognized option %s", key.c_str());
    }

    // apply the registerDepth function
    registerDepth(cameraMatrixIR, cameraMatrixRGB, distortionCoefficientRGB,
                     transformationMatrix, unregisteredDepth, outputImageSize,
                     registeredDepth, depthDilation); 

    // Convert cv::Mat back to mxArray
    plhs[0] = MxArray(registeredDepth);
}

The compilation did not give any errors but when i try to call this function i get the following error

Invalid MEX-file '/home/nick/mexopencv/+cv/registerDepth.mexa64':
Function mexFunction is missing.

I have no experience with c++ at all so i'm wondering if i did something wrong or if it is not possible at this time to make mexfunctions using mexopencv for the rgbd module.

Thanks in advance

amroamroamro commented 6 years ago

i can still make it using the mexopencv.hpp to make my own

Correct. If a module is missing in mexopencv, it just means we haven't gotten around to write wrappers for it, but you can always create your own MEX-files if you need a specific opencv function not currently exposed.

As for your mistake, the gateway function in a MEX-file must be named mexFunction, as described in MATLAB docs, i.e:


void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
}

Other than that, your code should work.

amroamroamro commented 6 years ago

I looked at opencv docs, here's my version of the wrapper for this function:

#include "mexopencv.hpp"
#include "opencv2/rgbd.hpp"
using namespace std;
using namespace cv;
using namespace cv::rgbd;

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    // Check the number of arguments
    nargchk(nrhs>=5 && (nrhs%2)==1 && nlhs<=1);

    // Argument vector
    vector<MxArray> rhs(prhs, prhs+nrhs);

    // Option processing
    Mat registeredDistCoeffs;
    bool depthDilation = false;
    for (int i=5; i<nrhs; i+=2) {
        string key(rhs[i].toString());
        if (key == "DistCoeffs")
            registeredDistCoeffs = rhs[i+1].toMat(CV_32F);
        else if (key == "DepthDilation")
            depthDilation = rhs[i+1].toBool()
        else
            mexErrMsgIdAndTxt("mexopencv:error",
                "Unrecognized option %s", key.c_str());
    }

    // Process
    Matx33f unregisteredCameraMatrix(rhs[0].toMatx<float,3,3>()),
        registeredCameraMatrix(rhs[1].toMatx<float,3,3>());
    Matx44f Rt(rhs[2].toMatx<float,4,4>());
    Mat unregisteredDepth(rhs[3].toMat(rhs[3].isUint16() ? CV_16U :
        (rhs[3].isSingle() ? CV_32F : CV_64F)));
    Size outputImagePlaneSize(rhs[4].toSize());
    Mat registeredDepth;
    registerDepth(unregisteredCameraMatrix, registeredCameraMatrix,
        registeredDistCoeffs, Rt, unregisteredDepth, outputImagePlaneSize,
        registeredDepth, depthDilation);
    plhs[0] = MxArray(registeredDepth);
}

I'll consider the rgbd module next for adding to mexopencv.

Nickstaut commented 6 years ago

Thank you very much for your quick response. I no longer get the error and can call the function just fine.