c++的opencv直线检测
时间: 2025-05-25 07:10:07 浏览: 25
### 基于C++和OpenCV的直线检测代码示例
以下是基于C++和OpenCV实现的标准霍夫直线检测、概率霍夫直线检测以及最小二乘法直线拟合的代码示例。
#### 标准霍夫直线检测
标准霍夫变换通过 `cv::HoughLines` 函数来实现,该函数返回一组 `(ρ, θ)` 参数表示的直线[^1]。下面是一个简单的代码示例:
```cpp
#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
// 加载图像并转换为灰度图
cv::Mat src = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);
if (src.empty()) {
std::cout << "Could not open or find the image!" << std::endl;
return -1;
}
// 边缘检测
cv::Mat edges;
cv::Canny(src, edges, 50, 150);
// 定义存储霍夫直线的结果容器
std::vector<cv::Vec2f> lines;
// 执行标准霍夫变换
cv::HoughLines(edges, lines, 1, CV_PI / 180, 150);
// 绘制检测到的直线
cv::Mat dst;
cv::cvtColor(edges, dst, cv::COLOR_GRAY2BGR);
for (size_t i = 0; i < lines.size(); ++i) {
float rho = lines[i][0], theta = lines[i][1];
cv::Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a * rho, y0 = b * rho;
pt1.x = cvRound(x0 + 1000 * (-b));
pt1.y = cvRound(y0 + 1000 * (a));
pt2.x = cvRound(x0 - 1000 * (-b));
pt2.y = cvRound(y0 - 1000 * (a));
cv::line(dst, pt1, pt2, cv::Scalar(0, 0, 255), 3, cv::LINE_AA);
}
// 显示结果
cv::imshow("Detected Lines (in red) - Standard Hough Line Transform", dst);
cv::waitKey();
return 0;
}
```
---
#### 概率霍夫直线检测
概率霍夫变换通过 `cv::HoughLinesP` 函数实现,它直接返回直线的两个端点坐标 `(x1, y1, x2, y2)`[^2]。下面是相应的代码示例:
```cpp
#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
// 加载图像并转换为灰度图
cv::Mat src = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);
if (src.empty()) {
std::cout << "Could not open or find the image!" << std::endl;
return -1;
}
// 边缘检测
cv::Mat edges;
cv::Canny(src, edges, 50, 150);
// 存储概率霍夫直线的结果
std::vector<cv::Vec4i> lines;
// 执行概率霍夫变换
cv::HoughLinesP(edges, lines, 1, CV_PI / 180, 50, 50, 10);
// 绘制检测到的直线
cv::Mat dst;
cv::cvtColor(edges, dst, cv::COLOR_GRAY2BGR);
for (size_t i = 0; i < lines.size(); ++i) {
cv::Vec4i l = lines[i];
cv::line(dst, cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), cv::Scalar(0, 0, 255), 3, cv::LINE_AA);
}
// 显示结果
cv::imshow("Probabilistic Line Transform", dst);
cv::waitKey();
return 0;
}
```
---
#### 最小二乘法直线拟合
最小二乘法可以通过计算边缘像素点的最佳拟合直线来完成。这里提供一个简单的方法[^1]:
```cpp
#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
// 加载图像并转换为灰度图
cv::Mat src = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);
if (src.empty()) {
std::cout << "Could not open or find the image!" << std::endl;
return -1;
}
// 边缘检测
cv::Mat edges;
cv::Canny(src, edges, 50, 150);
// 获取非零点作为候选数据集
std::vector<cv::Point> points;
cv::findNonZero(edges, points);
// 计算最小二乘法拟合直线
cv::Vec4f line;
cv::fitLine(points, line, cv::DIST_L2, 0, 0.01, 0.01);
// 提取直线参数
float vx = line[0], vy = line[1], x0 = line[2], y0 = line[3];
// 创建绘图窗口
cv::Mat dst;
cv::cvtColor(edges, dst, cv::COLOR_GRAY2BGR);
// 绘制拟合直线
int rows = dst.rows, cols = dst.cols;
cv::Point pt1(cvRound(x0 - vx * cols), cvRound(y0 - vy * cols));
cv::Point pt2(cvRound(x0 + vx * cols), cvRound(y0 + vy * cols));
cv::line(dst, pt1, pt2, cv::Scalar(0, 255, 0), 3, cv::LINE_AA);
// 显示结果
cv::imshow("Least Squares Line Fit", dst);
cv::waitKey();
return 0;
}
```
---
### 总结
以上分别展示了如何使用 OpenCV 的 C++ 接口执行标准霍夫直线检测、概率霍夫直线检测以及最小二乘法直线拟合。每种方法都有其适用场景,具体选择取决于实际需求。
阅读全文
相关推荐


















