二维/三维直线拟合–opencv实现
Hough变换可以提取图像中的直线,但是提取线的精度不高,然而我们的很多场合下需要精确估计直线的参数,这时就需要进行直线拟合。
直线拟合的方法有很多,比如:一元线性回归就是一种最简单的直线拟合方法,但是这种方法不适用于提取图像中的直线。因为这种算法假设每个数据点中的x坐标是精确的,Y坐标是带有噪声的,可是在实际的图像中,我们所提取到的点坐标的x、y坐标都是带有噪声的。因此,下面将介绍适用于图像中的精确直线拟合方法。
在介绍拟合过程之前,首先,我们需要明确的是精确的直线拟合过程其实就是使用所有的数据点构建一个包含两个直线方程参数的超定方程组,然后去优化这个方程组,从而计算出直线参数方程的过程。以下为建立超定方程组的过程:
已知条件:二维图像中提取的多个数据点(>=2)。
目标:找到最能“描述这些数据点”的直线方程。
S1:数据点中任意一点(xi,yi)到目标直线的距离为ri;
S2:直线拟合就是找到一条直线使得所有数据点到该条直线的距离“在某种意义下”最小,以下数据项即为所要求计算的最小项;
方法 | 距离函数 |
---|---|
CV_DIST_L1 | |
CV_DIST_L2 | |
CV_DIST_FAIR | (C=1.3998) |
CV_DIST_HUBER | [外链图片转存失败(img-lpGd8JF8-1565651177264)(https://latex.codecogs.com/png.latex?%5Crho%20%28r%29%3D%5Cbegin%7Bcases%7D%20%5Cfrac%7Br%5E%7B2%7D%7D%7B2%7D%26%20%5Ctext%7B%20if%20%7D%20r%3CC%20%5C%5C%20C%28r-%5Cfrac%7BC%7D%7B2%7D%29%26%20%5Ctext%7B%20if%20%7D%20otherwise%20%5Cend%7Bcases%7D)] (C=1.345) |
opencv中的直线合函数使用非常简单,具体可参考官方网站说明。其中,有一点需要说明一下,该函数计算出的直线参数信息在参数line中,该参数是cv::Vec4f类型,其中line[0]和line[1]代表直线的方向向量,而line[2]和line[3]代表直线上的一点坐标(直线方程:y=kx+b,k=line[1]/line[0],b=line[3]-k*line[2])。
Ransac直线拟合
Ransac,即随机采样一致性算法,最早用于计算位姿问题,目前已经广泛应用于估计任意模型的参数问题。对于数据中存在大比例的错误点,该方法十分有效,下面就以直线估计的例子来说明。
算法流程:
1.随机选择两点(确定一条直线所需要的最小点集为2),由这两点确定一条直线l;
2.根据阈值t,计算与直线l的几何距离小于t的数据点击S(l),并称它为直线l的一致集;
3.重复若干次选择,得到直线l1,l2,…,ln和相应的一致集S…;
4.使用几何距离,计算最大一致集的最佳拟合直线,作为数据点的最佳匹配直线。
测试
生成一条直线上随机的20个点,然后随机添加100个距离该直线>10的点,分别使用opencv中的fitLine函数和ransac版的函数进行拟合,以下为拟合结果:
三维点拟合—待续
大家好,我主要的研究方向有:
1)主流的结构光三维测量方法,包括:线扫,格雷码,相移,散斑等;
2)摄像机标定和投影仪标定;
3)点云处理;
4)图像处理;
5)Halcon应用;
6)机器视觉相机选型。
对以上研究方向感兴趣的朋友可以关注我的微信公众号: