OpenCV Error: Assertion failed
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 ...
uhmm, is this about multithreading ?
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
andLoop 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.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) ?
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
Did you solved this error?, if yes then please comment how?