OpenCV Error: Assertion failed

asked 2019-03-04 01:53:06 -0500

Farid gravatar image

updated 2019-03-04 02:20:55 -0500

berak gravatar image

Hi, I am trying to insert two images in one window to visualize and extract ORB features accordingly. This is the error I get when I run the program:

OpenCV Error: Assertion failed (key_ != -1 && "Can't fetch data from terminated TLS container.") in getData, file /tmp/binarydeb/ros-kinetic-opencv3-3.3.1/modules/core/src/system.cpp, line 1532
terminate called after throwing an instance of 'cv::Exception'
  what():  /tmp/binarydeb/ros-kinetic-opencv3-3.3.1/modules/core/src/system.cpp:1532: error: (-215) key_ != -1 && "Can't fetch data from terminated TLS container." in function getData

Aborted (core dumped)

This is also a piece of my code written in c++:

void FrameDrawer::DrawFrame(Mat &img_1, int f_k, Mat &img_2, int f_k_plus_1 , float mT)
{   
    const string &frameWinName = "ORB_VISLAM | Frames";
    namedWindow(frameWinName);

    if (img_1.empty())
    {
        cout << "img_1 empty! => BLANK!" << endl;
        img_1 = Mat::zeros(img_2.rows,img_2.cols, CV_8UC3);
    }
    if (img_2.empty())
    {
        cout << "img_2 empty! => STOP!" << endl;
        //img_1 = Mat::zeros(img_2.rows,img_2.cols, CV_8UC3);
        exit(EXIT_FAILURE);
    }

    if (f_k == f_k_plus_1)
    {
        return;
    }   
    float scale = .4;
    // img1:
    int w1,h1;
    int w1_scaled, h1_scaled;
    w1 = img_1.cols;
    h1 = img_1.rows;

    w1_scaled = w1*scale;
    h1_scaled = h1*scale;

    // img2:
    int w2,h2;
    int w2_scaled, h2_scaled;
    w2 = img_2.cols;
    h2 = img_2.rows;

    w2_scaled = w2*scale;
    h2_scaled = h2*scale;

    // MULTIPLE WINDOW:
    Mat window_img = Mat::zeros(cv::Size(w1_scaled+w2_scaled, h1_scaled), CV_8UC3);

    Mat temp1;
    Mat temp2;
    vector<cv::KeyPoint> vIniKeys; // Initialization: KeyPoints in reference frame
    vector<int> vMatches; // Initialization: correspondeces with reference keypoints

    vector<cv::KeyPoint> vCurrentKeys; // KeyPoints in current frame
    vector<bool> vbVO, vbMap; // Tracked MapPoints in current frame
    int state; // Tracking state

    //Copy variables within scoped mutex
    {
        unique_lock<mutex> lock(mMutex);
        state = mState;

        if(mState==Tracking::SYSTEM_NOT_READY)
        {
            mState=Tracking::NO_IMAGES_YET;
        }    

        if(mState==Tracking::NOT_INITIALIZED)
        {
            vCurrentKeys = mvCurrentKeys;
            vIniKeys = mvIniKeys;
            vMatches = mvIniMatches;
        }
        else if(mState==Tracking::OK)
        {
            vCurrentKeys = mvCurrentKeys;
            vbVO = mvbVO;
            vbMap = mvbMap;
        }
        else if(mState==Tracking::LOST)
        {
            vCurrentKeys = mvCurrentKeys;
        }
    } // destroy scoped mutex -> release mutex

    if(img_1.channels()<3) //this should be always true
    {
        cvtColor(img_1,img_1,CV_GRAY2BGR);
    }

    if(img_2.channels()<3) //this should be always true
    {
        cvtColor(img_2,img_2,CV_GRAY2BGR);
    }
    //Draw
    if(state==Tracking::NOT_INITIALIZED) //INITIALIZING
    {
        Point2f p_i1(1000,100);
        cv::circle(img_1,p_i1,20,Scalar(0,10,255),LINE_4);
        stringstream s_i1;
        //cout << "idx = " << f_idx<< endl;
        s_i1 << "Reference Frame = "+to_string(f_k);

        cv::putText(img_1,s_i1.str(),cv::Point(80,50),
                    cv::FONT_HERSHEY_PLAIN, 3, Scalar::all(255),4,LINE_4);
        // current keyP on img_2:
        Point2f p_i2(1000,500);
        cv::circle(img_2,p_i2,20,Scalar::all(255),LINE_4);
        stringstream s_i2;
        //cout << "idx = " << f_idx<< endl;
        s_i2 << "Current Frame = "+to_string(f_k_plus_1);

        cv::putText(img_2,s_i2.str(),cv::Point(80,50),
                    cv::FONT_HERSHEY_PLAIN, 3, Scalar::all(255),4,LINE_4);
        for(unsigned int i = 0; i < vMatches.size(); i++)
        {
            if(vMatches[i] >= 0)
            {
                //cv::line(im,vIniKeys[i].pt,vCurrentKeys[vMatches[i]].pt, Scalar(0,250,250));
                cv::circle(img_1,vIniKeys[i].pt,6,Scalar::all(255),LINE_4);
                //cv::circle(im,vCurrentKeys[vMatches[i]].pt,4,Scalar(170,1,1),LINE_4);
                cv::circle(img_2,vCurrentKeys[i].pt ...
(more)
edit retag flag offensive close merge delete

Comments

uhmm, is this about multithreading ?

berak gravatar imageberak ( 2019-03-04 01:57:05 -0500 )edit
1

Yes, but I do not insert two images in one window with threads. In my case, threads are meant for purposes such as Tracking, Mapping and Loop Closing in SLAM problem. To be more specific, my ORB SLAM algorithm detects and visualize ORB features in current frames. What I am interested to do, however, is to have reference frame on the left side, current frame on the right side and show the matches in a newly created window containing both frames with lines.

Farid gravatar imageFarid ( 2019-03-04 02:06:31 -0500 )edit
1

unfortunately, it's not only a lot of code, but also there's a lot of code (and all context) missing here.

can you try to come up with a minimal, reproducable example here (that we actually can run & test) ?

berak gravatar imageberak ( 2019-03-04 02:06:40 -0500 )edit
1

get rid of the multithreading, first.

at least, all of the gui code (namedWindow(), imshow(), wairtKey(), etc) ABSOLUTELY HAS TO STAY ON THE MAIN THREAD

berak gravatar imageberak ( 2019-03-04 02:07:24 -0500 )edit