OpenCV2学习笔记(八):使用霍夫变换检测直线和圆

在研究一幅图像时,常常会遇到一些平面或线性问题,直线在图像中频繁可见。这些富有意义的特征在物体识别等图像处理过程中扮演着重要的角色。本节主要记录一种经典的检测直线算法——霍夫变换(Hough Transform),用Hough变换检测图像中的直线和圆,开发平台为Qt5.3.2+OpenCV2.4.9。

一:Hough变换检测图像的直线

1.基础Hough变换

在霍夫变换中,直线用以下方程表示:

其中,参数

表示一条直线到图像原点(左上角)的距离,

表示与直线垂直的角度。如下图所示,直线1的垂直线的角度

等于0,而水平线5的

等于二分之π。同时,直线3的角度

等于四分之π,而直线4的角度大约是0.7π。为了能够在

为区间[0,π]之间得到所有可能的直线,半径值可取为负数,这正是直线2的情况。

OpenCV提供两种霍夫变换的实现,基础版本是:cv::HoughLines。它的输入为一幅包含一组点的二值图像,其中一些排列后形成直线,通常这是一幅边缘图像,比如来自Sobel算子或Canny算子。cv::HoughLines函数的输出是cv::Vec2f向量,每个元素都是一对代表检测到的直线的浮点数(p, r0)。在设计程序时,先求出图像中每点的极坐标方程,若相交于一点的极坐标曲线的个数大于最小投票数,则将该点所对应的(p, r0)放入vector中,即得到一条直线。cv::HoughLines函数的调用方法如下:

// 基础版本的Hough变换// 首先应用Canny算子获取图像的轮廓cv::Mat image = cv::imread(“c:/031.jpg”, 0);cv::Mat contours;cv::Canny(image,contours,125,350);// Hough变换检测直线std::vector<cv::Vec2f> lines;cv::HoughLines(contours,lines,1,PI/180, // 步进尺寸80);// 最小投票数

实现基础Hough变换的完整代码如下,直接在main函数中添加:

main(int argc, char *argv[]){QCoreApplication a(argc, argv);// 基础版本的Hough变换// 首先应用Canny算子获取图像的轮廓cv::Mat image = cv::imread(“c:/031.jpg”, 0);cv::Mat contours;cv::Canny(image,contours,125,350);// Hough变换检测直线std::vector<cv::Vec2f> lines;cv::HoughLines(contours,lines,cv::Mat result(contours.rows,contours.cols,CV_8U,cv::Scalar(255));image.copyTo(result);// 以下遍历图像绘制每一条线std::vector<cv::Vec2f>::const_iterator it= lines.begin();while (it!=lines.end()){theta= (*it)[1]; // 表示角度if (theta < PI/4. || theta > 3.*PI/4.) // 若检测为垂直线{// 得到线与第一行的交点cv::Point pt1(rho/cos(theta),0);// 得到线与最后一行的交点cv::Point pt2((rho-result.rows*sin(theta))/cos(theta),result.rows);// 调用line函数绘制直线cv::line(result, pt1, pt2, cv::Scalar(255), 1);} else // 若检测为水平线{// 得到线与第一列的交点cv::Point pt1(0,rho/sin(theta));// 得到线与最后一列的交点cv::Point pt2(result.cols,(rho-result.cols*cos(theta))/sin(theta));// 调用line函数绘制直线cv::line(result, pt1, pt2, cv::Scalar(255), 1);}++it;}// 显示结果cv::namedWindow(“Detected Lines with Hough”);cv::imshow(“Detected Lines with Hough”,result);return a.exec();}

改变cv::HoughLines中的最小投票数,可以得到不同的检测结果,因此可知道投票数对于直线的判决具有重要意义。最小投票数为100时:

最小投票数为60时:

注意hough变换要求输入的是包含一组点的二值图像。

2.概率Hough变换

由输出结果可知,基础Hough变换检测出图像中的直线,但在许多应用场合中,,我们需要的是局部的线段而非整条直线。正如代码中的情况,需要判定直线与图像边界的交点,才能确定一条线段,否则绘制的直线将穿过整幅图像。其次,霍夫变换仅仅查找边缘点的一种排列方式,由于意外的像素排列或是多条线穿过同一组像素,很有可能带来错误的检测。

尝到你和你在一起的快乐,你是唯一能让我尝到酸甜苦辣的人。

OpenCV2学习笔记(八):使用霍夫变换检测直线和圆

相关文章:

你感兴趣的文章:

标签云: