`

openCV入门----霍夫变换直线检测(CvHoughLine2的使用)

 
阅读更多

      上回书说道,霍夫变换检测直线的原理,以及自己编程实现,那么今天我就来使用openCV里的函数来完成这个有意思的任务,看看能收获些什么呢?

      前面我们利用openCV处理过平滑图像(高斯滤波)、边缘检测(canny算法),这些都是直接调用后可以直接得出图像的结果,然后显示出来,然而霍夫变换相对来说复杂一点点,它返回的结果是直线的参数,那么什么是直线的参数呢?

      这个问题我后面再来解释,先看看openCV里处理霍夫变换检测直线的函数有哪些?

      1.  CvHoughLine(...)

      2.  CvHoughLine2(...)

      openCV里有两个函数(比较常用)处理霍夫变换直线检测,有什么区别呢。

      CvHoughLine:是用于标准的霍夫变换方法

      CvHoughLine2:可以使用三种霍夫变换的方法,分别是标准霍夫变换(SHT)、多尺度标准霍夫变换(MSHT)、累计概率霍夫变换(PPHT)。

这些个方法是什么东西呢?暂且我们不管这个问题,但是很直观地告诉我们第二个比第一个要好,方法选择更加多,一看就是前者的升级进化版,所以我确定要学习第二个方法,那么第一个方法也自然水到渠成了。接下来我们再来具体探讨第二个方法的使用。

 

      首先,我们就从上述提到的三种方法开始解释,那三种霍夫变换究竟是什么东东呢?其实到现在我也只是简单地了解一下这玩意可能是什么,却也说不出究竟是个啥,怎么做出来的(这是不是就说明了没有经自己的手编程,那么永远都是门外汉或者说要经过长时间的纠结才能入门这个事实呢,所以有些玩意还是要自己动手才能明白的!),但是目前这个阶段,了解一下也就可以了:

     上述说是三种方法,其实归结到底是两种方法,(1)标准霍夫变换 (2)累计概率霍夫变换

     标准霍夫变换实际上就是我们上回书探讨的坐标变换的那个方法,详细细节请参考上一篇博客;

     PPHT实际上是标准霍夫变换的一个变种,计算单独线段的方向以及范围。之所以称之是概率,是因为并不将累加器平面内的所有可能得点相累加,而是只累加其中的一部分。该想法是如果峰值将要足够的高,只用一小部分时间去寻找它就足够了,这样可以大大节省时间。

      解释如上,摘自《Learning openCV》,但是总有一种看了跟没看的感觉,总的来说,主要了解一下一下几点就好了吧(个人认为):

      1.标准霍夫变换(SHT)就是满大街、书上、网上都找到的基本上相同的解释,如同我上篇介绍的那样;

      2.SHT返回的是直线的方向;

      3.PPHT以概率的方式操作累加器;

      4.PPHT可以大大节省时间;

      5.PPHT返回的是直线的方向和范围。

     知道了这几个区别,我相信聪明的你看出来了,哪个更加牛逼一些-----PPHT!不说别的,光从返回值来说,PPHT方法返回的信息将更加丰富,对编程者来说也意味着更加nice!

 

     接着,知道了以上比较笼统的概念后,我们来细看这个函数:

函数原型:

CvSeq* cvHoughLines2(
CvArr* image,
void* line_storage,
int mehtod,
double rho,
double theta,
int threshold,
double param1 =0,
double param2 =0
);

 

image
输入 8-比特、单通道 (二值) 图像,当用CV_HOUGH_PROBABILISTIC方法检测的时候其内容会被函数改变。
line_storage
检测到的线段存储仓. 可以是内存存储仓 (此种情况下,一个线段序列在存储仓中被创建,并且由函数返回),或者是包含线段参数的特殊类型(见下面)的具有单行/单列的矩阵(CvMat*)。矩阵头为函数所修改,使得它的 cols/rows 将包含一组检测到的线段。如果 line_storage 是矩阵,而实际线段的数目超过矩阵尺寸,那么最大可能数目的线段被返回(线段没有按照长度、可信度或其它指标排序).
method
Hough 变换变量,是下面变量的其中之一:
CV_HOUGH_STANDARD - 传统或标准 Hough 变换. 每一个线段由两个浮点数 (ρ, θ) 表示,其中 ρ 是直线与原点 (0,0) 之间的距离,θ 线段与 x-轴之间的夹角。因此,矩阵类型必须是 CV_32FC2 type.
CV_HOUGH_PROBABILISTIC - 概率 Hough 变换(如果图像包含一些长的线性分割,则效率更高). 它返回线段分割而不是整个线段。每个分割用起点和终点来表示,所以矩阵(或创建的序列)类型是 CV_32SC4.
CV_HOUGH_MULTI_SCALE - 传统 Hough 变换的多尺度变种。线段的编码方式与 CV_HOUGH_STANDARD 的一致。
rho
与像素相关单位的距离精度
theta
弧度测量的角度精度
threshold
阈值参数。如果相应的累计值大于 threshold, 则函数返回这条线段.
param1
第一个方法相关的参数:
对传统 Hough 变换,不使用(0).
对概率 Hough 变换,它是最小线段长度.
多尺度 Hough 变换,它是距离精度 rho 的分母 (大致的距离精度是 rho 而精确的应该是 rho / param1 ).
param2
第二个方法相关参数:
对传统 Hough 变换,不使用 (0).
对概率 Hough 变换,这个参数表示在同一条直线上进行碎线段连接的最大间隔值(gap), 即当同一条直线上的两条碎线段之间的间隔小于param2时,将其合二为一。
对多尺度 Hough 变换,它是角度精度 theta 的分母 (大致的角度精度是 theta 而精确的角度应该是 theta / param2).

(以上函数原型到参数解释内容摘抄自百度百科http://baike.baidu.com/link?url=cTXxnE2iR076usVBFRJq63PkwCLkiAvwLEMoeFUQPOdzFyc4eK-GBiVxNDI34dzo_8jbH5y1zQoEsgC93sKMrq另外解释一下,我一字不差的照搬过来并不是我懒,主要是,这玩意这没什么好写的。)

上面都是比较官方的话,接下来我想提几个我觉应该注意的问题:

1.参数返回类型:参数返回类型是CvSeq指针,CvSeq是openCV里一个很重要的数据结构,称之为“序列”,实际上类似于队列、链表这种数据结构,在后续学习笔记中我将专门探讨这种数据结构。

2.参数返回值:这里提到的返回值是针对不同的霍夫变换方法有不同的返回值,决定我们用怎样的方法来将这个返回值还原到直线。下面具体解释:

         (1)针对SHT(包括MSHT)方法,CvHoughLine2方法的返回值是直线极坐标方程的Rho、Theta参数。由于返回值是CvSeq类型,那么,我们令一个double类型的数值指针来得到这个序列中的结果:

                           double*  x = (double*)CvGetSeqElem(seq, i);

那么            

                           x[0]   -------------   Rho

                           x[1]   -------------   Theta

           那么可想而知,我们还原直线只能得到直线的方向信息,而不能得到范围信息,那么如何还原呢?主要有一下两种方法: 

               1> 
                
                如上图所示,表示的是直线可能出现的两种情况,其他情况本质上是一样的,这里不再赘述。

                第一种方法,实际上是分类讨论的思想,将特殊情况(直线平行于两坐标轴)与普通情况分开来计算,计算方法如下:

                情况1:直线平行于X轴,则令A点为(0,Rho),令B点为(img->width,Rho),直线AB即被检测直线的方向;

                情况2:直线平行于Y轴,则令A点为(Rho,0),令B点为(Rho,img->height),直线AB即被检测直线的方向;

                情况3:普通直线,令A点为(0,Rho/sin(Theta)),令B点为(0,Rho/cos(Theta)),直线AB即被检测直线的方向。

                实际上,这种方法就是通过得到被检测直线(注意这里的直线表示的就是没有范围的,只表示方向,实际上也是,线段才有范围的概念)与上图X,Y轴的交点,从而确定直线方向。初看可能很多人会误解这不就是第一张图的情况吗?其实所有的情况都是如此,直线总会与X,Y轴有交点,而交点坐标正是如上所计算。

          2>
                                   

          如图所示,我们人为设置两个比较大的数a,b(这里可以令a=b),使得图上的A,B两点计算出来再图片以外,这样可以得到A,B两点的坐标:A(X0 + b*sin(Theta)  ,  Y0 + b*cos(Theta)) B(X0 - a*sin(Theta) , Y0 - a*cos(Theta))。AB直线即检测直线的方向。
          最后上关键部分代码,并作出适当地解释:

 

          cvCvtColor(scr, gray, CV_BGR2GRAY);//转换成灰度图像

          注意:Hough变换的图像输入参数只可以接受八位图像

 

          //方法1: SHT----标准霍夫变换
 CvMemStorage* storage = cvCreateMemStorage(0);//创建一个默认大小的动态存储空间
 CvSeq* line = cvHoughLines2(gray, storage, CV_HOUGH_STANDARD, 1, CV_PI / 500, 200);//霍夫变换得到一个线的序列

 //方法2: PPHT----累计概率霍夫变换
 CvMemStorage* storage2 = cvCreateMemStorage(0);//创建一个默认大小的动态存储空间
 CvSeq* line2 = cvHoughLines2(gray, storage2, CV_HOUGH_PROBABILISTIC, 1, CV_PI / 180, 50, 100, 10);//霍夫变换得到一个线的序列

 //方法3:  SHT的多尺度变换
 CvMemStorage* storage3 = cvCreateMemStorage(0);//创建一个默认大小的动态存储空间
 CvSeq* line3 = cvHoughLines2(gray, storage3, CV_HOUGH_MULTI_SCALE, 1, CV_PI / 180, 120, 100, 10);//霍夫变换得到一个线的序列            

              
 /*
 在结果图像上画出检测的结果
 */

//对于SHT和MSHT方法来说,返回的是Rho值和theta值,如下还原
 for (int i = 0; i < MIN(line->total, 100); i++)
 {
  float* lines = (float*)cvGetSeqElem(line, i);
  float rho = lines[0];
  float theta = lines[1];
  CvPoint 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));
  cvLine(result, pt1, pt2, CV_RGB(255, 0, 0));
 }

for (int i = 0; i < line2->total; ++i)//对于PPHT方法,返回的就是直线端点的坐标。于是需要画出来就可以了
 {
  CvPoint* point = (CvPoint*)cvGetSeqElem(line2, i);
  cvLine(result2, point[0], point[1], CV_RGB(255, 0, 0));
  cout << "2 : " <<point[0].x << " " << point[0].y << endl;
  cout << point[1].x << " " << point[1].y << endl << endl;
 }

 

实验结果:

 

不妨对比一下上一个实验(自己编写的程序)的效果,openCV效果尤其是PPHT方法的效果简直是赞!

  • 大小: 3.5 KB
  • 大小: 3.9 KB
  • 大小: 5.8 KB
  • 大小: 91.7 KB
分享到:
评论

相关推荐

    OpenCV霍夫变换(Hough Transform)直线检测详解

    基本Hough变换检测直线: 由于同一条直线上的不同点在参数平面中是会经过同一个点的多条线。对图像的所有点作霍夫变换,检测直线就意味着找到对应参数平面中的直线相交最多的点。对这些交点做票数累计,然后取出票数...

    OpenCV-MinGW-Build-OpenCV-4.5.2-x64.zip

    在本压缩包“OpenCV-MinGW-Build-OpenCV-4.5.2-x64.zip”中,提供的是一份已经针对MinGW编译器优化的OpenCV 4.5.2版本,适用于64位Windows系统。 OpenCV 4.5.2是该库的一个稳定版本,它包含了众多新特性和性能提升...

    霍夫变换检测直线

    在本实验中,我们使用MATLAB实现霍夫变换检测直线。首先,我们对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像。本实验基于VS2008和OPENCV来实现。 实验的步骤如下: 1. 读入图像,转换成...

    opencv-4.5.5-1.5.7-API文档-中文版.zip

    赠送jar包:opencv-4.5.5-1.5.7.jar; 赠送原API文档:opencv-4.5.5-1.5.7-javadoc.jar; 赠送源代码:opencv-4.5.5-1.5.7-sources.jar; 赠送Maven依赖信息文件:opencv-4.5.5-1.5.7.pom; 包含翻译后的API文档:...

    OpenCV-MinGW-Build-OpenCV-4.5.0-with-contrib.zip

    OpenCV-MinGW-Build-OpenCV-4.5.0-with-contrib

    opencv-4.5.1-1.5.5-API文档-中英对照版.zip

    赠送jar包:opencv-4.5.1-1.5.5.jar; 赠送原API文档:opencv-4.5.1-1.5.5-javadoc.jar; 赠送源代码:opencv-4.5.1-1.5.5-sources.jar; 赠送Maven依赖信息文件:opencv-4.5.1-1.5.5.pom; 包含翻译后的API文档:...

    opencv4.8.0-opencv4.9.0-opencv-contrib4.8.0-opencv-contrib4.9.0

    2. opencv_contrib 4.8.0和4.9.0的源代码,包含额外的模块和实验性功能。 3. 编译脚本和配置文件,帮助用户配置和构建OpenCV库。 4. 文档和示例代码,供用户学习和参考OpenCV的使用方法。 了解并掌握OpenCV库的这两...

    OpenCV-MinGW-Build-OpenCV-4.5.0-with-contrib-32bit.zip

    这个压缩包"OpenCV-MinGW-Build-OpenCV-4.5.0-with-contrib-32bit.zip"是专为在Windows环境下使用MinGW编译器进行C++开发而准备的。MinGW(Minimalist GNU for Windows)是一个小型的GNU开发工具集,它提供了一个不...

    OpenCvSharp-4.1.0-x86-20190417.zip

    2. **LICENSE**:这是OpenCV和OpenCvSharp的许可协议文件,通常遵循BSD或MIT等开源许可,确保用户可以自由地使用、修改和分发代码,但需遵守特定的条款。 3. **README.md**:这是一个Markdown格式的文件,通常包含...

    QT+opencv霍夫直线检测,圆检测及椭圆检测

    但是,可以使用霍夫变换检测直线的思路,通过拟合多个直线来近似椭圆。或者,可以使用其他方法,如最小二乘法或直接搜索所有可能的椭圆参数,但这通常计算量较大。 在QT环境中,我们可以利用其丰富的GUI功能来显示...

    opencv-4.5.5-1.5.7-API文档-中英对照版.zip

    赠送jar包:opencv-4.5.5-1.5.7.jar; 赠送原API文档:opencv-4.5.5-1.5.7-javadoc.jar; 赠送源代码:opencv-4.5.5-1.5.7-sources.jar; 赠送Maven依赖信息文件:opencv-4.5.5-1.5.7.pom; 包含翻译后的API文档:...

    OpenCvSharp-4.5.2-20210405.rar

    OpenCvSharp-4.5.2-20210405.rar

    opencv-4.5.1-1.5.5-API文档-中文版.zip

    赠送jar包:opencv-4.5.1-1.5.5.jar; 赠送原API文档:opencv-4.5.1-1.5.5-javadoc.jar; 赠送源代码:opencv-4.5.1-1.5.5-sources.jar; 赠送Maven依赖信息文件:opencv-4.5.1-1.5.5.pom; 包含翻译后的API文档:...

    opencv-python-4.10.0.84.tar.gz

    `cv2`是`opencv-python`库的Python接口,包含了所有OpenCV的功能。使用`pip install opencv-python`即可安装这个库。在4.10.0.84版本中,可能包含了性能优化、新功能添加或已知问题的修复。由于这是一个压缩包,解压...

    android-sdk-opencv-4.5.5&opencv-contrib-4.5.5-arm64-v8a

    1.android 版的opencv-4.5.5 sdk;...2.含有opencv-contrib-4.5.5 扩展模块; 3.可以在android studio 中加载,通过java 层调用,也可以添加so库+头文件的方式在jni 层调用; 4.适用于arm64-v8a架构,即64bit cpu。

    opencv_官网 安装包 opencv-4.1.2-vc14_vc15

    opencv 安装包 opencv-4.1.2-vc14_vc15 opencv 安装包 opencv-4.1.2-vc14_vc15 opencv 安装包 opencv-4.1.2-vc14_vc15 opencv 安装包 opencv-4.1.2-vc14_vc15 opencv 安装包 opencv-4.1.2-vc14_vc15 opencv 安装包 ...

    OpenCvSharp-4.0.0-x86-20181130.zip

    2. 特征检测:如角点检测(Harris角点、Shi-Tomasi角点)、边缘检测(Canny、Sobel、Laplacian)、条纹检测、关键点检测(SIFT、SURF、ORB)等。 3. 机器学习:支持多种分类器和回归器,如支持向量机(SVM)、决策树...

    霍夫变换直线检测法粗定位身份证

    霍夫变换直线检测法是一种在图像处理中广泛使用的算法,尤其在识别图像中的直线和曲线时非常有效。在本项目中,我们利用霍夫变换来粗定位身份证在照片中的位置,这对于自动识别和处理身份证信息至关重要。在Windows...

    opencv-python 3.4.1.15 opencv-contrib-python 3.4.1.15 win64版

    opencv-python 3.4.1.15 opencv-contrib-python 3.4.1.15 win64版,opencv-python 3.4.1.15 opencv-contrib-python 3.4.1.15,支持版本:python3.4,3.5,3.6

    OpenCV3.0.0-beta版本

    3. **更丰富的算法库**:OpenCV包含了各种图像处理和计算机视觉算法,如特征检测(SIFT、SURF、ORB等)、图像分割、物体识别、人脸识别、3D重建、视频分析等,3.0.0-beta版可能增加了新的算法或优化了现有算法。...

Global site tag (gtag.js) - Google Analytics