iOS OpenCV: Image matching with ORB leads to EXC_BAD_ACCESS

asked 2019-08-08 08:07:00 -0600

Airlenbauer gravatar image

I'm fairly new to OpenCV and I'm trying to match images from the camera feed with provided descriptors for the images that shall be matched. However my Objective-C++ code currently crashes with EXC_BAD_ACCESS which leads me to believe that something has been released or is not present. I just can't quite find the culprit.

I'm using OpenCV 4.1.1 for iOS, Xcode 10.3 and iOS 12.4

I'm using Objective-C++ to speak to OpenCV and and Swift for all UI related things and the rest.

So here's what I've done so far.

I've set up the included CvVideoCamera and the camera image is displayed fine inside an UIImageView. (since this works fine with simple template matching I'll spare you with that code)

In my OpenCVWrapper.mm which is also the CvVideoCamera's delegate I do the following in processImage:(cv::Mat&)image;

CV_Assert(!image.empty());
cv::ORB *orb = cv::ORB::create();
cv::Mat descriptors, mask;
std::vector<cv::KeyPoint> points;
CV_Assert(!orb->empty());
orb->detectAndCompute(image, mask, points, descriptors);
cv::DescriptorMatcher *matcher = cv::DescriptorMatcher::create(cv::BFMatcher::BRUTEFORCE) ;
std::vector<std::vector<cv::DMatch>> knnMatches;
NSArray *targetDescriptors = [[self delegate] descriptors];
for (SourceDescriptor *source in targetDescriptors) {
    matcher->knnMatch(descriptors, source.mat.mat, knnMatches, 2);
    float ratioThreshold = 0.f;
    NSMutableArray *innerDistances = [@[] mutableCopy];
    for (NSInteger counter = 0; counter < knnMatches.size(); counter++) {
        const cv::DMatch& bestMatch = knnMatches[counter][0];
        const cv::DMatch& betterMatch = knnMatches[counter][1];
        float finalDistance = bestMatch.distance / betterMatch.distance;
        if (finalDistance <= ratioThreshold) {
            [innerDistances addObject:[NSNumber numberWithFloat:finalDistance]];
        }
    }
    if ([innerDistances count] > 0) {
        NSSortDescriptor *highestToLowest = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:NO];
        [innerDistances sortUsingDescriptors:[NSArray arrayWithObject:highestToLowest]];
        Result *leresult = [[Result alloc] init];
        NSNumber *score = (NSNumber *)[innerDistances objectAtIndex:0];
        [leresult setScore:[score floatValue]];
        [leresult setSourceDescriptor:source];
        [result addObject:leresult];
    }
}

My code however crashes at orb->detectAndCompute() with an EXC_BAD_ACCESS

As you can see from the code I'm checking whether the orb or image are empty which isn't the case.

Any help would be greatly appreciated. If any more information needs to be provided I will gladly do so.

edit retag flag offensive close merge delete

Comments

I'm facing same issue, did you finally solve that? I'm use OpenCV 4.3 ... but I'm not sure if contrib is required for detectAndCompute.

vitto32 gravatar imagevitto32 ( 2020-04-10 03:17:41 -0600 )edit

I found the culprit. cv::ORB *orb = cv::ORB::create();

should be cv::Ptr<cv::ORB> orb = cv::ORB::create();

otherwise the pointer is deallocated too soon.

vitto32 gravatar imagevitto32 ( 2020-04-10 10:03:54 -0600 )edit