博客
关于我
(六)基于霍夫变换的直线和圆检测
阅读量:797 次
发布时间:2023-03-28

本文共 3756 字,大约阅读时间需要 12 分钟。

霍夫变换是一种强大的图像处理技术,广泛应用于直线和圆的检测。了解其工作原理和OpenCV的实现方法,可以帮助我们高效地解决实际问题。

1.霍夫变换概述

霍夫变换最初由Paul Hough提出,后由Richard Duda和Peter Hart推广。其核心思想是将图像中的直线转换为极坐标系下的曲线,从而通过曲线交点的特性来识别直线。这种方法在图像处理领域具有重要地位。

2.霍夫线检测

2.1标准霍夫线检测

OpenCV提供了HoughLines函数,该函数用于检测图像中的直线。其参数包括:

  • image:输入的单通道8位灰度图像。
  • lines:输出的直线向量,类型为Vec2f,每个向量包含ρ和θ值。
  • rho:ρ轴的精度,单位为像素。
  • theta:θ轴的精度,单位为弧度。
  • threshold:曲线交点的累积投票阈值。

示例代码:

#include 
#include
#include
#include
#include
using namespace std;
int main(int argc, char **argv) {
const char *filename = (argc >= 2) ? argv[1] : "line.png";
Mat src = imread(findFile(filename), IMREAD_GRAYSCALE);
if (src.empty()) {
cout << filename << " is empty." << endl;
return -1;
}
// 边缘检测
Canny(src, dst, 50, 200, 3);
cvtColor(dst, cdst, COLOR_GRAY2BGR);
// 标准霍夫线检测
vector
lines; HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0); // 绘制检测到的直线 for (size_t i = 0; i < lines.size(); ++i) { float rho = lines[i][0]; float theta = lines[i][1]; Point p1, p2; double a = cos(theta), b = sin(theta); p1.x = round(rho * a + 1000 * (-b)); p1.y = round(rho * b + 1000 * a); p2.x = round(rho * a - 1000 * (-b)); p2.y = round(rho * b - 1000 * a); line(cdst, p1, p2, Scalar(0, 0, 255), 3, LINE_AA); } imwrite("std_line_res.png", cdst); // 可能性的霍夫线检测 vector
linesP; HoughLinesP(dst, linesP, 1, CV_PI/180, 2, 2, 5); // 绘制检测到的直线 for (size_t i = 0; i < linesP.size(); ++i) { Vec4f l = linesP[i]; line(cdstP, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, LINE_AA); } imwrite("prob_line_res.png", cdstP); imshow("Source", src); imshow("Detected Lines - Standard Hough Line Transform", cdst); imshow("Detected Lines - Probabilistic Line Transform", cdstP); waitKey(); return 0; }

结果展示:

  • 原图:[图片链接]
  • 标准霍夫线检测结果:[图片链接]
  • 概率霍夫线检测结果:[图片链接]

3.霍夫圆检测

3.1霍夫圆变换

OpenCV提供了HoughCircles函数,用于检测图像中的圆。其参数包括:

  • image:输入的单通道8位灰度图像。
  • circles:输出的圆信息,类型为Vec4fVec4i,每个向量包含圆心坐标、半径和投票数。
  • method:检测方法,当前仅支持HOUGH_GRADIENT
  • dp:累加器的精度。
  • minDist:圆心的最小距离。
  • param1param2:根据检测方法适配的参数。
  • minRadius:检测的最小圆半径。
  • maxRadius:检测的最大圆半径。

示例代码:

#include 
#include
#include
#include
#include
using namespace std;
int main(int argc, char **argv) {
const char *filename = (argc >= 2) ? argv[1] : "apple.png";
Mat src = imread(findFile(filename), IMREAD_COLOR);
if (src.empty()) {
cout << filename << " is empty." << endl;
return -1;
}
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
medianBlur(gray, gray, 5);
vector
circles; HoughCircles(gray, circles, HOUGH_GRADIENT, 1, 100, 30, 1, 10); for (size_t i = 0; i < circles.size(); ++i) { Vec4f c = circles[i]; Point center(c[0], c[1]); circle(src, center, 2, Scalar(0, 0, 255), 2); circle(src, center, c[2], Scalar(0, 0, 255), 3, LINE_AA); cout << "circle vote numbers: " << c[3] << endl; } imwrite("detected_circle.png", src); imshow("Detected Circles", src); // 调整dp参数 HoughCircles(gray, circles, HOUGH_GRADIENT, 4, 100, 30, 1, 10); for (size_t i = 0; i < circles.size(); ++i) { Vec4f c = circles[i]; Point center(c[0], c[1]); circle(src, center, 2, Scalar(0, 0, 255), 2); circle(src, center, c[2], Scalar(0, 0, 255), 3, LINE_AA); cout << "circle vote numbers: " << c[3] << endl; } imwrite("detected_circle_4.png", src); waitKey(); return 0; }

结果展示:

  • 原图:[图片链接]
  • 检测结果:[图片链接]

4.参数优化

在实际应用中,合理选择霍夫变换的参数可以显著影响检测的效果和性能。例如:

  • 霍夫线检测

    • rhotheta的精度参数需要根据图像分辨率和预期直线密度进行调整。
    • threshold参数控制曲线交点的阈值,较低的阈值可能导致更多的假阳性,较高的阈值可能遗漏真实的直线。
  • 霍夫圆检测

    • dp参数控制累加器的分辨率,较高的dp值可能导致检测时间增加,但也可能减少误检。
    • minRadiusmaxRadius参数限制检测的圆的大小范围,可以减少冗余检测。

5.总结

霍夫变换是一种强大的图像处理工具,能够有效地检测图像中的直线和圆。OpenCV提供了丰富的API,允许开发者根据具体需求选择合适的检测方法和参数。通过合理配置参数和结合边缘检测算法,可以实现高效且准确的图像分析任务。

转载地址:http://yohfk.baihongyu.com/

你可能感兴趣的文章
Objective-C实现循环链表(附完整源码)
查看>>
Objective-C实现循环队列算法(附完整源码)
查看>>
Objective-C实现循环队列链表算法(附完整源码)
查看>>
Objective-C实现快速傅立叶变换FFT算法(附完整源码)
查看>>
Objective-C实现快速傅里叶变换FFT(附完整源码)
查看>>
Objective-C实现快速傅里叶变换FFT(附完整源码)
查看>>
Objective-C实现快速排序(附完整源码)
查看>>
Objective-C实现快速排序(附完整源码)
查看>>
Objective-C实现快速排序算法(附完整源码)
查看>>
Objective-C实现恩尼格玛密码机算法(附完整源码)
查看>>
Objective-C实现感知哈希算法(附完整源码)
查看>>
Objective-C实现感知哈希算法(附完整源码)
查看>>
Objective-C实现截留雨水问题的动态编程方法算法(附完整源码)
查看>>
Objective-C实现截留雨水问题的蛮力方法的算法(附完整源码)
查看>>
Objective-C实现打印10000以内的完数(附完整源码)
查看>>
Objective-C实现打印1000以内的水仙花数(附完整源码)
查看>>
Objective-C实现打印九九乘法表(附完整源码)
查看>>
Objective-C实现打印从 0 到 n 的卡特兰数算法(附完整源码)
查看>>
Objective-C实现打印函数调用堆栈( 附完整源码)
查看>>
Objective-C实现打印月份的日历算法(附完整源码)
查看>>