Reputation: 3170
Following this example,
I'm trying to build an application to recognize objects in a video.
My program is composed of the following steps (see code sample of each step below):
cv::Mat
object.Problem: The 6'th step causes a segmentation fault (see code below).
Question: What causes it, and how can I fix it?
Thank you!
Notes:
drawMatches(...);
there is no crash.Debuggind attempt:
Running the program through gdb yields 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 - reading object's image:
Mat object;
object = imread(OBJECT_FILE, CV_LOAD_IMAGE_GRAYSCALE);
Step 2 - Detecting keypoints in the object and computing 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 just before the segfault:
Frame 22 (completely black):
Frame 23 (in which the segfault occurs):
Upvotes: 4
Views: 4455
Reputation: 3170
The problem was with 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'm using the match
method of the matcher
object:
matcher.match(descriptors_frame, descriptors_object, matches);
The signature of this method is
void match( const Mat& queryDescriptors, const Mat& trainDescriptors,
CV_OUT vector<DMatch>& matches, const Mat& mask=Mat() ) const;
Which means that matches
contains matches from trainDescriptors
to queryDescriptors
.
In my case, the train descriptors are of the object
and the query descriptors are of the frame
, so matches
contains matches from the object
to the frame
.
The signature of 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 the incorrect order of parameters:
drawMatches(object, keypoints_object, frame, keypoints_frame, matches, output);
the method looks for the coordinates of matches in the incorrect image, which might result in trying to access "out-of-bounds" pixels; Thus the segmentation fault.
Upvotes: 5
Reputation: 3988
Have you tried running your prog in a debugger?
Just a guess, drawmatch is segfaulting when there are no matches to draw?? try adding if (!matches.empty())
before drawMatches
. By the way, are you sure matches
is emptied before calling matcher.matches(...)
? If not you should do it manually at each loop iteration.
Upvotes: 0