Hough变换原理

博客里面编辑数学公式太麻烦了,还是截图吧,自己写的,有不严谨的地方还望多多指教。
这里写图片描述
这里写图片描述

标准hough变换源码:

static void icvHoughLinesStandard(const CvMat* img, float rho, float theta,int threshold, CvSeq *lines, int linesMax)
{
    cv::AutoBuffer<int> _accum, _sort_buf;    // _accum:计数用数组,_sort_buf,排序用数组
    cv::AutoBuffer<float> _tabSin, _tabCos;   // 提前计算sin与cos值,避免重复计算带来的计算性能下降

    const uchar* image;
    int step, width, height;
    int numangle, numrho;
    int total = 0;
    float ang;
    int r, n;
    int i, j;
    float irho = 1 / rho;   // rho指像素精度,常取1,因此irho常为1
    double scale;

    CV_Assert(CV_IS_MAT(img) && CV_MAT_TYPE(img->type) == CV_8UC1);

    image = img->data.ptr;
    step = img->step;
    width = img->cols;
    height = img->rows;

    numangle = cvRound(CV_PI / theta);  // 根据th精度计算th维度的长度
    numrho = cvRound(((width + height) * 2 + 1) / rho);  // 根据r精度计算r维度的长度

    _accum.allocate((numangle + 2) * (numrho + 2));
    _sort_buf.allocate(numangle * numrho);
    _tabSin.allocate(numangle);
    _tabCos.allocate(numangle);
    int *accum = _accum, *sort_buf = _sort_buf;
    float *tabSin = _tabSin, *tabCos = _tabCos;

    memset(accum, 0, sizeof(accum[0]) * (numangle + 2) * (numrho + 2));

    for (ang = 0, n = 0; n < numangle; ang += theta, n++)   // 计算三角函数表,避免重复计算
    {
        tabSin[n] = (float)(sin(ang) * irho);
        tabCos[n] = (float)(cos(ang) * irho);
    }

    // stage 1. fill accumulator 
    for (i = 0; i < height; i++)
    for (j = 0; j < width; j++)
    {
        if (image[i * step + j] != 0)
        for (n = 0; n < numangle; n++)
        {
            r = cvRound(j * tabCos[n] + i * tabSin[n]);  // Hough极坐标变换式
            r += (numrho - 1) / 2;
            accum[(n + 1) * (numrho + 2) + r + 1]++;  // 计数器统计
        }
    }

    // stage 2. find local maximums
    for (r = 0; r < numrho; r++)
    for (n = 0; n < numangle; n++)
    {
        int base = (n + 1) * (numrho + 2) + r + 1;
        if (accum[base] > threshold       // 大于阈值,且是局部极大值
            && accum[base] > accum[base - 1]
            && accum[base] >= accum[base + 1]
            && accum[base] > accum[base - numrho - 2]
            && accum[base] >= accum[base + numrho + 2])
            sort_buf[total++] = base;
    }

    // stage 3. sort the detected lines by accumulator value
    icvHoughSortDescent32s(sort_buf, total, accum);

    // stage 4. store the first min(total,linesMax) lines to the output buffer
    linesMax = MIN(linesMax, total);  // linesMax是输入参数,表示最多输出多少个直线参数
    scale = 1. / (numrho + 2);
    for (i = 0; i < linesMax; i++)
    {
        CvLinePolar line;           // 输出结构,就是(r,theta)
        int idx = sort_buf[i];
        int n = cvFloor(idx*scale) - 1;
        int r = idx - (n + 1)*(numrho + 2) - 1;
        line.rho = (r - (numrho - 1)*0.5f) * rho;
        line.angle = n * theta;
        cvSeqPush(lines, &line);  // 确定的直线入队列输出
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值