Search code examples
c++cmatlabopencvmex

Linker Error (MEX could not find the OpenCV library)


I'm using MATLAB R2013a x64 and Win7 x64. I installed OpenCV 2.4.7.2 to the path (C:\opencv). Previous compile errors with round are solved, but now there is a linking error.

MEX command output:

>> mex -LC:\opencv\build\x64\vc11\lib -IC:\opencv\build\include\opencv -lcv -lcxcore me_HaarDetectOpenCV.cpp

Warning: MEX could not find the library "cv" specified with -l option. 
         MEX looked for a file with one of the names: 
               cv.lib 
               libcv.lib 
         MEX looked for the library in the following directories: 
               D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\LIB\amd64 
               D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\ATLMFC\LIB\amd64 
               C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x64 
               D:\Program Files\MATLAB\R2013a\extern\lib\win64 
               D:\Program Files\MATLAB\R2013a\extern\lib\win64\microsoft 
               C:\opencv\build\x64\vc11\lib 

Warning: MEX could not find the library "cxcore" specified with -l option. 
         MEX looked for a file with one of the names: 
               cxcore.lib 
               libcxcore.lib 
         MEX looked for the library in the following directories: 
               D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\LIB\amd64 
               D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\ATLMFC\LIB\amd64 
               C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x64 
               D:\Program Files\MATLAB\R2013a\extern\lib\win64 
               D:\Program Files\MATLAB\R2013a\extern\lib\win64\microsoft 
               C:\opencv\build\x64\vc11\lib 

     Creating library C:\Users\AsUs\AppData\Local\Temp\mex_47j5SQ\templib.x and object C:\Users\AsUs\AppData\Local\Temp\mex_47j5SQ\templib.exp 
  me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvCreateImage referenced in function mexFunction 
  me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvReleaseImage referenced in function mexFunction 
  me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvCreateMemStorage referenced in function mexFunction 
  me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvReleaseMemStorage referenced in function mexFunction 
  me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvGetSeqElem referenced in function mexFunction 
  me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvLoad referenced in function mexFunction 
  me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvEqualizeHist referenced in function mexFunction 
  me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvReleaseHaarClassifierCascade referenced in function mexFunction 
  me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvHaarDetectObjects referenced in function mexFunction 
  me_HaarDetectOpenCV.mexw64 : fatal error LNK1120: 9 unresolved externals 

    D:\PROGRA~2\MATLAB\R2013A\BIN\MEX.PL: Error: Link of 'me_HaarDetectOpenCV.mexw64' failed. 

Error using mex (line 206)
Unable to complete successfully. 
>>

How do I fix the error and compile (create the MEX file me_HaarDetectOpenCV.mexw64)?


i'm edit me_HaarDetectOpenCV.Cpp and fix error .

#include "D:\Program Files\MATLAB\R2013a\extern\include\mex.h"
#include "C:\opencv\build\include\opencv\cv.h" 
#include "C:\opencv\build\include\opencv\highgui.h"
#include "C:\opencv\build\include\opencv\cxcore.h"

MEX command output:

>> mex me_HaarDetectOpenCV.cpp
   Creating library C:\Users\AsUs\AppData\Local\Temp\mex_7BQNq1\templib.x and object C:\Users\AsUs\AppData\Local\Temp\mex_7BQNq1\templib.exp 
me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvReleaseMemStorage referenced in function mexFunction 
me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvReleaseHaarClassifierCascade referenced in function mexFunction 
me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvReleaseImage referenced in function mexFunction 
me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvGetSeqElem referenced in function mexFunction 
me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvHaarDetectObjects referenced in function mexFunction 
me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvEqualizeHist referenced in function mexFunction 
me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvCreateMemStorage referenced in function mexFunction 
me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvCreateImage referenced in function mexFunction 
me_HaarDetectOpenCV.obj : error LNK2019: unresolved external symbol cvLoad referenced in function mexFunction 
me_HaarDetectOpenCV.mexw64 : fatal error LNK1120: 9 unresolved externals 

  D:\PROGRA~2\MATLAB\R2013A\BIN\MEX.PL: Error: Link of 'me_HaarDetectOpenCV.mexw64' failed. 

Error using mex (line 206)
Unable to complete successfully. 

Solution

  • As I mentioned in previous comments, your code is using the old C interface of OpenCV. It is preferred to use the newer C++ interface.

    Perhaps it is best to show a complete example. The code below runs face detecting using the Haar-based cascade classifier. I simplified it from your code a bit by removing some of the parameters parsing.

    If you want an easier wrapper for using OpenCV inside MATLAB, consider using mexopencv.

    faces.cpp

    #include "mex.h"
    #include <string>
    #include "opencv2/opencv.hpp"
    #include "opencv2/objdetect/objdetect.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    {
        // validate arguments
        if (nrhs < 2) {
            mexErrMsgTxt("Wrong number of input arguments.");
        }
        if (nlhs > 1) {
            mexErrMsgTxt("Too many output arguments.");
        }
        if (!mxIsChar(prhs[0]) || mxGetM(prhs[0])!=1) {
            mexErrMsgTxt("First argument must be a string.");
        }
        if (!mxIsUint8(prhs[1]) || mxGetNumberOfDimensions(prhs[0])!=2) {
            mexErrMsgTxt("Second argument must be a uint8 grayscale image.");
        }
    
        // get XML cascade file name
        char *xmlfile = mxArrayToString(prhs[0]);
        cv::CascadeClassifier cascade;
        if (!cascade.load(std::string(xmlfile))) {
            mexErrMsgTxt("Failed to load cascade classifier.");
        }
        mxFree(xmlfile);
    
        // get grayscale image
        mwSize nrows = mxGetM(prhs[1]);
        mwSize ncols = mxGetN(prhs[1]);
        uint8_T *data = reinterpret_cast<uint8_T*>(mxGetData(prhs[1]));
    
        // copy into an OpenCV mat (there are better ways to do this step!)
        cv::Mat img(nrows, ncols, CV_8UC1, cv::Scalar::all(0));
        for(mwIndex c=0; c<ncols; c++) {
            for(mwIndex r=0; r<nrows; r++) {
                img.at<char>(r,c) = data[r + nrows*c];
            }
        }
    
        // process image before detection
        cv::equalizeHist(img, img);
    
        // detect faces
        std::vector<cv::Rect> faces;
        cascade.detectMultiScale(img, faces, 1.1, 4, 0, cv::Size(30,30));
    
        // return rectangles found to MATLAB
        plhs[0] = mxCreateDoubleMatrix(4, faces.size(), mxREAL);
        double *out = mxGetPr(plhs[0]);
        for(mwIndex i=0; i<faces.size(); i++) {
            out[i+0] = static_cast<double>(faces[i].x);
            out[i+1] = static_cast<double>(faces[i].y);
            out[i+2] = static_cast<double>(faces[i].width);
            out[i+3] = static_cast<double>(faces[i].height);
        }
    }
    

    Assuming you have download OpenCV 2.4.7 and extracted it into C:\OpenCV (with sources and build sub-directories beneath it), run the following command to compile the code:

    mex -largeArrayDims -I'C:\OpenCV\build\include' -L'C:\OpenCV\build\x64\vc11\lib'
      -lopencv_core247 -lopencv_imgproc247 -lopencv_objdetect247 faces.cpp
    

    (adjust the libraries path above according to your compiler. I'm using VS2012)

    Next we test the MEX-function in MATLAB:

    % some grayscale face image
    img = imread('http://www.ece.rice.edu/~wakin/images/lena512.bmp');
    
    % detect face
    rect = faces('./haarcascade_frontalface_alt2.xml', img);
    
    % show result
    imshow(img)
    rectangle('Position',rect(:,1), 'LineWidth',4, 'EdgeColor','g')
    

    face_detected