您的位置:首页 > 其它

Hough直线检测

2016-01-10 21:07 375 查看
需求:直线检测

目的:实现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
= (float)(sin((double)ang) * irho);
tabCos
= (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
+ j * tabSin
);
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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hough 直线检测