У меня есть точки в изображении. Мне нужно обнаружить самые коллинеарные точки. Самый быстрый способ - использовать преобразование Хафа, но мне нужно изменить метод opencv. На самом деле мне нужно, чтобы полуколлинеарные точки возвращались с обнаруженной линией, поэтому я модифицировал структуру полярной линии. Порог допуска также необходим для обнаружения почти обнаруженных точек, как показано на изображении. Может ли кто-нибудь помочь в настройке этого порога? Мне нужно, по крайней мере, четыре полуколлинеарных точки, чтобы обнаружить линию, к которой они принадлежат. Преобразование hough возвращает коллинеарные и полуколлинеарные точки
Точки первого изображения были обнаружены 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);
}
}
Я знаю, что это больше подходит для моего случая, но не возвращает коллинеарных точек – dervish