Search code examples
c++opencvld

Collect2 ld error when compiling program with openCV


When compiling a program with opencv2, I'm getting a weird compiler error with ld. I'm unable to find anything online to do with the error.

I'm using this command to compile the program

g++ -Wall Tracker.cpp -o Tracker

and I'm getting this output from the compiler

Tracker.cpp: In function ‘int main(int, char**)’:
Tracker.cpp:60:10: warning: unused variable ‘ok’ [-Wunused-variable]
   60 |     bool ok = video.read(frame);
      |          ^~
/usr/bin/ld: /tmp/cc2Q6W8D.o: in function `main':
Tracker.cpp:(.text+0x29d): undefined reference to `cv::VideoCapture::VideoCapture(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)'
/usr/bin/ld: Tracker.cpp:(.text+0x2ca): undefined reference to `cv::VideoCapture::isOpened() const'
/usr/bin/ld: Tracker.cpp:(.text+0x34a): undefined reference to `cv::VideoCapture::read(cv::_OutputArray const&)'
/usr/bin/ld: Tracker.cpp:(.text+0x425): undefined reference to `cv::rectangle(cv::_InputOutputArray const&, cv::Rect_<int>, cv::Scalar_<double> const&, int, int, int)'
/usr/bin/ld: Tracker.cpp:(.text+0x492): undefined reference to `cv::imshow(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cv::_InputArray const&)'
/usr/bin/ld: Tracker.cpp:(.text+0x503): undefined reference to `cv::Tracker::init(cv::_InputArray const&, cv::Rect_<double> const&)'
/usr/bin/ld: Tracker.cpp:(.text+0x544): undefined reference to `cv::VideoCapture::read(cv::_OutputArray const&)'
/usr/bin/ld: Tracker.cpp:(.text+0x562): undefined reference to `cv::getTickCount()'
/usr/bin/ld: Tracker.cpp:(.text+0x5b3): undefined reference to `cv::Tracker::update(cv::_InputArray const&, cv::Rect_<double>&)'
/usr/bin/ld: Tracker.cpp:(.text+0x5cd): undefined reference to `cv::getTickFrequency()'
/usr/bin/ld: Tracker.cpp:(.text+0x5da): undefined reference to `cv::getTickCount()'
/usr/bin/ld: Tracker.cpp:(.text+0x697): undefined reference to `cv::rectangle(cv::_InputOutputArray const&, cv::Rect_<int>, cv::Scalar_<double> const&, int, int, int)'
/usr/bin/ld: Tracker.cpp:(.text+0x772): undefined reference to `cv::putText(cv::_InputOutputArray const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cv::Point_<int>, int, double, cv::Scalar_<double>, int, int, bool)'
/usr/bin/ld: Tracker.cpp:(.text+0x86e): undefined reference to `cv::putText(cv::_InputOutputArray const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cv::Point_<int>, int, double, cv::Scalar_<double>, int, int, bool)'
/usr/bin/ld: Tracker.cpp:(.text+0x9ab): undefined reference to `cv::putText(cv::_InputOutputArray const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cv::Point_<int>, int, double, cv::Scalar_<double>, int, int, bool)'
/usr/bin/ld: Tracker.cpp:(.text+0xa49): undefined reference to `cv::imshow(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cv::_InputArray const&)'
/usr/bin/ld: Tracker.cpp:(.text+0xa80): undefined reference to `cv::waitKey(int)'
/usr/bin/ld: Tracker.cpp:(.text+0xab8): undefined reference to `cv::VideoCapture::~VideoCapture()'
/usr/bin/ld: Tracker.cpp:(.text+0xe35): undefined reference to `cv::VideoCapture::~VideoCapture()'
/usr/bin/ld: /tmp/cc2Q6W8D.o: in function `cv::Mat::~Mat()':
Tracker.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x39): undefined reference to `cv::fastFree(void*)'
/usr/bin/ld: /tmp/cc2Q6W8D.o: in function `cv::Mat::release()':
Tracker.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x4b): undefined reference to `cv::Mat::deallocate()'
collect2: error: ld returned 1 exit status

Tracker.cpp

#include <opencv2/opencv.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/core/ocl.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;
using namespace std;

// Convert to string
#define SSTR( x ) static_cast< std::ostringstream & >(( std::ostringstream() << std::dec << x )).str()

int main(int argc, char **argv)
{
    // List of tracker types in OpenCV 3.4.1
    string trackerTypes[8] = {"BOOSTING", "MIL", "KCF", "TLD","MEDIANFLOW", "GOTURN", "MOSSE", "CSRT"};
    // vector <string> trackerTypes(types, std::end(types));

    // Create a tracker
    string trackerType = trackerTypes[2];

    Ptr<Tracker> tracker;

    #if (CV_MINOR_VERSION < 3)
    {
     // tracker = Tracker::create(trackerType);
    }
    #else
    {
        if (trackerType == "BOOSTING")
            tracker = TrackerBoosting::create();
        if (trackerType == "MIL")
            tracker = TrackerMIL::create();
        if (trackerType == "KCF")
            tracker = TrackerKCF::create();
        if (trackerType == "TLD")
            tracker = TrackerTLD::create();
        if (trackerType == "MEDIANFLOW")
            tracker = TrackerMedianFlow::create();
        if (trackerType == "GOTURN")
            tracker = TrackerGOTURN::create();
        if (trackerType == "MOSSE")
            tracker = TrackerMOSSE::create();
        if (trackerType == "CSRT")
            tracker = TrackerCSRT::create();
    }
    #endif
    // Read video
    VideoCapture video("videos/test.mp4");

    // Exit if video is not opened
    if(!video.isOpened())
    {
        cout << "Could not read video file" << endl; 
        return 1; 
    } 

    // Read first frame 
    Mat frame; 
    bool ok = video.read(frame); 

    // Define initial bounding box 
    Rect2d bbox(287, 23, 86, 320); 

    // Uncomment the line below to select a different bounding box 
    //bbox = selectROI(frame, false); 
    // Display bounding box. 
    rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 ); 

    imshow("Tracking", frame); 
    tracker->init(frame, bbox);

    while(video.read(frame))
    {     
        // Start timer
        double timer = (double)getTickCount();

        // Update the tracking result
        bool ok = tracker->update(frame, bbox);

        // Calculate Frames per second (FPS)
        float fps = getTickFrequency() / ((double)getTickCount() - timer);

        if (ok)
        {
            // Tracking success : Draw the tracked object
            rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );
        }
        else
        {
            // Tracking failure detected.
            putText(frame, "Tracking failure detected", Point(100,80), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0,0,255),2);
        }

        // Display tracker type on frame
        putText(frame, trackerType + " Tracker", Point(100,20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50,170,50),2);

        // Display FPS on frame
        putText(frame, "FPS : " + SSTR(int(fps)), Point(100,50), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50,170,50), 2);

        // Display frame.
        imshow("Tracking", frame);

        // Exit if ESC pressed.
        int k = waitKey(1);
        if(k == 27)
        {
            break;
        }

    }
}

I've never seen this sort of error before and i'm not sure what's causing it, any help would be great.


Solution

  • Looks like you forgot to link, maybe something like:

    g++ -Wall Tracker.cpp -o Tracker -lopencv_core -lopencv_imgproc -lopencv_dnn -lopencv_highgui
    

    You might have to add -lopencv_videoio as well depending on version