OpenCV discovery and matching function - segfault on drawing matches

Following this example ,
I am trying to create an application for recognizing objects in a video.
My program consists of the following steps (see the sample code for each step below):

  • Read the image of the object to be recognized into the cv::Mat object.
  • Define key points in an object and compute descriptors.
  • Read every frame of the video,
  • Key point detection and frame descriptor calculation,
  • Match the frame descriptors with the object descriptors,
  • Draw the results.

Problem: The 6th step causes a segmentation error (see code below).
Question: What causes it and how to fix it?

Thanks!

Notes:

  • The program runs for several frames before segfault. The accident occurs at frame 23, which is the first frame of the video having any content (i.e., not completely black).
  • By removing the line drawMatches(...); will fail no .
  • Works on Windows 7, OpenCV 2.4.2, MinGW.

Debugging:

Running the program through gdb gives the following message:

 Program received signal SIGSEGV, Segmentation fault. 0x685585db in _fu156___ZNSs4_Rep20_S_empty_rep_storageE () from c:\opencv\build\install\bin\libopencv_features2d242.dll 

Step 1 - view the image of the object:

 Mat object; object = imread(OBJECT_FILE, CV_LOAD_IMAGE_GRAYSCALE); 

Step 2 - Detection of key points in the object and calculation descriptors:

 SurfFeatureDetector detector(500); SurfDescriptorExtractor extractor; vector<KeyPoint> keypoints_object; Mat descriptors_object; detector.detect(object , keypoints_object); extractor.compute(object, keypoints_object, descriptors_object); 

Steps 3-6:

 VideoCapture capture(VIDEO_FILE); namedWindow("Output",0); BFMatcher matcher(NORM_L2,true); vector<KeyPoint> keypoints_frame; vector<DMatch> matches; Mat frame, output, descriptors_frame; while (true) { //step 3: capture >> frame; if(frame.empty()) { break; } cvtColor(frame,frame,CV_RGB2GRAY); //step 4: detector.detect(frame, keypoints_frame); extractor.compute(frame, keypoints_frame, descriptors_frame); //step 5: matcher.match(descriptors_frame, descriptors_object, matches); //step 6: drawMatches(object, keypoints_object, frame, keypoints_frame, matches, output); imshow("Output", output); waitKey(1); } 

Screenshot before segfault: Screen shot

Frame 22 (completely black): Frame 22

Frame 23 (in which segfault occurs): Frame 23

+4
source share
2 answers

The problem was the order of the parameters in drawMatches .
The correct order is:

 drawMatches(frame, keypoints_frame, object, keypoints_object, matches, output); 

Explanation:

In step 5, I use the match method of the matcher object:

 matcher.match(descriptors_frame, descriptors_object, matches); 

Signature of this method

 void match( const Mat& queryDescriptors, const Mat& trainDescriptors, CV_OUT vector<DMatch>& matches, const Mat& mask=Mat() ) const; 

This means that matches contains matches from trainDescriptors to queryDescriptors .
In my case, the train descriptors have an object , and the request descriptors have a frame , so matches contains matches from object to frame .

Signature drawMatches is

 void drawMatches( const Mat& img1, const vector<KeyPoint>& keypoints1, const Mat& img2, const vector<KeyPoint>& keypoints2, const vector<DMatch>& matches1to2, ... ); 

When calling drawMatches with an invalid parameter:

 drawMatches(object, keypoints_object, frame, keypoints_frame, matches, output); 

the method looks for the coordinates of matches in the incorrect image, which may lead to an attempt to access pixels "outside the boundaries"; Therefore, segmentation error.

+5
source

Have you tried to run your program in the debugger?

Just guess drawmatch segfaulting when there are no matches for the draw ?? try adding if (!matches.empty()) before drawMatches . By the way, are you sure that matches empty before calling matcher.matches(...) ? If not, you must do this manually at each iteration of the loop.

0
source

Source: https://habr.com/ru/post/1441136/


All Articles