数字图像处理成长之路8:霍夫线变换

来源:互联网 发布:淘宝上怎么买到电视棒 编辑:程序博客网 时间:2024/06/14 21:46

霍夫线变换

霍夫变换是图像分析,机器视觉,数字图像处理中常用的处理方法。这种方法能从图像中分离出一些特定的形状的图形。经典的霍夫变换研究的是如何在图像中分离出直线,随着研究的深入,霍夫变换可以分离出图像中的圆,椭圆,甚至是任意形状。


原理

如果给定一条直线,y= k * x+b,则直线上所有点都满足这个公式,如(x0,y0)。相反地,如果给定一个点(x0,y0),则所有过这个点的直线都满足,y0= k0 * x0 +b0。同样的,对于给定一点(x1,y1),则过这个点的所有直线满足y1= k1* x1 +b1。同理,对于任意点(x2,y2)y2= k2 * x2 +b2。其中,k0k1k2b0b1b2,均为变量。如果(x0,y0)(x1,y1)(x2,y2)在一条直线上,则必存在某一斜率和截距,使k0= k1 = k2b0= b1 = b2

c++算法

for(int x = 0; x < width; x++)//遍历图像每个点,        for (int y = 0; y < height; y++)        {            if (tmpMat.at<uchar>(y,x))//因为图像经过canny边缘处理,因此像素值不为零的点对我们才有意义            {                cqHoughPoint hough;//把不为零的点保存起来,记住它们的坐标,以待后面进一步处理                hough._x = x;                hough._y = y;                for (int theta = minTheta +1; theta < maxTheta; theta++) //假设每个点都有180条直线穿过                {                    hough._theta[theta] =  tmpMat.at<uchar>(y,x) - x * tan(theta);//记录每个角度对应的直线的截距                }                cqHoughPointVector.push_back(hough); //把每个像素坐标,及每个像素所对应的180条直线(包含180个角和截距)保存在一个结构体对象中, }                                                                                                  //然后把结构体对象一一入向来容器保存。        }



    vector <cqHoughPoints> cqHoughPointsVector;//每个cqHoughPoints 结构体里保存着几个点,这几个点在一条直线上    for (int theta = minTheta +1; theta < maxTheta; theta++)//从0度开始,计算每一个角度下,有多少点的截距相同    {        for (vector<cqHoughPoint>::iterator iter = cqHoughPointVector.begin();             iter != cqHoughPointVector.end();             iter++)        {            cqHoughPoints houghPoints;//one houghPoints include several points ,these points are in one line.            houghPoints.counter++;            houghPoints._Points.push_back(cqPoint(iter->_x, iter->_y ));            for (vector<cqHoughPoint>::iterator iterj = cqHoughPointVector.begin();                 iterj !=  cqHoughPointVector.end();                 iterj++)// find the point that value of b equl to iteri            {                if (iter->_theta == iterj->_theta)                {                    houghPoints.counter++;                    houghPoints._Points.push_back(cqPoint(iterj->_x, iterj->_y));                }            }            /*            if (houghPoints.counter > 2) //3个点截距相同,才说名这三个点在一条直线上            {                cqHoughPointsVector.push_back(houghPoints);                for (vector<cqPoint>::iterator i = houghPoints._Points.begin();                     i != houghPoints._Points.end();                     i++)                    tmpMat.at<uchar>(i->_y, i->_x) = 250;//用高亮代替画直线            }            */            //draw        }    }
struct cqPoint//点结构{    int _x;    int _y;    cqPoint(int x, int y)    {        _x = x;        _y = y;     }};struct cqHoughPoint//每个点的角度和截距信息{    int _x;    int _y;    int _theta[180];};struct cqHoughPoints//用来保存在一条直线上的点{    int counter = 0;    vector <cqPoint> _Points;};


这是一个示例程序,它存在几个问题

1)执行速度慢

2)并没有验证程序算法是否争取,只是把自己的思路整理了出来,以后有时间在求改进

原创粉丝点击