c/c++的opencv霍夫变换
OpenCV中的霍夫变换 (C/C++) Hough Transform
霍夫变换 (Hough Transform) 是一种在图像分析中用于检测几何形状(如直线、圆形等)的特征提取技术。它通过一种投票机制在参数空间中寻找特定形状的实例。OpenCV 库为 C++ 开发者提供了强大且易用的霍夫变换函数。
1. 霍夫直线变换 (Hough Line Transform) 📏
霍夫直线变换用于检测图像中的直线。其基本思想是将图像空间中的点映射到参数空间(通常是极坐标 ( ρ , θ ) (\rho, \theta) (ρ,θ) 空间),并在参数空间中寻找峰值,这些峰值对应于图像空间中的直线。
直线方程: ρ = x cos θ + y sin θ \rho = x \cos\theta + y \sin\theta ρ=xcosθ+ysinθ
其中:
- ρ \rho ρ (rho) 是从原点到直线的垂直距离。
-
θ
\theta
θ (theta) 是这条垂直线与 x 轴之间的角度。
1.1 标准霍夫变换 (Standard Hough Transform - SHT)
cv::HoughLines 函数实现了标准霍夫变换。它返回一个包含 ( ρ , θ ) (\rho, \theta) (ρ,θ) 对的向量。
函数原型:
void cv::HoughLines( cv::InputArray image, // 输入图像 (必须是8位单通道二值图像,通常是Canny边缘检测的输出) cv::OutputArray lines, // 输出向量,存储检测到的直线的参数 (cv::Vec2f 表示 rho 和 theta) double rho, // rho 的累加器分辨率 (以像素为单位) double theta, // theta 的累加器分辨率 (以弧度为单位) int threshold, // 累加器阈值参数,只有累加值大于该阈值的直线才会被检测到 double srn = 0, // 对于多尺度霍夫变换,它是 rho 的除数。如果为0,则使用经典霍夫变换。 double stn = 0, // 对于多尺度霍夫变换,它是 theta 的除数。如果为0,则使用经典霍夫变换。 double min_theta = 0, // 检测直线的最小角度 (弧度) double max_theta = CV_PI // 检测直线的最大角度 (弧度) );
主要步骤:
- 边缘检测:通常使用 cv::Canny。
- 应用 cv::HoughLines。
- 遍历检测到的直线参数,并在原图上绘制。
示例代码:
#include #include #include int main() { cv::Mat src = cv::imread("your_image_with_lines.png", cv::IMREAD_GRAYSCALE); if (src.empty()) { std::cerr 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(color_dst, pt1, pt2, cv::Scalar(0, 0, 255), 1, cv::LINE_AA); } cv::imshow("Source", src); cv::imshow("Detected Lines (Standard Hough)", color_dst); cv::waitKey(0); return 0; } cv::Mat src = cv::imread("your_image_with_lines.png", cv::IMREAD_COLOR); if (src.empty()) { std::cerr cv::Vec4i l = linesP[i]; cv::line(src, cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), cv::Scalar(0, 0, 255), 2, cv::LINE_AA); } cv::imshow("Source", gray); // 显示灰度图或原彩色图 cv::imshow("Detected Lines (Probabilistic Hough)", src); cv::waitKey(0); return 0; } cv::Mat src = cv::imread("your_image_with_circles.png", cv::IMREAD_COLOR); if (src.empty()) { std::cerr cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); int radius = cvRound(circles[i][2]); // 绘制圆心 cv::circle(src, center, 3, cv::Scalar(0, 255, 0), -1, 8, 0); // 绘制圆轮廓 cv::circle(src, center, radius, cv::Scalar(0, 0, 255), 2, 8, 0); } cv::imshow("Source", src); // 在原彩色图上绘制 cv::imshow("Detected Circles", src); cv::waitKey(0); return 0; }