Hough直线检测

需求:直线检测
目的:实现Hough变换
思路:y = kx + b变换成p = xcos(a) + ysin(a)
这里写图片描述

#include "cv.h"
#include "highgui.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <exception>
using namespace std;

typedef struct pLine
{
    float rho;
    float angle;
}pLine;
void hough1(CvMat *gray, float theta, float rho, int threshold, int linesMax, vector<pLine>& lines);
int main()
{
    IplImage* src = cvLoadImage("1.bmp", 1);
    const int WIDTH = src->width;
    const int HEIGHT = src->height;

    CvMat *gray = cvCreateMat(HEIGHT, WIDTH, CV_8UC1);
    CvMat *dst = cvCreateMat(HEIGHT, WIDTH, CV_8UC3);
    cvCvtColor(src, gray, CV_BGR2GRAY);
    cvCanny(gray, gray, 70, 170);

    //设置角度精度,距离精度
    float theta = 4.0f * CV_PI / 180.0f;
    float rho = 4.0f;
    int threshold = 150.0f;
    int linesMax = 350;

    vector<pLine>lines;
    hough1(gray, theta, rho, threshold, linesMax, lines);
    cout << lines.size();
    for (int i = 0; i < lines.size(); i++)
    {
        pLine line = lines[i];
        CvPoint pt1, pt2;
        double a = cos(line.angle), b = sin(line.angle);
        double x0 = a*line.rho, y0 = b*line.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));
        cvLine( src, pt1, pt2, CV_RGB(255,0,0), 3, CV_AA, 0 );
    }
    cvShowImage("SRC", src);
    cvWaitKey(0);

    return 0;
}
void hough1(CvMat *gray, float theta, float rho, int threshold, int linesMax, vector<pLine>& lines)
{
    const int WIDTH = gray->width;
    const int HEIGHT = gray->height;

    int numangle = cvRound(CV_PI / theta);;
    int numrho = cvRound(((WIDTH + HEIGHT) * 2 + 1) / rho);

    float *tabSin = new float [numangle];
    float *tabCos = new float [numangle];

    float ang = 0.0f, irho = 1.0f / rho;
    for(int n = 0; n < numangle; ang += theta, n++ )
    {
        tabSin[n] = (float)(sin((double)ang) * irho);
        tabCos[n] = (float)(cos((double)ang) * irho);
    }

    int * accum = new int [(numangle+2) * (numrho+2)];

    memset(accum, 0, (numangle+2) * (numrho+2)*sizeof(int));
    // stage 1. fill accumulator
    for(int j = 0; j < HEIGHT; j ++)
    {
        uchar* data = (uchar*)(gray->data.ptr + j * gray->step);
        for(int i = 0; i < WIDTH; i ++)
        {
            if( data[i] != 0 )
            {
                for(int n = 0; n < numangle; n++ )
                {
                    int r = cvRound( i * tabCos[n] + j * tabSin[n] );
                    r += (numrho - 1) / 2;
                    accum[(n+1) * (numrho+2) + r+1]++;
                }
            }
        }
    }
    // stage 2. find local maximums
    vector<int> sort_buf;
    for(int r = 0; r < numrho; r++ )
    {
        for(int 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.push_back(base);
        }
    }
    // stage 3. sort the detected lines by accumulator value
    int total = sort_buf.size();
    sort(sort_buf.begin(), sort_buf.end());
    reverse(sort_buf.begin(), sort_buf.end());

    int linesMax = 150;
    linesMax = MIN(linesMax, total);
    float scale = 1.0 / (numrho + 2.0);
    ;

    for (int i = 0; i < linesMax; i++)
    {
        pLine line;
        int idx = sort_buf[i];
        int n = (int)idx * scale - 1;
        int r = idx - (n+1)*(numrho+2) - 1;
        line.rho = (r - (numrho - 1)*0.5f) * rho;
        line.angle = n * theta;
        lines.push_back(line);
    }

    delete []accum;
    delete []tabCos;
    delete []tabSin;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值