Well, I changed the icvHoughlines function to go to a specific range of angles. I'm sure there are cleaner methods that also play with memory allocation, but I got a gain from 100 ms to 33 ms for an angle range of 180 to 60 degrees, so I'm happy with that.
Note that this code also displays the battery value. In addition, I only output 1 line, because it was consistent with my goals, but there was no gain.
static void icvHoughLinesStandard2( const CvMat* img, float rho, float theta, int threshold, CvSeq *lines, int linesMax ) { cv::AutoBuffer<int> _accum, _sort_buf; cv::AutoBuffer<float> _tabSin, _tabCos; const uchar* image; int step, width, height; int numangle, numrho; int total = 0; float ang; int r, n; int i, j; float irho = 1 / rho; double scale; CV_Assert( CV_IS_MAT(img) && CV_MAT_TYPE(img->type) == CV_8UC1 ); image = img->data.ptr; step = img->step; width = img->cols; height = img->rows; numangle = cvRound(CV_PI / theta); numrho = cvRound(((width + height) * 2 + 1) / rho); _accum.allocate((numangle+2) * (numrho+2)); _sort_buf.allocate(numangle * numrho); _tabSin.allocate(numangle); _tabCos.allocate(numangle); int *accum = _accum, *sort_buf = _sort_buf; float *tabSin = _tabSin, *tabCos = _tabCos; memset( accum, 0, sizeof(accum[0]) * (numangle+2) * (numrho+2) ); // find n and ang limits (in our case we want 60 to 120 float limit_min = 60.0/180.0*PI; float limit_max = 120.0/180.0*PI; //num_steps = (limit_max - limit_min)/theta; int start_n = floor(limit_min/theta); int stop_n = floor(limit_max/theta); for( ang = limit_min, n = start_n; n < stop_n; ang += theta, n++ ) { tabSin[n] = (float)(sin(ang) * irho); tabCos[n] = (float)(cos(ang) * irho); } // stage 1. fill accumulator for( i = 0; i < height; i++ ) for( j = 0; j < width; j++ ) { if( image[i * step + j] != 0 ) // for( n = start_n; n < stop_n; n++ ) { r = cvRound( j * tabCos[n] + i * tabSin[n] ); r += (numrho - 1) / 2; accum[(n+1) * (numrho+2) + r+1]++; } } int max_accum = 0; int max_ind = 0; for( r = 0; r < numrho; r++ ) { for( n = start_n; n < stop_n; n++ ) { int base = (n+1) * (numrho+2) + r+1; if (accum[base] > max_accum) { max_accum = accum[base]; max_ind = base; } } } CvLinePolar2 line; scale = 1./(numrho+2); int idx = max_ind; n = cvFloor(idx*scale) - 1; r = idx - (n+1)*(numrho+2) - 1; line.rho = (r - (numrho - 1)*0.5f) * rho; line.angle = n * theta; line.votes = accum[idx]; cvSeqPush( lines, &line ); }
Denis source share