Ask Your Question
0

EXC_BAD_ACCESS while Calculating Descriptor

asked 2016-10-05 02:46:44 -0600

Vintez gravatar image

updated 2016-10-05 03:18:04 -0600

I try to calculate a SIFT Descriptor out of KeyPoints found by the FAST Corner Detection. For that, I adapted some functions from the Sift.cpp and changed them so they can be used with FAST generated KeyPoints with nonmaxsuppression. While I try to calculate the Descriptor I get an EXC_BAD_ACCESS Error and I cant find the origin of this Error. I tried to make a example as small as possible of my code where the Error is generated with no constants or aliases. When you want to know more about the full code see my Git or look at this Question where already some things have been explained in the comments. You can get the Example Image with this Link Now the code:

#include <opencv2/opencv.hpp>
#include <opencv2/core/hal/hal.hpp>

using namespace cv;
int descriptorSize() {
    // Descr_Width * Descr_Width * Descr_hist_bins
    return 3*3*4;
}

static void calcSiftDescriptor( const Mat& img, Point2f ptf, float ori, float scl,
                           int d, int n, float* dst )
{
    Point pt(cvRound(ptf.x), cvRound(ptf.y));
    float cos_t = cosf(ori*(float)(CV_PI/180));
    float sin_t = sinf(ori*(float)(CV_PI/180));
    float bins_per_rad = n / 360.f;
    float exp_scale = -1.f/(d * d * 0.5f);
    // 3.f = Descr_scale_factor
    float hist_width = 3.f * scl;
    int radius = cvRound(hist_width * 1.4142135623730951f * (d + 1) * 0.5f);
    // Clip the radius to the diagonal of the image to avoid autobuffer too large exception
    radius = std::min(radius, (int) sqrt(((double) img.cols)*img.cols + ((double) img.rows)*img.rows));
    cos_t /= hist_width;
    sin_t /= hist_width;

    int i, j, k, len = (radius*2+1)*(radius*2+1), histlen = (d+2)*(d+2)*(n+2);
    int rows = img.rows, cols = img.cols;

    AutoBuffer<float> buf(len*6 + histlen);
    float *X = buf, *Y = X + len, *Mag = Y, *Ori = Mag + len, *W = Ori + len;
    float *RBin = W + len, *CBin = RBin + len, *hist = CBin + len;

    for( i = 0; i < d+2; i++ )
    {
        for( j = 0; j < d+2; j++ )
            for( k = 0; k < n+2; k++ )
                hist[(i*(d+2) + j)*(n+2) + k] = 0.;
    }

    for( i = -radius, k = 0; i <= radius; i++ )
        for( j = -radius; j <= radius; j++ )
        {
            // Calculate sample's histogram array coords rotated relative to ori.
            // Subtract 0.5 so samples that fall e.g. in the center of row 1 (i.e.
            // r_rot = 1.5) have full weight placed in row 1 after interpolation.
            float c_rot = j * cos_t - i * sin_t;
            float r_rot = j * sin_t + i * cos_t;
            float rbin = r_rot + d/2 - 0.5f;
            float cbin = c_rot + d/2 - 0.5f;
            int r = pt.y + i, c = pt.x + j;

            if( rbin > -1 && rbin < d && cbin > -1 && cbin < d &&
               r > 0 && r < rows - 1 && c > 0 && c < cols - 1 )
            {
                float dx = (float)(img.at<float>(r, c+1) - img.at<float>(r, c-1));
                float dy = (float)(img.at<float>(r-1, c) - img.at<float>(r+1, c));
                X[k] = dx; Y[k] = dy; RBin[k] = rbin; CBin[k] = cbin;
                W[k] = (c_rot * c_rot + r_rot * r_rot)*exp_scale;
                k++;
            }
        }

    len = k;
    cv::hal::fastAtan2(Y, X, Ori ...
(more)
edit retag flag offensive close merge delete

Comments

can we have your image, too ?

-2147483648 = 0x80000000 (which looks more like some "mark this invalid", than a number)

are you able to debug it ?

berak gravatar imageberak ( 2016-10-05 03:12:49 -0600 )edit
1

Totally forgot the Image Sorry. I uploaded it here I can run my Example in XCode and get the Error at line 111 hist[idx] += v_rco000; like before in the big Project.

Vintez gravatar imageVintez ( 2016-10-05 03:17:27 -0600 )edit

ok, i can reproduce it, v_rco000 is NaN at idx=88

(win10, x64, mingw64)

berak gravatar imageberak ( 2016-10-05 03:51:24 -0600 )edit

Checked that Again. One step before I get the Error, I also have, that all Values of v_[...] are NaN at idx = 15 the variable o0 = 3. After that, again all values are NaN and i have the out of bounds idx occuring because o0 is also out of bounds. So the Error should be because of the Calculation of Mag, Ori, X and Y?

Vintez gravatar imageVintez ( 2016-10-05 04:03:54 -0600 )edit

CV_Assert( ! cvIsNaN(mag) ); <-- i guess, you'll need a lot of similar assertions, and slowly work your way up the call stack

berak gravatar imageberak ( 2016-10-05 04:18:17 -0600 )edit

ok, I'll try that, but I'm not very familiar with Assertions. Should I set that after The loop where mag is filled? And similar assertions I think you mean, that I try that also with the other Pointers?

Vintez gravatar imageVintez ( 2016-10-05 04:22:25 -0600 )edit

in my case, float mag = Mag[k]*W[k]; is already NaN. so you need to check Mag and W

yes, try some other vars, too !

berak gravatar imageberak ( 2016-10-05 04:26:06 -0600 )edit

So after setting the Assertion I see that mag = NaN when k = 8. After that I testet which one of the two Matrix variables is NaN which is Mag[k]. Even Ori[k] does not throw a Assertion Error before that code. So it seems, that Mag is the problem then?

Vintez gravatar imageVintez ( 2016-10-05 04:42:14 -0600 )edit

Also set Assertions at the calculation of dx and dy now. Both also throw a Assertion dy = NaN Where c = 363 and r = 103 and dx = NaN where c = 362and r=103 normally, both are still in the Image bounds which are 724x724 so I don't have a clue, why they are NaN in addition, they both dont seem to throw the Assertion at the Point where Mag would be NaN.

Vintez gravatar imageVintez ( 2016-10-05 05:22:31 -0600 )edit

just to cheer you up in the meantime: image description

berak gravatar imageberak ( 2016-10-05 05:34:20 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2016-10-06 03:28:32 -0600

berak gravatar image

lo, i found it !

playing with this other NaN candidate, hehe , and looking at your remarks about trying to change the types, i found, that you access the image in calcSiftDescriptor ~L57 as : img.at<float>(r, c+1) .

dang ! it's still uchar (output from GaussianBlur) , not float !

so, just insert a tmp.convertTo(tmp, CV_32F); after the resize() in main() (also, more prec. for the blur), and all the NaN's are gone !

you've simply introduced a buffer overrun due to wrong image access, which caused those ;)

edit flag offensive delete link more

Comments

Wow... ;) so the only problem all the way was, that I tried to access a uchar image? did it even work with the image pick method? or Sobel? I will try that immediantly

Vintez gravatar imageVintez ( 2016-10-06 03:32:03 -0600 )edit

sorry, did neither try the picking or the sobel ;(

berak gravatar imageberak ( 2016-10-06 03:38:55 -0600 )edit

i'll try then no Problem :D Trying with picking I get really strange Angles from my first method calcHistOrientation (all in the area around e+33!) :x Same Thing also with Sobel (not as extremly high as picking but still far too high) Which results in getting a angle for the Descriptor calculation e.g. -1.63692521E+31 so either my angle Calculation seems to make a mistake, or its not the solution! But I'm still totally thankful for the Idea, because the varibales dx, dy, Ori, Mag and W are never NaN as it seems. Probably I should post another Question with the Angle Calculation to check if sth. is wrong there... ;P

Vintez gravatar imageVintez ( 2016-10-06 03:40:17 -0600 )edit
1

Well I found sth. in the Sift.cppgray.convertTo(gray_fpt, DataType<sift_wt>::type, SIFT_FIXPT_SCALE, 0); the mat gray in this case, is always a Grayscale Image at this point. Probably If I do the same my first solution will work. So probably your Idea was right in some way. tested it now and it looks very fine. I still get huge angles but no NaN I think this Question is solved ;)

Vintez gravatar imageVintez ( 2016-10-06 05:04:50 -0600 )edit

Hey @berak, I got one Question now, when I convert the Image before I search the Feature Candidates with the FAST detector, could it be, that I get a false List of candidates from FAST? Fast needs a Greyscale Image or not? e.g. before Conversion, I set a vector of integer values which always produce around 300 candidates of a Image. After I added the Conversion I get around 20000 candidates with the same threshold. Is that okay? or could it be that FAST Detects wrong candidates there?

Vintez gravatar imageVintez ( 2016-10-07 03:12:24 -0600 )edit

sorry, but i got no idea, how FAST works, can't really help here ;(

  • grayscale -- i'd think so, too.
  • threshold -- iirc, FAST does not have some kp properties, so some default values are taken.
berak gravatar imageberak ( 2016-10-07 03:15:25 -0600 )edit

So when I convert it into sth like this: gray.convertTo(gray_fpt, DataType<sift_wt>::type, SIFT_FIXPT_SCALE, 0); before the FAST Detection its not rly a grayscale anymore or not? So it probably detects wrong candidates. e.g. the threshold I took (FAST(img, candidates, thresh, true); was 44 and I got ~300 as aspected. But now with the conversion before that I get ~20000 to get ~300 again I need a threshold of 185. The Reason I ask is, I want to be sure, that I can still use the Detector now, because If I convert the Image after detection I strangely get a Assertion in the Descriptor calculation because Mag[k] = NaN again.

Vintez gravatar imageVintez ( 2016-10-07 03:27:43 -0600 )edit
berak gravatar imageberak ( 2016-10-07 03:31:30 -0600 )edit

So as I see it now then, I have to convert the Image After finding the candidates...?

Vintez gravatar imageVintez ( 2016-10-07 03:38:34 -0600 )edit

to extract features then ? i'd guess so.

berak gravatar imageberak ( 2016-10-07 03:42:41 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-10-05 02:46:44 -0600

Seen: 421 times

Last updated: Oct 06 '16