Opencv2.4.9函数HoughLinesP分析

  

标准霍夫变换本质上是把图像映射到它的参数空间上,它需要计算所有的M个边缘点,这样它的运算量和所需内存空间都会很大。如果在输入图像中只是处理M (m<米)个边缘点,则这M个边缘点的选取是具有一定概率性的,因此该方法被称为概率霍夫变换(概率霍夫变换)。该方法还有一个重要的特点就是能够检测出线端,即能够检测出图像中直线的两个端点,确切地定位图像中的直线。

  

HoughLinesP函数就是利用概率霍夫变换来检测直线的。它的一般步骤为:

  

1,随机抽取图像中的一个特征点,即边缘点,如果该点已经被标定为是某一条直线上的点,则继续在剩下的边缘点中随机抽取一个边缘点,直到所有边缘点都抽取完了为止;

  

2,对该点进行霍夫变换,并进行累加和计算,

  

3,选取在霍夫空间内值最大的点,如果该点大于阈值的,则进行步骤,否则回到步骤1;

  

4,根据霍夫变换得到的最大值,从该点出发,沿着直线的方向位移,从而找到直线的两个端点;

  

5,计算直线的长度,如果大于某个阈值,则被认为是好的直线输出,回到步骤1 .

  

HoughLinesP函数的原型为:

  

空白HoughLinesP (InputArray形象,OutputArray线、双ρ,双θ,int阈值,双minLineLength=0,双maxLineGap=0)

  

图像为输入图像,要求是8位单通道图像

  

线为输出的直线向量,每条线用4个元素表示,即直线的两个端点的4个坐标值

  

ρ和θ分别为距离和角度的分辨率

  

阈值为阈值,即步骤3中的阈值

  

minLineLength为最小直线长度,在步骤5中要用的到,即如果小于该值,则不被认为是一条直线

  

maxLineGap为最大直线间隙,在步骤4中要用的到,即如果有两条线段是在一条直线上,但它们之间因为有间隙,所以被认为是两个线段,如果这个间隙大于该值,则被认为是两条线段,否则是一条。

  

HoughLinesP函数是在来源/模块/imgproc/src/hough.cpp文件中被定义的:

        空白的简历::HoughLinesP (InputArray _image, OutputArray _lines,   双ρ,双θ,int阈值,   双minLineLength,双maxGap)   {   Ptr存储=cvCreateMemStorage (STORAGE_SIZE);   垫图像=_image.getMat ();   CvMat c_image=图像;   CvSeq * seq=cvHoughLines2 (CV_HOUGH_PROBABILISTIC及c_image、存储,   ρ,θ,阈值、minLineLength maxGap);   seqToMat (seq, _lines);   }      

从HoughLinesP函数可以看的出,该函数会调用cvHoughLines2函数。它通过参数CV_HOUGH_PROBABILISTIC,最终调用了icvHoughLinesProbabilistic函数:
  

        静态的空白   icvHoughLinesProbabilistic (CvMat *形象,   ρ浮动,浮动θ,int阈值,   int lineLength, int lineGap   CvSeq *线,int linesMax)   {//accum为累加器矩阵,面具为掩码矩阵   简历:垫accum面具;   简历:vectortrigtab;//用于存储事先计算好的正弦和余弦值//开辟一段内存空间   简历:MemStorage存储(cvCreateMemStorage (0));//用于存储特征点坐标,即边缘像素的位置   CvSeq * seq;   CvSeqWriter作家;   int宽度、高度;//图像的宽和高   int numangle numrho;//角度和距离的离散数量   和浮动;   int r, n,计数;   CvPoint pt;   浮动irhoρ=1/;//距离分辨率的倒数   CvRNG rng=CvRNG (1);//随机数   const浮* ttab;//向量trigtab的地址指针   uchar * mdata0;//矩阵面具的地址指针//确保输入图像的正确性   CV_Assert (CV_IS_MAT(图片),,CV_MAT_TYPE(图片→类型)==CV_8UC1);      图像宽度=乜?//提取出输入图像的宽   身高=形象→行;//提取出输入图像的高//由角度和距离分辨率,得到角度和距离的离散数量   numangle=cvRound (CV_PI/θ);   numrho=cvRound(((宽+高)* 2 + 1)/ρ);//创建累加器矩阵,即霍夫空间   accum.create (numangle numrho CV_32SC1);//创建掩码矩阵,大小与输入图像相同   面具。创建(高度、宽度、CV_8UC1);//定义trigtab的大小,因为要存储正弦和余弦值,所以长度为角度离散数的2倍   trigtab.resize (numangle * 2);//累加器矩阵清零   accum=简历::标量(0);//避免重复计算,事先计算好所需的所有正弦和余弦值   (ang=0, n=0;n & lt;numangle;和+=θ,n + +)   {   trigtab [n * 2]=(浮动)(cos (ang) * irho);   trigtab [n * 2 + 1]=(浮动)(sin (ang) * irho);   }//赋值首地址   ttab=, trigtab [0];   mdata0=mask.data;//开始写入序列   cvStartWriteSeq (CV_32SC2 sizeof (CvSeq), sizeof (CvPoint)、存储、及作家);//第1阶段。收集非零像点//收集图像中的所有非零的点,因为输入图像是边缘图像,所以非零点就是边缘点   (pt.y=0,数=0;pt.y & lt;高度;pt.y + +)   {//提取出输入图像和掩码矩阵的每行地址指针   const uchar *数据=https://www.yisu.com/zixun/image-> data.ptr + pt.y *图像->步骤;   uchar * mdata=mdata0 + pt.y *宽度;   (pt.x=0;pt.x

Opencv2.4.9函数HoughLinesP分析