opencv直线拟合+直线与图像交点坐标
- 背景
- 函数说明
- fitLine
- clipLine
- 代码
背景
在车道线拟合过程中,需要计算拟合直线与图像边界的交点,以确定车道区域。主要使用的函数fitLine
和clipLine
。
函数说明
fitLine
/* 返回的lineParam信息如下:
* @param lineParam
* ax + by + c=0
* a = lineParam[1]
* b = -lineParam[0]
* c = line[0] * line[3] - line[1] * line[2]
* k = lineParam[1] / lineParam[0]
* 直线上点 p(lineParam[2], lineParam[3])
* 直线垂直时:lineParam[1]为1,lineParam[0]为负无穷小
* 直线水平时:lineParam[1]为0,lineParam[0]为1
*/
void fitLine( InputArray points, OutputArray line, int distType,double param, double reps, double aeps )
clipLine
clipLine()函数判断pt1到pt2的直线是否在一个矩形范围内。函数声明如下:
bool clipLine( // true if any part of line in imgRectcv::Rect imgRect, // rectangle to clip tocv::Point& pt1, // first endpoint of line overwrittencv::Point& pt2 // second endpoint of line, overwritten
);
bool clipLine( // true if any part of line in image sizecv::Size imgSize, // size of image,implies rectangle at 0,0cv::Point& pt1, // first endpoint of line,overwrittencv::Point& pt2 // second endpoint of line,overwritten
);
第一种函数的形式使用了cv::Rect,直线和这个矩形比较;第二个函数只有cv::Size,该形式表示矩形的范围是从(0,0)开始的。
只有当直线完全在指定的矩形范围之外时,函数cv::clipLine()才会返回false。
代码
#include"opencv2/opencv.hpp"
int main()
{cv::Mat img(800, 800, CV_8UC3, { 255,255,255 });cv::Rect rect(100, 100, 400, 400);cv::rectangle(img, rect, { 0,0,0 }, 3);// ---- 直线拟合 cv::Point temp[2] = { {100, 100}, {200,100} };cv::Vec4f line_para;cv::fitLine(std::vector<cv::Point>{ temp[0], temp[1]}, line_para, cv::DIST_L2, 0, 1e-2, 1e-2);// ---- 直线端点cv::Point point0(line_para[2], line_para[3]);//计算直线的端点(y = k(x - x0) + y0)cv::Point point1, point2;if (line_para[1] == 1) {point1 = cv::Point(line_para[2], 0);point2 = cv::Point(line_para[2], img.rows);}else {float k = line_para[1] / line_para[0];point1.x = 0;point1.y = k * (0 - point0.x) + point0.y;point2.x = img.cols;point2.y = k * (point2.x - point0.x) + point0.y;}cv::Point line1[] = { point1,point2 };cv::line(img, line1[0], line1[1], { 255,0,0 }, 2);// ----- 直线与矩形框交点if (cv::clipLine(rect, line1[0], line1[1])) {cv::circle(img, line1[0], 3, { 0,0,255 }, -1);cv::circle(img, line1[1], 3, { 0,0,255 }, -1);}// -- 绘制cv::circle(img, temp[0], 4, { 0,255,0 }, 2);cv::circle(img, temp[1], 4, { 0,255,0 }, 2);cv::imshow("1", img);cv::waitKey(0);return 0;
}