Eh bien, j'ai modifié la fonction icvHoughlines
pour obtenir une certaine gamme d'angles. Je suis sûr qu'il y a des manières plus propres qui jouent aussi avec l'allocation de mémoire, mais j'ai obtenu un gain de vitesse allant de 100ms à 33ms pour un angle allant de 180deg à 60deg, donc je suis content de ça.
Remarque Notez que ce code fournit également la valeur de l'accumulateur. En outre, je ne produis que 1 ligne parce que cela correspond à mes objectifs, mais il n'y avait pas de gain vraiment là.
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);
}