翻译 unsigned int n = points.size(); if (n < 2) { return; } RNG random; double bestScore = -1.; vector<Point2d>vpdTemp; int iterations = log(1 - 0.99) / (log(1 - (1.00 / n)))*10; for (int k = 0; k < iterations; k++) { int i1 = 0, i2 = 0; while (i1 == i2) { i1 = random(n); i2 = random(n); } const cv::Point2d& p1 = points[i1]; const cv::Point2d& p2 = points[i2]; Point2d vectorP21 = p2 - p1; vectorP21 *= 1. / norm(vectorP21); double score = 0; vpdTemp.clear(); for (int i = 0; i < n; i++) { Point2d vectorPi1 = points[i] - p1; double d = vectorPi1.y * vectorP21.x - vectorPi1.x * vectorP21.y;//calculate the cosΘ of the two vectors. if (fabs(d) < sigma) { score += 1; } else { vpdTemp.push_back(points[i]); } } if (score > bestScore) { bestScore = score; vpdExceptPoints = vpdTemp; } }
时间: 2024-03-15 11:42:08 浏览: 186
这段代码的作用是利用随机采样一致性算法(RANSAC)来估算一组二维点集中的直线。首先,通过points.size()获取点集中点的数量,并将其赋值给无符号整型变量n。如果n小于2,直接返回。接着使用RNG类生成一个伪随机数对象random。然后定义一个变量bestScore表示最好的得分,初始值为-1.0。定义一个vpdTemp向量用于存储临时点集,和一个iterations变量表示迭代次数,计算公式为log(1 - 0.99) / (log(1 - (1.00 / n))) * 10。在循环中,执行iterations次随机采样。每次采样随机选取两个点,计算它们连成的直线的得分,如果得分比目前最好的得分要高,则更新最好的得分和vpdExceptPoints向量。最后返回vpdExceptPoints向量,它包含了剔除异常点后的点集。
相关问题
如何在这段代码中增加将获取到的点根据点的分数剔除比例再次筛选void DyConcentricArc::RansacCircleFiler(const vector<Point2d>& points, vector<Point2d>& vpdExceptPoints, double sigma) { unsigned int n = points.size(); if (n < 3) { return; } RNG random; double bestScore = -1.; vector<Point2d>vpdTemp; int iterations = log(1 - 0.99) / (log(1 - (1.00 / n))); for (int k = 0; k < iterations; k++) { int i1 = 0, i2 = 0, i3 = 0; Point2d p1(0, 0), p2(0, 0), p3(0, 0); while (true) { i1 = random(n); i2 = random(n); i3 = random(n); if ((i1 != i2 && i1 != i3 && i2 != i3)) { if ((points[i1].y != points[i2].y) && (points[i1].y != points[i3].y)) { break; } } } p1 = points[i1]; p2 = points[i2]; p3 = points[i3]; //use three points to caculate a circle Point2d pdP12 = GetPPCenter(p1, p2); double dK1 = -1 / GetLineSlope(p1, p2); double dB1 = pdP12.y - dK1 * pdP12.x; Point2d pdP13 = GetPPCenter(p1, p3); double dK2 = -1 / GetLineSlope(p1, p3); double dB2 = pdP13.y - dK2 * pdP13.x; Point2d pdCenter(0, 0); pdCenter.x = (dB2 - dB1) / (dK1 - dK2); pdCenter.y = dK1 * pdCenter.x + dB1; double dR = GetPPDistance(pdCenter, p1); double score = 0; vpdTemp.clear(); for (int i = 0; i < n; i++) { double d = dR - GetPPDistance(points[i], pdCenter); if (fabs(d) < sigma) { score += 1; } else { vpdTemp.push_back(points[i]); } } if (score > bestScore) { bestScore = score; vpdExceptPoints = vpdTemp; } } }
可以在函数中增加一个参数,表示剔除分数较低的点的比例,比如设为ratio。在每次迭代的时候,先计算出剔除的点数为n*ratio,然后将点按照得分从小到大排序,再依次将得分较低的n*ratio个点删除,剩下的点作为下一次迭代的输入点。可以在函数中增加如下代码:
```cpp
void DyConcentricArc::RansacCircleFiler(const vector<Point2d>& points, vector<Point2d>& vpdExceptPoints, double sigma, double ratio) {
unsigned int n = points.size();
if (n < 3) {
return;
}
RNG random;
double bestScore = -1.;
vector<Point2d>vpdTemp;
int iterations = log(1 - 0.99) / (log(1 - (1.00 / n)));
for (int k = 0; k < iterations; k++) {
int i1 = 0, i2 = 0, i3 = 0;
Point2d p1(0, 0), p2(0, 0), p3(0, 0);
while (true) {
i1 = random(n);
i2 = random(n);
i3 = random(n);
if ((i1 != i2 && i1 != i3 && i2 != i3)) {
if ((points[i1].y != points[i2].y) && (points[i1].y != points[i3].y)) {
break;
}
}
}
p1 = points[i1];
p2 = points[i2];
p3 = points[i3];
//use three points to caculate a circle
Point2d pdP12 = GetPPCenter(p1, p2);
double dK1 = -1 / GetLineSlope(p1, p2);
double dB1 = pdP12.y - dK1 * pdP12.x;
Point2d pdP13 = GetPPCenter(p1, p3);
double dK2 = -1 / GetLineSlope(p1, p3);
double dB2 = pdP13.y - dK2 * pdP13.x;
Point2d pdCenter(0, 0);
pdCenter.x = (dB2 - dB1) / (dK1 - dK2);
pdCenter.y = dK1 * pdCenter.x + dB1;
double dR = GetPPDistance(pdCenter, p1);
double score = 0;
vpdTemp.clear();
for (int i = 0; i < n; i++) {
double d = dR - GetPPDistance(points[i], pdCenter);
if (fabs(d) < sigma) {
score += 1;
}
else {
vpdTemp.push_back(points[i]);
}
}
// sort points by score
sort(vpdTemp.begin(), vpdTemp.end(), [&](Point2d a, Point2d b) {
return GetPPDistance(a, pdCenter) < GetPPDistance(b, pdCenter);
});
// remove low-score points
int numToRemove = (int)(vpdTemp.size() * ratio);
for (int i = 0; i < numToRemove; i++) {
vpdTemp.erase(vpdTemp.begin());
}
if (score > bestScore) {
bestScore = score;
vpdExceptPoints = vpdTemp;
}
}
}
```
阅读全文