Quantcast
Channel: OpenCV Q&A Forum - Latest question feed
Viewing all articles
Browse latest Browse all 19555

EXC_BAD_ACCESS while Calculating Descriptor

$
0
0
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](https://github.com/opencv/opencv_contrib/blob/master/modules/xfeatures2d/src/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](https://github.com/vincentthe0ne/Testproject) or look at this [Question](http://answers.opencv.org/question/103562/no-member-getmat/) where already some things have been explained in the comments. You can get the Example Image with this [Link](http://imgur.com/a/YXEEh) Now the code: #include #include 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 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(r, c+1) - img.at(r, c-1)); float dy = (float)(img.at(r-1, c) - img.at(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, len, true); cv::hal::magnitude32f(X, Y, Mag, len); cv::hal::exp32f(W, W, len); for( k = 0; k < len; k++ ) { float rbin = RBin[k], cbin = CBin[k]; float obin = (Ori[k] - ori)*bins_per_rad; float mag = Mag[k]*W[k]; int r0 = cvFloor( rbin ); int c0 = cvFloor( cbin ); int o0 = cvFloor( obin ); rbin -= r0; cbin -= c0; obin -= o0; if( o0 < 0 ) o0 += n; if( o0 >= n ) o0 -= n; // histogram update using tri-linear interpolation float v_r1 = mag*rbin, v_r0 = mag - v_r1; float v_rc11 = v_r1*cbin, v_rc10 = v_r1 - v_rc11; float v_rc01 = v_r0*cbin, v_rc00 = v_r0 - v_rc01; float v_rco111 = v_rc11*obin, v_rco110 = v_rc11 - v_rco111; float v_rco101 = v_rc10*obin, v_rco100 = v_rc10 - v_rco101; float v_rco011 = v_rc01*obin, v_rco010 = v_rc01 - v_rco011; float v_rco001 = v_rc00*obin, v_rco000 = v_rc00 - v_rco001; int idx = ((r0+1)*(d+2) + c0+1)*(n+2) + o0; hist[idx] += v_rco000; //EXC_BAD_ACCESS here hist[idx+1] += v_rco001; hist[idx+(n+2)] += v_rco010; hist[idx+(n+3)] += v_rco011; hist[idx+(d+2)*(n+2)] += v_rco100; hist[idx+(d+2)*(n+2)+1] += v_rco101; hist[idx+(d+3)*(n+2)] += v_rco110; hist[idx+(d+3)*(n+2)+1] += v_rco111; } // finalize histogram, since the orientation histograms are circular for( i = 0; i < d; i++ ) for( j = 0; j < d; j++ ) { int idx = ((i+1)*(d+2) + (j+1))*(n+2); hist[idx] += hist[idx+n]; hist[idx+1] += hist[idx+n+1]; for( k = 0; k < n; k++ ) dst[(i*d + j)*n + k] = hist[idx+k]; } // copy histogram to the descriptor, // apply hysteresis thresholding // and scale the result, so that it can be easily converted // to byte array float nrm2 = 0; len = d*d*n; for( k = 0; k < len; k++ ) nrm2 += dst[k]*dst[k]; //0.2f = Descriptor Mag Threshold float thr = std::sqrt(nrm2)*0.2f; for( i = 0, nrm2 = 0; i < k; i++ ) { float val = std::min(dst[i], thr); dst[i] = val; nrm2 += val*val; } //512.f = Factor to convert floating point descriptor to uchar nrm2 = 512.f/std::max(std::sqrt(nrm2), FLT_EPSILON); for( k = 0; k < len; k++ ) { dst[k] = saturate_cast(dst[k]*nrm2); } } Mat src, gry, dst, tmp; int main(int argc, const char * argv[]) { Point2f pt(351, 119); float ori = 2.97183228; String imgName("/users/mtuchner/desktop/test/test/example.jpg"); src = imread(imgName); cvtColor(src, gry, CV_BGR2GRAY); int rows = gry.rows/sqrt(2); int cols = gry.cols/sqrt(2); resize(gry, tmp, Size(rows, cols), 0, 0, INTER_NEAREST); GaussianBlur(tmp, dst, Size(5,5), 0, 0); //Detection of keypoints here. Normally in a Loop where the Image is always made //smaler until the Size of the found Features is < 100. int dsize = descriptorSize(); // 489 = Number of all Features found in the Detection. Mat descriptors(489, dsize, CV_32F); int i = 3; // 3.5 is the size normally calculated from the keyPoint size, // 3 is the Descriptor width and 4 the Bins in the Descriptor Histogram calcSiftDescriptor(dst, pt, ori, 3.5, 3, 4, descriptors.ptr((int)i)); return 0; } The Value of Idx is in this case totally strange. (-2147483648) The Origin could be the Orientation Matrix `Ori` which results out of the function `hal::fastAtan2` the value of `Y[k] = NaN` which normally shouldn't be because the corresponding grab for `dy`is still in the Image and not out of bounds.

Viewing all articles
Browse latest Browse all 19555

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>