您的位置:首页 > 其它

标准hough变换的具体实现

2018-01-07 15:50 204 查看
hough直线检测的原理就是采用积分图来统计直线上响应的点数,从而通过设定阈值获取响应较大的直线作为最终的直线,关于太具体的理论可自行查阅。关于hough直线检测之前也写过一篇博文hough直线检测初探,本博文也类似于之前博文,若有不当之处,望指教,谢谢!
#ifndef _HOUGH_JL_H_
#define _HOUGH_JL_H_

#include <iostream>
#include <math.h>
#include <opencv2\opencv.hpp>

using namespace std;
using namespace cv;

#define PI 3.1415926
#define UCHAR unsigned char
#define bcolor Scalar(255,0,0)
#define gcolor Scalar(0,255,0)
#define rcolor Scalar(0,0,255)

#define AngleNum 180
#define perangle (CV_PI/180)

typedef struct
{
vector<Vec4i> left_line_ePt;
vector<int> left_line_count;
vector<Vec4i> right_line_ePt;
vector<int> right_line_count;
}hough_line;

hough_line hough_standard(Mat src,Mat roi_edges, int T);

#endif;
#include "hough_JL.h"

//统计每条直线出现的频数;
hough_line hough_standard(Mat src,Mat roi_edges, int T)
{
float angle = 0.;
int dis = 0.;

Mat test = Mat::zeros(src.size(),src.type());
int len = (int)sqrt(H * H + W * W);
int numrho = int(len * 2 + 1);
int numangle = int(CV_PI / perangle);
int* left_number = (int*)malloc(numrho * numangle * sizeof(int));
int* right_number = (int*)malloc(numrho * numangle * sizeof(int));
int* left_buf = (int*)malloc(numrho * numangle * sizeof(int));
int* right_buf = (int*)malloc(numrho * numangle * sizeof(int));

for (int i = 0; i < numrho * numangle; i++)
{
left_number[i] = 0;
right_number[i] = 0;
}

//提前计算好sin和cos,避免重复计算
float* tabsin = (float*)malloc(numangle * sizeof(float));
float* tabcos = (float*)malloc(numangle * sizeof(float));

float ang = 0;
for (int i = 0; i < numangle; i++, ang += perangle)
{
tabsin[i] = float(sin(ang));
tabcos[i] = float(cos(ang));
}

//统计每条直线出现的频数;
for (int i = vanishingPt; i < roi_edges.rows - 30; i++)
{
for (int j = 0; j < roi_edges.cols; j++)
{
if (roi_edges.ptr<uchar>(i)[j])
{
for (int n = 0; n < numangle; n++)
{
if (n >= 25 && n <= 65)
{
dis = 0;
dis = (int)(i * tabsin
+ j * tabcos
);
dis += (numrho - 1) / 2;
left_number[dis * numangle + n]++;
}
else if (n >= 70 && n <= 165)
{
dis = 0;
dis = (int)(i * tabsin
+ j * tabcos
);
dis += (numrho - 1) / 2;
right_number[dis * numangle + n]++;
}
}
}
}
}

//非极大值抑制
int totall = 0;
int totalr = 0;

for (int r = 1; r < numrho - 1; r++)
{
for (int n = 1; n < numangle - 1; n++)
{
int base = r * numangle + n;
if ((left_number[base] > T) && (left_number[base] > left_number[base + 1]) && (left_number[base] > left_number[base - 1])
&& (left_number[base] > left_number[base - numangle]) && (left_number[base] > left_number[base + numangle]))
{
left_buf[totall++] = base;
}

if ((right_number[base] > T) && (right_number[base] > right_number[base + 1]) && (right_number[base] > right_number[base - 1])
&& (right_number[base] > right_number[base - numangle]) && (right_number[base] > right_number[base + numangle]))
{
right_buf[totalr++] = base;
}
}
}

//获取直线的端点;
hough_line m_lines;
const int EP = 1000;

for (int i = 0; i < totall; i++)
{
int rho = left_buf[i] / numangle;
rho = rho - (numrho - 1) / 2;
float theta = left_buf[i] % numangle * perangle;

float a = cos(theta), b = sin(theta);
float x0 = rho * a;
float y0 = rho * b;

float tao = PI / 2 + theta;
float kk = tan(tao);

float bb = y0 - kk * x0;

int yb = 0;// H - 30;
int yt = H - 1;// vanishingPt;

int xb = (yb - bb) / kk;
int xt = (yt - bb) / kk;

line(src, Point(xb, yb), Point(xt, yt), gcolor);

Vec4i vec;
vec[0] = xb;
vec[1] = yb;
vec[2] = xt;
vec[3] = yt;

m_lines.left_line_ePt.push_back(vec);
m_lines.left_line_count.push_back(left_number[left_buf[i]]);
}

for (int i = 0; i < totalr; i++)
{
int rho = right_buf[i] / numangle;
rho = rho - (numrho - 1) / 2;
float theta = right_buf[i] % numangle * perangle;

float a = cos(theta), b = sin(theta);
float x0 = rho * a;
float y0 = rho * b;

float tao = PI / 2 + theta;
float kk = tan(tao);

float bb = y0 - kk * x0;

int yb = 0;// H - 30;
int yt = H;// vanishingPt;

int xb = (yb - bb) / kk;
int xt = (yt - bb) / kk;

line(src, Point(xb, yb), Point(xt, yt), gcolor);

Vec4i vec;
vec[0] = xb;
vec[1] = yb;
vec[2] = xt;
vec[3] = yt;

m_lines.left_line_ePt.push_back(vec);
m_lines.left_line_count.push_back(right_number[right_buf[i]]);
}

free(left_number);
free(right_number);
free(tabsin);
free(tabcos);
free(left_buf);
free(right_buf);

imshow("src",src);
waitKey(10);

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