标准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;
#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变换实现直线检测的代码
- opencv+vs2008实现canny边缘检测与hough变换检测直线并用红线在原图标出直线
- Hough变换的实现
- OpenCV2马拉松第22圈——Hough变换直线检測原理与实现
- Hough变换以及C实现
- OpenCV2马拉松第22圈——Hough变换直线检测原理与实现
- 图像进行Sobel算子、Hough变换检测圆的matlab实现
- OpenCV实现Hough变换检测圆形
- 直线hough变换原理及实现
- opencv中标准Hough变换检测出的直线参数
- hough变换 正在的c代码风格实现
- C实现hough变换拟合直线
- Hough变换 直线检测原理及其Matlab实现
- Hough变换的C实现
- MATLAB 实现Hough变换
- Matlab实现Hough变换检测图像中的直线 分类: 图像处理 2014-06-14 22:07 641人阅读 评论(0) 收藏
- Hough变换实现图像纠偏-从matlab到c++实现
- 利用Hough变换实现直线检测的代码
- Matlab实现Hough变换检测图像中的直线
- 利用Hough变换实现直线检测的代码