Strange memory exception (access violation) in running DBRIEF
Hi,
This isn't exactly related an existing OpenCV module, but I'm trying to run the DBREIF descriptor that is based on OpenCV. Unfortunately, the code uses the old C api.
Here's where I get the exception:
void Dbrief::getDbriefDescriptor(bitset<DESC_LEN>& desc, cv::KeyPoint kpt, IplImage* img)
{
// Calculate the width step of the boxSmoothedImage image
int inWS = boxSmoothedImage->step / CV_ELEM_SIZE(boxSmoothedImage->type);
// Hold the pointer of the data part of boxSmoothedImage image matrix with "iD"
float* iD = boxSmoothedImage->data.fl;
// Hold the pointer to the top left corner of the patch to be analysed
int X = kpt.pt.x - HALF_PATCH_SIZE,
Y = kpt.pt.y - HALF_PATCH_SIZE;
cv::Point2i point;
float result;
GET_MATRIX_DATA(iD, 488 + 32, 603 + 1, 765); /// HERE IS EXCEPTION
/***********************************************
Here's the function that calls this function:
void Dbrief::getDbriefDescriptors(vector< bitset<DESC_LEN> >& descriptors,
vector<cv::KeyPoint>& kpts,
IplImage* img)
{
// Make sure that input image contains only one color channel:
assert(img->nChannels == 1);
// Check whether all the keypoints are inside the subimage:
assert(validateKeypoints(kpts, img->width, img->height));
// If memory allocated in 'descriptors' is not enough, then resize it:
descriptors.resize(kpts.size());
// Allocate memory for the box smoothed image
allocateBoxSmoothedImage(img);
// Calculate the box smoothed image:
cvSmooth(img, boxSmoothedImage, CV_BLUR_NO_SCALE, KERNEL_SIZE, KERNEL_SIZE);
// Iterate over keypoints:
for (unsigned int i = 0; i < kpts.size(); ++i){
printf("%d\n", i);
getDbriefDescriptor(descriptors[i], kpts[i], img);
}
}
Now, in the first 24 times the function "getDbriefDescriptor(descriptors[i], kpts[i], img);" is called, there is no exception, only in the 24'th time. The size of boxSmoothedImage is width=765 and height = 512.
I'm stumped. Why an exception rises in the exact same command, only in the 24'th time the function is called? It has to do with something related to memory management, but I'm not sure what.
Any help will be greatly appreciated.
Thanks,
Gil
EDIT:
Thanks berak and Mathieu! you're the best.
Here is the original source code:
http://cvlab.epfl.ch/research/detect/dbrief
Now, originally, the source code is:
void Dbrief::getDbriefDescriptor(bitset<DESC_LEN>& desc, cv::KeyPoint kpt, IplImage* img)
{
// Calculate the width step of the boxSmoothedImage image
int inWS = boxSmoothedImage->step / CV_ELEM_SIZE(boxSmoothedImage->type);
// Hold the pointer of the data part of boxSmoothedImage image matrix with "iD"
float* iD = boxSmoothedImage->data.fl;
// Hold the pointer to the top left corner of the patch to be analysed
int X = kpt.pt.x - HALF_PATCH_SIZE,
Y = kpt.pt.y - HALF_PATCH_SIZE;
cv::Point2i point;
float result;
GET_MATRIX_DATA(iD, 488 + 32, 603 + 1, 765);
/***********************************************
Projection: 1
************************************************/
result = 0.f;
result += GET_MATRIX_DATA(iD, Y + 1, X + 1, inWS) * (0.16649845f);
result += GET_MATRIX_DATA(iD, Y + 32, X + 2, inWS) * (0.11555521f);
result += GET_MATRIX_DATA(iD, Y + 1, X + 3, inWS) * (0.07356358f);
followed by many lines of the form:
result += GET_MATRIX_DATA(iD, Y + 1, X + 3, inWS) * (0.07356358f);
with different parameters.
Now, I get an exception in the 24'th time the function "getDbriefDescriptor" is called (not the 24'th projection, the 24'th ...
Why the down vote?
I agree, it seems someone is doing down vote for no reason on many posts. (I've counter balance, but it's not ideal).
May I suggest to rewrite with the C++ API. It's straightforward here, and/or give us the implementation or details about GET_MATRIX_DATA, because values seems odd to me... ;-)
hi @Gil, maybe you need a bit more explanation and code here. e.g. the link to the src, mention that it's in the 24th projection , that those are of the form
GET_MATRIX_DATA(iD, Y+32,X+6, stride)
, your img size, etc.also i can't find any occurence of GET_MATRIX_DATA(iD, Y + 32, X + 1,inWS) in that section (or at all). could you clarify that part ?
Thanks guys, I'll respond when I'm at home and have the code in front of me.
i'm giving up on the demo code there. it does not crash here, but is leaking memory like hell
maybe it gets more usable in c++ ( well i tried that )
Thanks for the effort @berak. Does the C++ version that you wrote also leaks?
i hope not ;) (still working on that. trying to get rid of the bitsets in favour of a Mat that can be passed to bfmatcher)
I can't thank you enough @berak.
btw, I open a feature request and asked if the moderators will be willing to accept BinBoost without a "create" implementation. They still haven't answered. Also, I'm working on a blog post on rotated BRIEF. Once I'll get it done (including experiments) I'll ask someone to review it and help me make a pull request. Unfortunately, it will take some time as I have to work on my research.
i think, i found the overflow:,
looking at the drawing, a keypoint can be as far to the right (or bottom) as
HALF_KERNEL_SIZE + HALF_PATCH_SIZE
(which is 17) and then a [32,32] region to right/bottom is checked for the projections.. again, that's 15 too many.probably the whole subimage is wrong, better be HALF_KERNEL_SIZE to top/left and PATCH_SIZE to bottom/right.
and then, i played a bit with the code, trying to feed the extracted features to a BFMatcher, but results are poor. (they all cluster to the same first points) no idea why, maybe my unpacking logic is wrong. [on the other hand, the BFMatcher only sees 32bit features now, and there are indeed like 80% duplicates of the same thing]