图像的Hough直线检测之c++实现(qt + 不调包)

1.基本原理

    在平面直角坐标系中,直线可以用y=k*x + b表示,在下图中,如果假设以O为原点,x轴为极坐标轴,并且OA与极坐标轴的夹角为\theta,那么点A可由极坐标\left ( \rho, \right \theta )表示,经过一系列公式转换可得\rho = y*sin(\theta ) + x*cos(\theta ),任意一组\left ( \rho, \right \theta )可以确定一条直线,检测直线主要是以下几步:

    1)建立一个二维数组houghbuf[360][p],其中p的长度为图像对角线长度(对应着\rho),其中360°(对应着\theta

    2)循环遍历图像的坐标(x,y)的时候,\theta也同时由0-360取值遍历,并代入公式\rho = y*sin(\theta ) + x*cos(\theta ),根据\left ( \rho, \right \theta )来累加(1)中的二维数组,同一条线上的点,会被累加到一起

    3)取阈值,有多少个点在一条线上,则认为这是一条线

图像的Hough直线检测之c++实现(qt + 不调包)_第1张图片

2.代码实现(代码是我以前自学图像处理时写的,代码很粗糙没做任何优化,但很好理解

 //先用边缘检测生成图像,再hough变换
QImage* MainWindow:: HoughLine(QImage* image)
{
    double sinValue[360];
    double cosValue[360];
    int k = 100;
    double scale=1;
    int p = (int)(sqrt(double(image->width()*image->width() + image->height()*image->height())+1));
    QImage* newImage = new QImage(360,p,QImage::Format_ARGB32);
    QColor color;
    int houghbuf[360][p];

    memset(houghbuf,0,sizeof(int)*360*p);//必须清0
    for(int i = 0;i<360;i++)
    {
        sinValue[i] = sin(i*3.1415926/180);
        cosValue[i] = cos(i*3.1415926/180);
    }
    int tp;
    for(int y =0;yheight();y++)
    {
        for(int x =0;xwidth();x++)
        {
            color = QColor(image->pixel(x,y));
            for(int i = 0;i<360;i++)
            {
                if(color.red() > k)
                {
                    tp = (int)(x*sinValue[i] + y*cosValue[i]);
                    if(tp<0||houghbuf[i][tp]==255) continue;
                    houghbuf[i][tp]+=scale;
                }
            }
        }
    }
    for(int i = 0;i<360;i++)
    {
        for(int j = 0;jsetPixel(i,j,qRgb(houghbuf[i][j],houghbuf[i][j],houghbuf[i][j]));
        }
    }
    return newImage;
}


//先用边缘检测生成图像,接着hough变换,再滤波,最后画出直线 ,其中k1取值3000
QImage* MainWindow:: DrawLine(QImage* image,QImage* image1,int k1)
{
    double sinValue[360];
    double cosValue[360];
    int k = 100;
    double scale=1;
    int p = (int)(sqrt(double(image->width()*image->width() + image->height()*image->height())+1));
    QImage* newImage = new QImage(360,p,QImage::Format_ARGB32);
    QColor color;
    int houghbuf[360][p];

    memset(houghbuf,0,sizeof(int)*360*p);//必须清0
    for(int i = 0;i<360;i++)
    {
        sinValue[i] = sin(i*3.1415926/180);
        cosValue[i] = cos(i*3.1415926/180);
    }
    int tp;
    for(int y =0;yheight();y++)
    {
        for(int x =0;xwidth();x++)
        {
            color = QColor(image->pixel(x,y));
            for(int i = 0;i<360;i++)
            {
                if(color.red() > k)
                {
                    tp = (int)(x*sinValue[i] + y*cosValue[i]);
                    if(tp<0||houghbuf[i][tp]==255) continue;
                    houghbuf[i][tp]+=scale;
                }
            }
        }
    }
    for(int i = 0;i<360;i++)
    {
        for(int j = 0;jsetPixel(i,j,qRgb(houghbuf[i][j],houghbuf[i][j],houghbuf[i][j]));
        }
    }

    int tmplt[5][5]={
        {-2,-2,-2,-2,-2},
        {-2,0,4,0,-2},
        {-2,4,16,4,-2},
        {-2,0,4,0,-2},
        {-2,-2,-2,-2,-2}
    };
    int templtsize = 5;
    double kk,bb;
    int xx,yy;
    for(int x = 0;x<360;x++)
   {
      for(int y= 0;ypixel(px1,py1));
                  r+=color.red()*tmplt[i][j];
                  g+=color.green()*tmplt[i][j];
                  b+=color.blue()*tmplt[i][j];
               }
           }
           if(r>k1)
           {
               if(x!=90)
               {
                   bb = y/cos(x*3.1415926535/180);
                   kk = -sin(x*3.1415926535/180)/cos(x*3.1415926535/180);
                   yy =0;
                   xx =0;
                   if(abs(kk)<=1)
                   {
                       for(xx =0;xxwidth();xx++)
                       {
                           yy=(int)(kk*xx+bb);
                           if(yy>=0 && yyheight())
                           {
                               r = 255;
                               g = 0;
                               b = 0;
                               image1->setPixel(xx,yy,qRgb( r,g,b));
                           }
                       }
                   }
                   else
                   {
                       for(yy =0;yyheight();yy++)
                       {
                           xx=(int)(yy/kk - bb/kk);
                           if(xx>=0 && xxwidth())
                           {
                               r = 255;
                               g = 0;
                               b = 0;
                               image1->setPixel(xx,yy,qRgb( r,g,b));
                           }
                       }
                   }
               }
               else
               {
                   for(yy=0;yyheight();yy++)
                   {
                       r = 255;
                       g = 0;
                       b = 0;
                       image1->setPixel(x,yy,qRgb( r,g,b));
                   }
               }

           }
       }
   }
    delete newImage;
    return   image1;
}

3.参考资料

    数字图像处理——技术详解与Visual C++实践(左飞等著),写代码与写博客的时间相差两年,至于还参考其他的资料不,我已经忘记了,如若需要,我可以补上去

你可能感兴趣的:(c++基本图像处理算法)