代码地址:https://github.com/KEDIARAHUL135/VanishingPoint
我们将计算和发现使用之前发现的线条的图像的消失点。
这一节涉及与线(它们的交点和它们的距离)有关的基本数学从一个点)和一个小的逻辑。
// 我们在这里要做的是,我们将使用两个线的组合,然后找到它们交点。这个交点可以是消失点,因为它期望线在消失点附近收敛。但这里有一个问题,就是有很多lines (我们的最大值是15),所以两条线的这种交点的数量可以导致许多不同的
点。那么我们如何在这些点中找到最接近实际的消失点?
为此,我们在逻辑中引入了一个“误差”因素。误差基本上是这个点到每条直线距离的平方和的平方根 。相对应的点最小误差值可能是最接近消失点的值,因此我们计算出了消失点。
下面展示了两线相交后的计算点错误值。这里我们仅以3条lines为例。
我们取直线L1和L2它们的交点是(x0, y0),直线方程L1是y = m1x + c1直线L2的方程是y = m2x +c2。
计算L1和L2的交点(x0,y0):
我们现在会找到这一点到直线L的距离,直线L的方程是y = m*x + c,为此,我们设直线L_ (L破折号)(方程:y = m_*x + c_)垂直于L,并通过这个点 (x0, y0)。直线L_与直线L的交点为(x_, y_),即点的距离(x0, y0)到直线L的距离是 d= (x0, y0)到(x_, y_)的距离。这些点在直线L处的误差值是这些点的平方和的根如图所示。
计算L1和L2的交点(x0,y0)到直线L的距离:
int* GetVanishingPoint(std::vector<std::vector<double>> Lines)
{
// We will apply RANSAC inspired algorithm for this.We will take combination
// of 2 lines one by one, find their intersection point, and calculate the
// total error(loss) of that point.Error of the point means root of sum of
// squares of distance of that point from each line.
int* VanishingPoint = new int[2];
VanishingPoint[0] = -1; VanishingPoint[1] = -1;
double MinError = 1000000000.0;
for (int i = 0; i < Lines.size(); i++) //遍历lines,一次取2个
{
for (int j = i + 1; j < Lines.size(); j++)
{
//获取直线的 m,c; y=mx+c
double m1 = Lines[i][4], c1 = Lines[i][5];
double m2 = Lines[j][4], c2 = Lines[j][5];
if (m1 != m2) //如果俩条直线不平行
{ //直线L1和L2它们的交点是(x0, y0)
double x0 = (c1 - c2) / (m2 - m1);
double y0 = m1 * x0 + c1;
double err = 0;
// 迭代所有lines进行错误计算
for (int k = 0; k < Lines.size(); k++)
{
double m = Lines[k][4], c = Lines[k][5];
double m_ = (-1 / m);
double c_ = y0 - m_ * x0;//过交点(x0, y0),斜率k=(-1 / m)的直线L_
//求直线L和直线L_的 交点(x_ , y_)
double x_ = (c - c_) / (m_ - m);
double y_ = m_ * x_ + c_;
//直线L1和直线L2的 交点到L的距离就是交点(x0, y0)到点(x_ , y_)的距离
double l = pow((pow((y_ - y0), 2) + pow((x_ - x0), 2)), 0.5);
err += pow(l, 2);
}
err = pow(err, 0.5);
if (MinError > err)
{
MinError = err;
VanishingPoint[0] = (int)x0;
VanishingPoint[1] = (int)y0;
}
}
}
}
return VanishingPoint;
}