Opencv2.4.9函数函数HoughLinesP分析分析
标准霍夫变换本质上是把图像映射到它的参数空间上,它需要计算所有的M个边缘点,这样它的运算量和所需内存空间都会很
大。如果在输入图像中只是处理m(m<M)个边缘点,则这m个边缘点的选取是具有一定概率性的,因此该方法被称为概率霍
夫变换(Probabilistic Hough Transform)。该方法还有一个重要的特点就是能够检测出线端,即能够检测出图像中直线的两
个端点,确切地定位图像中的直线。
HoughLinesP函数就是利用概率霍夫变换来检测直线的。它的一般步骤为:
1、随机抽取图像中的一个特征点,即边缘点,如果该点已经被标定为是某一条直线上的点,则继续在剩下的边缘点中随机抽
取一个边缘点,直到所有边缘点都抽取完了为止;
2、对该点进行霍夫变换,并进行累加和计算;
3、选取在霍夫空间内值最大的点,如果该点大于阈值的,则进行步骤4,否则回到步骤1;
4、根据霍夫变换得到的最大值,从该点出发,沿着直线的方向位移,从而找到直线的两个端点;
5、计算直线的长度,如果大于某个阈值,则被认为是好的直线输出,回到步骤1。
HoughLinesP函数的原型为:
void HoughLinesP(InputArray image,OutputArray lines, double rho, double theta, int threshold, double
minLineLength=0,double maxLineGap=0 )
image为输入图像,要求是8位单通道图像
lines为输出的直线向量,每条线用4个元素表示,即直线的两个端点的4个坐标值
rho和theta分别为距离和角度的分辨率
threshold为阈值,即步骤3中的阈值
minLineLength为最小直线长度,在步骤5中要用到,即如果小于该值,则不被认为是一条直线
maxLineGap为最大直线间隙,在步骤4中要用到,即如果有两条线段是在一条直线上,但它们之间因为有间隙,所以被认为
是两个线段,如果这个间隙大于该值,则被认为是两条线段,否则是一条。
HoughLinesP函数是在sources/modules/imgproc/src/hough.cpp文件中被定义的:
void cv::HoughLinesP( InputArray _image, OutputArray _lines,
double rho, double theta, int threshold,
double minLineLength, double maxGap )
{
Ptr<CvMemStorage> storage = cvCreateMemStorage(STORAGE_SIZE);
Mat image = _image.getMat();
CvMat c_image = image;
CvSeq* seq = cvHoughLines2( &c_image, storage, CV_HOUGH_PROBABILISTIC,
rho, theta, threshold, minLineLength, maxGap );
seqToMat(seq, _lines);
}
从HoughLinesP函数可以看出,该函数会调用cvHoughLines2函数。它通过参数CV_HOUGH_PROBABILISTIC,最终调用了
icvHoughLinesProbabilistic函数:
static void
icvHoughLinesProbabilistic( CvMat* image,
float rho, float theta, int threshold,
int lineLength, int lineGap,
CvSeq *lines, int linesMax )
{
//accum为累加器矩阵,mask为掩码矩阵
cv::Mat accum, mask;
cv::vector<float> trigtab; //用于存储事先计算好的正弦和余弦值
//开辟一段内存空间
cv::MemStorage storage(cvCreateMemStorage(0));
//用于存储特征点坐标,即边缘像素的位置
CvSeq* seq;
CvSeqWriter writer;
int width, height; //图像的宽和高
int numangle, numrho; //角度和距离的离散数量
float ang;
int r, n, count;