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

1.基本原理

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

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

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

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

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;y<image->height();y++)
    {
        for(int x =0;x<image->width();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;j<p;j++)
        {
            newImage->setPixel(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;y<image->height();y++)
    {
        for(int x =0;x<image->width();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;j<p;j++)
        {
            newImage->setPixel(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;y<p;y++)
       {
           int r = 0;
           int g = 0;
           int b = 0;
           int px1 = 0;
           int py1 = 0;
           for(int i = 0;i<templtsize;i++)
           {
              for(int j = 0;j<templtsize;j++)
               {
                  py1=(y-templtsize/2+i+p)%p;
                  px1=(x-templtsize/2+j+360)%360;
                  color = QColor(newImage->pixel(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;xx<image->width();xx++)
                       {
                           yy=(int)(kk*xx+bb);
                           if(yy>=0 && yy<image->height())
                           {
                               r = 255;
                               g = 0;
                               b = 0;
                               image1->setPixel(xx,yy,qRgb( r,g,b));
                           }
                       }
                   }
                   else
                   {
                       for(yy =0;yy<image->height();yy++)
                       {
                           xx=(int)(yy/kk - bb/kk);
                           if(xx>=0 && xx<image->width())
                           {
                               r = 255;
                               g = 0;
                               b = 0;
                               image1->setPixel(xx,yy,qRgb( r,g,b));
                           }
                       }
                   }
               }
               else
               {
                   for(yy=0;yy<image->height();yy++)
                   {
                       r = 255;
                       g = 0;
                       b = 0;
                       image1->setPixel(x,yy,qRgb( r,g,b));
                   }
               }

           }
       }
   }
    delete newImage;
    return   image1;
}

3.下载路径

   整个系列链接: https://blog.csdn.net/m0_59023219/category_12425183.html

   内容介绍:

  [1]根据算法原理,编写纯c++源码,不调用外源库opencv 等;
  [2]包括各种图像处理的基本算法,包含腐蚀膨胀,缩放,转置,镜像,平移,均衡变化,灰度拉升,灰度阈值,灰度非线性,转灰度,灰度线性,旋转,简单平滑,高斯平滑,轮廓跟踪,种子算法,hough直线检测,拉普拉斯,带方向边缘检测,常规边缘检测(梯度算子、Roberts算子和Sobel算子),中值滤波,反色操作等;
  [3]程序中有完整的注释,便于大家很好理解代码。

   代码下载路径:基于QT的C++多种图像处理基本算法源码

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值