OpenCV | 直线拟合fitline函数

本文详细介绍了如何使用OpenCV的fitLine函数来拟合直线,包括函数参数的解释和代码示例。fitLine函数通过最小化输入点到直线的距离来找到最佳拟合线,支持多种距离类型如L1、L2等。在示例中,展示了如何从数据点生成矩阵,调用fitLine函数,并计算得到直线的斜率和截距。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        

学习目标:

学习掌握OpenCV的fitline函数


学习内容:

cv::fitLine()的具体调用形式如下:

void cv::fitLine(  
    cv::InputArray points, // 待拟合的直线的集合,必须是矩阵形式;
    cv::OutputArray line, //  距离类型。fitline为距离最小化函数,拟合直线时,要使输入点到拟合直线的距离和最小化。  
    int distType, // 距离类型  
    double param, //  距离参数,跟所选的距离类型有关,值可以设置为0。
    double reps, // 径向的精度参数  表示直线到原点距离的精度,建议取 0.01。设为0,则自动选用最优值
    double aeps // 角度精度参数  表示直线角度的精度,建议取 0.01
);

距离类型有以下的类别:

cv2.DIST_USER : User defined distance
cv2.DIST_L1: distance = |x1-x2| + |y1-y2|
cv2.DIST_L2: 欧式距离,此时与最小二乘法相同
cv2.DIST_C:distance = max(|x1-x2|,|y1-y2|)
cv2.DIST_L12:L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1))
cv2.DIST_FAIR:distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998
cv2.DIST_WELSCH: distance = c2/2(1-exp(-(x/c)2)), c = 2.9846
cv2.DIST_HUBER:distance = |x|<c ? x^2/2 : c(|x|-c/2), c=1.345


代码实现:

def fit(x,y,length):
    points = []
    for i in range(length):
        points.append([x[i], y[i]])
    points = np.array(points)
    output = cv.fitLine(points, cv.DIST_L2, 0, 0.01, 0.01)
    #output[0],output[1]是一个方向向量,output[2],output[3]是直线上一个点
    k = output[1] / output[0]
    b = output[3] - k * output[2]

### 轮廓检测与直线拟合OpenCV 中,轮廓检测通常涉及使用 `findContours` 函数来提取图像中的轮廓。一旦获得了这些轮廓点,就可以应用 `cv::fitLine` 函数来进行直线拟合。 #### 使用最小二乘法进行直线拟合 为了执行此操作,首先需要加载一幅图像并对它进行预处理以便更容易找到边缘和轮廓。下面展示了一个完整的流程,包括读取图像、灰度转换、阈值化以及最终的轮廓检测和直线拟合过程[^3]: ```cpp #include <opencv2/opencv.hpp> using namespace cv; using namespace std; int main() { // 加载图片并转为灰度图 Mat src = imread("image.jpg", IMREAD_COLOR); Mat gray, edges; cvtColor(src, gray, COLOR_BGR2GRAY); // 应用Canny算子获取边缘 Canny(gray, edges, 50, 150, 3); // 查找所有外部轮廓 vector<vector<Point>> contours; findContours(edges, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); // 创建一个窗口用于显示结果 namedWindow("Detected Lines", WINDOW_AUTOSIZE); // 遍历每一个轮廓尝试拟合成一条线 for (size_t i = 0; i < contours.size(); ++i){ Vec4f lineParams; // 对当前轮廓做直线拟合 fitLine(contours[i], lineParams, DIST_L2, 0, 0.01, 0.01); float vx = lineParams[0]; float vy = lineParams[1]; Point pt1(lineParams[2],lineParams[3]); // 计算线上两个端点的位置 double scale = sqrt(pow(src.cols, 2) + pow(src.rows, 2)); Point pt2(static_cast<int>(pt1.x + scale * vx), static_cast<int>(pt1.y + scale * vy)); // 绘制拟合后的线条到原图上 line(src, pt1, pt2, Scalar(0, 255, 0), 2); } imshow("Detected Lines", src); waitKey(); } ``` 这段代码展示了如何从输入图像中识别物体边界,并基于那些边界的坐标集合运用最小二乘算法寻找最佳匹配的直线。通过调整参数如距离测量方式(`DIST_L2`)和其他精度控制选项,可以获得更精确的结果[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值