基于c++ opencv的车道线检测算法流程及完整代码
时间: 2024-01-01 10:04:10 浏览: 171
以下是基于C++和OpenCV的车道线检测算法流程及完整代码:
1. 读取图像并进行灰度化和高斯滤波
```c++
Mat image = imread("image.jpg");
Mat grayImage, blurImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);
GaussianBlur(grayImage, blurImage, Size(5, 5), 0, 0);
```
2. 进行Canny边缘检测
```c++
Mat edges;
Canny(blurImage, edges, 50, 150);
```
3. 对图像进行ROI裁剪
```c++
Mat roiMask = Mat::zeros(image.size(), image.type());
Point points[4] = {Point(0, image.rows), Point(image.cols / 2, image.rows / 2), Point(image.cols / 2 + 50, image.rows / 2), Point(image.cols, image.rows)};
fillConvexPoly(roiMask, points, 4, Scalar(255, 0, 0));
Mat roiImage;
bitwise_and(edges, roiMask, roiImage);
```
4. 进行霍夫变换检测直线
```c++
vector<Vec2f> lines;
HoughLines(roiImage, lines, 1, CV_PI / 180, 100, 0, 0);
```
5. 进行直线筛选和拟合
```c++
vector<Vec2f> leftLines, rightLines;
for (int i = 0; i < lines.size(); i++) {
float rho = lines[i][0], theta = lines[i][1];
if (theta < CV_PI / 4 || theta > 3 * CV_PI / 4) {
leftLines.push_back(lines[i]);
} else {
rightLines.push_back(lines[i]);
}
}
Vec2f leftLine, rightLine;
if (leftLines.size() > 0) {
float leftRho = 0, leftTheta = 0;
for (int i = 0; i < leftLines.size(); i++) {
leftRho += leftLines[i][0];
leftTheta += leftLines[i][1];
}
leftRho /= leftLines.size();
leftTheta /= leftLines.size();
leftLine = Vec2f(leftRho, leftTheta);
}
if (rightLines.size() > 0) {
float rightRho = 0, rightTheta = 0;
for (int i = 0; i < rightLines.size(); i++) {
rightRho += rightLines[i][0];
rightTheta += rightLines[i][1];
}
rightRho /= rightLines.size();
rightTheta /= rightLines.size();
rightLine = Vec2f(rightRho, rightTheta);
}
```
6. 计算直线与图像边界的交点
```c++
Point leftStart, leftEnd, rightStart, rightEnd;
if (leftLine[1] != 0) {
float leftSlope = -1 / tan(leftLine[1]);
float leftIntercept = leftLine[0] / sin(leftLine[1]);
leftStart = Point(0, leftIntercept);
leftEnd = Point(image.cols, leftSlope * image.cols + leftIntercept);
} else {
leftStart = Point(leftLine[0], 0);
leftEnd = Point(leftLine[0], image.rows);
}
if (rightLine[1] != 0) {
float rightSlope = -1 / tan(rightLine[1]);
float rightIntercept = rightLine[0] / sin(rightLine[1]);
rightStart = Point(0, rightIntercept);
rightEnd = Point(image.cols, rightSlope * image.cols + rightIntercept);
} else {
rightStart = Point(rightLine[0], 0);
rightEnd = Point(rightLine[0], image.rows);
}
```
7. 绘制车道线并显示图像
```c++
line(image, leftStart, leftEnd, Scalar(0, 0, 255), 2);
line(image, rightStart, rightEnd, Scalar(0, 0, 255), 2);
imshow("Lane Detection", image);
```
完整代码如下:
```c++
#include <opencv2/opencv.hpp>
using namespace cv;
int main() {
Mat image = imread("image.jpg");
Mat grayImage, blurImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);
GaussianBlur(grayImage, blurImage, Size(5, 5), 0, 0);
Mat edges;
Canny(blurImage, edges, 50, 150);
Mat roiMask = Mat::zeros(image.size(), image.type());
Point points[4] = {Point(0, image.rows), Point(image.cols / 2, image.rows / 2), Point(image.cols / 2 + 50, image.rows / 2), Point(image.cols, image.rows)};
fillConvexPoly(roiMask, points, 4, Scalar(255, 0, 0));
Mat roiImage;
bitwise_and(edges, roiMask, roiImage);
vector<Vec2f> lines;
HoughLines(roiImage, lines, 1, CV_PI / 180, 100, 0, 0);
vector<Vec2f> leftLines, rightLines;
for (int i = 0; i < lines.size(); i++) {
float rho = lines[i][0], theta = lines[i][1];
if (theta < CV_PI / 4 || theta > 3 * CV_PI / 4) {
leftLines.push_back(lines[i]);
} else {
rightLines.push_back(lines[i]);
}
}
Vec2f leftLine, rightLine;
if (leftLines.size() > 0) {
float leftRho = 0, leftTheta = 0;
for (int i = 0; i < leftLines.size(); i++) {
leftRho += leftLines[i][0];
leftTheta += leftLines[i][1];
}
leftRho /= leftLines.size();
leftTheta /= leftLines.size();
leftLine = Vec2f(leftRho, leftTheta);
}
if (rightLines.size() > 0) {
float rightRho = 0, rightTheta = 0;
for (int i = 0; i < rightLines.size(); i++) {
rightRho += rightLines[i][0];
rightTheta += rightLines[i][1];
}
rightRho /= rightLines.size();
rightTheta /= rightLines.size();
rightLine = Vec2f(rightRho, rightTheta);
}
Point leftStart, leftEnd, rightStart, rightEnd;
if (leftLine[1] != 0) {
float leftSlope = -1 / tan(leftLine[1]);
float leftIntercept = leftLine[0] / sin(leftLine[1]);
leftStart = Point(0, leftIntercept);
leftEnd = Point(image.cols, leftSlope * image.cols + leftIntercept);
} else {
leftStart = Point(leftLine[0], 0);
leftEnd = Point(leftLine[0], image.rows);
}
if (rightLine[1] != 0) {
float rightSlope = -1 / tan(rightLine[1]);
float rightIntercept = rightLine[0] / sin(rightLine[1]);
rightStart = Point(0, rightIntercept);
rightEnd = Point(image.cols, rightSlope * image.cols + rightIntercept);
} else {
rightStart = Point(rightLine[0], 0);
rightEnd = Point(rightLine[0], image.rows);
}
line(image, leftStart, leftEnd, Scalar(0, 0, 255), 2);
line(image, rightStart, rightEnd, Scalar(0, 0, 255), 2);
imshow("Lane Detection", image);
waitKey(0);
return 0;
}
```
阅读全文