opencv笔记(5):Hough变换

六、Hough变换

1.Hough线变换

Hough线变换是一种用来寻找直线的方法。首先要对图像进行边缘检测处理,Hough线变换的直接输入只能是边缘的二值图像。
  • 标准霍夫变换(HoughLines函数)
  • 多尺度霍夫变换(HoughLines函数)
  • 累计概率霍夫变换(HoughLinesP函数)
1.首先对于一个点 ,通过这个点的直线定义为:
2.而对于一个定点,则可以 画出所有通过此点的线,例如点(8,6)则有:

3.继续对其他点进行画图,则有:
4.而三条线相交的一点,则是三条线的共同参数,表明三点在同一条直线上。
5.于是,可以通过寻找在平面交于一点的曲线数量来检测同一条直线上的点。之后通过设置阈值来定义相交点是否满足条件。
6.若交于一点的曲线数量超过阈值,那么可以认为这个交点所代表的参数对在原图中为一条直线。

1.1HoughLines()函数

void HoughLines(InputArray image,
OutputArray lines, 
double rho, 
double theta, 
int threshold, 
double srn=0, 
double stn=0 )  
参数1:输入图像。
参数2:存储了检测的线条的输出矢量。每条直线由具有两个元素的矢量表示。
参数3:以像素为单位的距离精度。
参数4:以弧度为单位的角度精度。
参数5:阈值。
参数6:对于多尺度的霍夫变换,这是第三个参数进步尺寸rho的除数距离。粗略的累加器进步尺寸直接是第三个参数rho,而精确的累加器进步尺寸为rho/srn。
参数7:对于多尺度霍夫变换,srn表示第四个参数进步尺寸的单位角度theta的除数距离。且如果srn和stn同时为0,就表示使用经典的霍夫变换。否则,这两个参数应该都为正数。

int main( )  
{  
    //【1】载入原始图和Mat变量定义     
    Mat srcImage = imread("1.jpg"); 
    Mat midImage,dstImage;//临时变量和目标图的定义  
  
    //【2】进行边缘检测和转化为灰度图  
    Canny(srcImage, midImage, 50, 200, 3);//进行一此canny边缘检测  
    cvtColor(midImage,dstImage, CV_GRAY2BGR);//转化边缘检测后的图为灰度图  
  
    //【3】进行霍夫线变换  
    vector<Vec2f> lines;//定义一个矢量结构lines用于存放得到的线段矢量集合  
    HoughLines(midImage, lines, 1, CV_PI/180, 150, 0, 0 );  
  
    //【4】依次在图中绘制出每条线段  
    for( size_t i = 0; i < lines.size(); i++ )  
    {  
        float rho = lines[i][0], theta = lines[i][1];  
        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));  
        line( dstImage, pt1, pt2, Scalar(55,100,195), 1, CV_AA);  
    }  
  
    //【5】显示原始图    
    imshow("【原始图】", srcImage);    
  
    //【6】边缘检测后的图   
    imshow("【边缘检测后的图】", midImage);    
  
    //【7】显示效果图    
    imshow("【效果图】", dstImage);    
  
    waitKey(0);    
  
    return 0;    
}  

1.2HoughLinesP()函数

void HoughLinesP(InputArray image,
OutputArray lines,
double rho, 
double theta,
int threshold, 
double minLineLength=0,
double maxLineGap=0 )
参数1:输入图像。
参数2:存储线条的输出矢量。
参数3:以像素为单位的距离精度。
参数4:以弧度为单位的角度精度。
参数5:阈值。
参数6:最低线段的长度,默认值为0。
参数7:同一行点与点之间连接起来的最大距离,默认值为0。

int main( )  
{  
    //【1】载入原始图和Mat变量定义     
    Mat srcImage = imread("1.jpg"); 
    Mat midImage,dstImage;//临时变量和目标图的定义  
  
    //【2】进行边缘检测和转化为灰度图  
    Canny(srcImage, midImage, 50, 200, 3);//进行一此canny边缘检测  
    cvtColor(midImage,dstImage, CV_GRAY2BGR);//转化边缘检测后的图为灰度图  
  
    //【3】进行霍夫线变换  
    vector<Vec4i> lines;//定义一个矢量结构lines用于存放得到的线段矢量集合  
    HoughLinesP(midImage, lines, 1, CV_PI/180, 80, 50, 10 );  
  
    //【4】依次在图中绘制出每条线段  
    for( size_t i = 0; i < lines.size(); i++ )  
    {  
        Vec4i l = lines[i];  
        line( dstImage, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(186,88,255), 1, CV_AA);  
    }  
  
    //【5】显示原始图    
    imshow("【原始图】", srcImage);    
  
    //【6】边缘检测后的图   
    imshow("【边缘检测后的图】", midImage);    
  
    //【7】显示效果图    
    imshow("【效果图】", dstImage);    
  
    waitKey(0);    
  
    return 0;    
}  

2.Hough圆变换

霍夫梯度法原理:
1.对图像进行边缘检测。
2.对边缘图像中的每一个非零点,考虑其局部梯度,即用Sobel()函数计算X和Y方向的一阶导数得到梯度。
3.利用得到的梯度,由斜率指定的直线上的每一个点都在累加器中被累加。斜率指的是从一个指定的最小值到指定的最大值的距离。
4.标记图像中每一个非0像素的位置。
5.从二维累加器中这些点钟选择候选的中心,这些中心都大于给定阈值并且大于其所有近邻。这些候选中心按照累加值降序排列,以便于最支持像素的中心首先出现。
6.对每个中心,考虑所有的非0像素。
7.这些像素按照其与中心的距离排序。从最大半径的最小距离算起,选择非0像素最支持的一条半径。
8.如果一个中心收到边缘图像非0像素的最充分支持,并且前期被选择的中心有足够的距离,那么它就会被保留下来。

void HoughCircles(InputArray image,
OutputArray circles,
int method, 
double dp, 
double minDist,
double param1=100,
double param2=100,
int minRadius=0,
int maxRadius=0 )
参数1:输入像素。
参数2:存储检测圆的矢量,每个矢量由包含了3个元素的浮点矢量(x,y,radius)表示。
参数3:检测方法,目前使用CV_HOUGH_GRADIENT。
参数4:若dp=1,累加器和输入图像具有相同的分辨率;若dp=2,累加器只有输入图像的一半那么大的宽度和高度。即输入图像与累加器大小的比值。
参数5:区分两个不同检测到的圆之间的最小距离。
参数6:检测方法的参数,即canny检测算子的高阈值,而低阈值为高阈值的一半。
参数7:检测方法的参数,为检测阶段圆心的累加器阈值。越小就可以检测到更多的圆甚至不存在的圆,越大则通过的圆就越接近完美的圆形。
参数8:圆半径最小值,默认值为0。
参数9:圆半径最大值,默认值为0。

int main( )  
{  
    //【1】载入原始图和Mat变量定义     
    Mat srcImage = imread("1.jpg");
    Mat midImage,dstImage;//临时变量和目标图的定义  
  
    //【2】显示原始图  
    imshow("【原始图】", srcImage);    
  
    //【3】转为灰度图,进行图像平滑  
    cvtColor(srcImage,midImage, CV_BGR2GRAY);//转化边缘检测后的图为灰度图  
    GaussianBlur( midImage, midImage, Size(9, 9), 2, 2 );  
  
    //【4】进行霍夫圆变换  
    vector<Vec3f> circles;  
    HoughCircles( midImage, circles, CV_HOUGH_GRADIENT,1.5, 10, 200, 100, 0, 0 );  
  
    //【5】依次在图中绘制出圆  
    for( size_t i = 0; i < circles.size(); i++ )  
    {  
        Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));  
        int radius = cvRound(circles[i][2]);  
        //绘制圆心  
        circle( srcImage, center, 3, Scalar(0,255,0), -1, 8, 0 );  
        //绘制圆轮廓  
        circle( srcImage, center, radius, Scalar(155,50,255), 3, 8, 0 );  
    }  
  
    //【6】显示效果图    
    imshow("【效果图】", srcImage);    
  
    waitKey(0);    
  
    return 0;    
} 


特别说明:本文为本人学习opencv所做笔记。具体参照:http://blog.csdn.net/column/details/opencv-tutorial.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值