У меня есть точки на изображении. Мне нужно обнаружить самые коллинеарные точки. Самый быстрый способ — использовать преобразование Хафа, но мне нужно изменить метод opencv. На самом деле мне нужно, чтобы полуколлинеарные точки возвращались с обнаруженной линией, поэтому я изменил структуру полярной линии. Порог допуска также необходим для обнаружения почти обнаруженных точек, как показано на рисунке. Может кто-нибудь помочь в том, как настроить этот порог?
Мне нужно как минимум четыре полуколлинеарных точки, чтобы определить линию, к которой они принадлежат.
Точки первого изображения были обнаружены 6 перекрывающимися линиями
точка средних изображений ничем не обнаружена
Какой самый лучший способ избавиться от перекрытия залогового удержания ?? Или как настроить порог допуска для обнаружения полуколлинеарных точек только одной линией?
это мой собственный вызов функции:
vector<CvLinePolar2> lines;
CvMat c_image = source1; // loaded image
HoughLinesStandard(&c_image,1,CV_PI/180,4,&lines,INT_MAX);
typedef struct CvLinePolar2
{
float rho;
float angle;
vector<CvPoint> points;
};
void HoughLinesStandard( const CvMat* img, float rho, float theta,
int threshold, vector<CvLinePolar2> *lines, int linesMax= INT_MAX )
{
cv::AutoBuffer<int> _accum, _sort_buf;
cv::AutoBuffer<float> _tabSin, _tabCos;const uchar* image;
int step, width, height;
int numangle, numrho;
int total = 0;
int i, j;
float irho = 1 / rho;
double scale;
vector<vector<CvPoint>> lpoints;
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) );
//memset( lpoints, 0, sizeof(lpoints) );
lpoints.resize(sizeof(accum[0]) * (numangle+2) * (numrho+2));
float ang = 0;
for(int n = 0; n < numangle; 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 )
{
CvPoint pt;
pt.x = j; pt.y = i;
for(int n = 0; n < numangle; n++ )
{
int r = cvRound( j * tabCos[n] + i * tabSin[n] );
r += (numrho - 1) / 2;
int ind = (n+1) * (numrho+2) + r+1;
int s = accum[ind];
accum[ind]++;
lpoints[ind].push_back(pt);}
}
}
// stage 2. find local maximums
for(int r = 0; r < numrho; r++ )
for(int n = 0; n < numangle; n++ )
{
int base = (n+1) * (numrho+2) + r+1;
if( accum[base] > threshold &&
accum[base] > accum[base - 1] && accum[base] >= accum[base + 1] &&
accum[base] > accum[base - numrho - 2] && accum[base] >= accum[base + numrho + 2] )
sort_buf[total++] = base;
}
// stage 3. sort the detected lines by accumulator value
icvHoughSortDescent32s( sort_buf, total, accum );
// stage 4. store the first min(total,linesMax) lines to the output buffer
linesMax = MIN(linesMax, total);
scale = 1./(numrho+2);
for( i = 0; i < linesMax; i++ )
{
CvLinePolar2 line;
int idx = sort_buf[i];
int n = cvFloor(idx*scale) - 1;
int r = idx - (n+1)*(numrho+2) - 1;
line.rho = (r - (numrho - 1)*0.5f) * rho;
line.angle = n * theta;
line.points = lpoints[idx];
lines->push_back(line);
}
}
Один подход немаксимальное подавление прореживать набор кандидатов для потенциальных линий. После того, как вы определили утонченные потенциальные линии, вы можете вычислить среднее значение оставшихся линий, которое будет удовлетворять некоторому порогу угловой или пространственной разности.
Пытаться HoughLinesP
..ссылка на opencv