My MEX code crashes when I input a large image.

Hi,
I'm new to creating MEX functions and can't figure out what's going wrong. The code below matches the SURF features of two greyscale images and outputs the position of the matched features. It is based on an OpenCV Tutorial, but modified to use MEX inputs/outputs. I encounter no issues with smaller inputs but it crashes MATLAB when anything bigger than around 1000x1000 images are input.
I'm guessing, based on my research, that it has something to do with memory allocation but I don't know what I'm looking for to be able to fix it. Any help would be greatly appreciated.
Many thanks,
Jack
#include "opencvmex.hpp"
#include "mex.h"
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include <vector>
#include "opencv2/legacy/compat.hpp"
using namespace cv;
#define IMAGE_ARRAY_IN prhs[0]
#define TARGET_ARRAY_IN prhs[1]
#define POSITION_OUT plhs[0]
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
Ptr<Mat> image = ocvMxArrayToImage_uint8(IMAGE_ARRAY_IN, false);
Ptr<Mat> target = ocvMxArrayToImage_uint8(TARGET_ARRAY_IN, false);
// Get features for image
int minHessian = 400;
SurfFeatureDetector detector(minHessian);
std::vector<cv::KeyPoint> keypointsImage, keypointsTarget;
detector.detect(*image, keypointsImage);
detector.detect(*target, keypointsTarget);
// Calculate descriptors
SurfDescriptorExtractor extractor;
Mat descriptorsTarget, descriptorsImage;
extractor.compute( *target, keypointsTarget, descriptorsTarget );
extractor.compute( *image, keypointsImage, descriptorsImage );
// Match Descriptors
FlannBasedMatcher matcher;
std::vector< DMatch > matches;
matcher.match( descriptorsTarget, descriptorsImage, matches );
size_t numberOfMatches=matches.size();
// Get keypoints for matches only
std::vector<Point2f> targetPosition;
std::vector<Point2f> imagePosition;
std::vector<float> imageSize, imageAngle;
for( int i = 0; i < numberOfMatches; i++ )
{
targetPosition.push_back( keypointsTarget[ matches[i].queryIdx ].pt );
imagePosition.push_back ( keypointsImage [ matches[i].trainIdx ].pt );
imageSize.push_back ( keypointsImage [ matches[i].trainIdx ].size );
imageAngle.push_back ( keypointsImage [ matches[i].trainIdx ].angle );
}
// Output matched point location
std::vector<double> matchedPoints;
matchedPoints.resize(numberOfMatches,4);
size_t i;
POSITION_OUT = mxCreateNumericMatrix(numberOfMatches,4, mxDOUBLE_CLASS, mxREAL);
double *outputPointer=mxGetPr(POSITION_OUT);
for( i = 0; i < numberOfMatches; i++ )
{
float size, angle;
float xPosition, yPosition;
xPosition = imagePosition[i].x;
yPosition = imagePosition[i].y;
size = imageSize[i];
angle = imageAngle[i];
outputPointer[i] = xPosition;
outputPointer[i+numberOfMatches] = yPosition;
outputPointer[i+numberOfMatches*2] = size;
outputPointer[i+numberOfMatches*3] = angle;
}
}
UPDATE: I've managed to find the boundary between inputs that work and inputs that don't. If the feature detector finds more than 141 key points in either image, MATLAB crashes, otherwise it runs fine. The number of matches doesn't make a difference, and the total number of key points doesn't change anything, just if there are 142 or more key points detected in one of the images.
I've managed to botch it by changing the minimum hessian dynamically to keep the detected points below the magic number but obviously this isn't ideal: there's no guarantee the detected points will match if it's a busy image.

Answers (0)

Asked:

on 14 Apr 2016

Edited:

on 23 Apr 2016

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!