您的位置:首页 > 运维架构

opencv之7.3霍夫变换

2017-10-23 22:51 337 查看
霍夫变换可以实现任何由参数方程描述的几何体的检测。

1.检测直线

原理:霍夫变换基于二值图像,寻找经过每个单独像素点的所有直线,当直线经过足够多的像素点,则这个直线的存在足够明显。

void HoughLines( InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn = 0, double stn = 0, double min_theta = 0, double max_theta = CV_PI );

代码:

Mat image, result, result2;
image = imread("D:/road.jpg", 0);
Canny(image, result, 120, 200);
namedWindow("Canny");
imshow("Canny", result);

/*vector<Vec2f> lines;                                      //lines为二维向量,vector<Vec2f>定义二维浮点向量
HoughLines(result, lines, 1, PI/ 180, 120);                 //霍夫变换
vector<Vec2f>::iterator it = lines.begin();
while (it != lines.end())
{
float rho = (*it)[0];
float theta = (*it)[1];
if (theta < PI / 4 || theta>3 * PI / 4)                 //这个是优化
{
Point ptr1(rho / cos(theta), 0);
Point ptr2((rho - result.rows*sin(theta))
/ cos(theta), result.rows);
line(result, ptr1, ptr2, Scalar(255,0,0));          //
}
else
{
Point ptr1(0, rho / sin(theta));
Point ptr2(result.cols, (rho - result.cols*sin(theta)) / cos(theta));
line(result, ptr1, ptr2, Scalar(255,255,0));
}
it++;
}
namedWindow("hough");
imshow("hough", result);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30


[/code]

概率霍夫检测:不再逐行扫描图像,随机选择像素。一旦累加器达到阈值,则移除直线所经过的像素点,并接受线段的长度。
void HoughLinesP( InputArray image, OutputArray lines,double rho, double theta, int threshold,double minLineLength = 0, double maxLineGap = 0 );
minLineLength表示接受线段的最小长度,maxLineGap表示像素点的最大距离。
代码:
LineFinder.h头文件:


#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#define PI 3.141591653
using namespace std;
using namespace cv;

class LineFinder
{
private:
Mat image;
vector<Vec4f> lines;
double deltaRho, deltatheta;
int minVote;
double minLength;
double maxGap;

public:
LineFinder() :deltaRho(1), deltatheta(PI / 180), minVote(10), minLength(0.), maxGap(0.)
{

}
//设置分辨率
void SetAccResolusion(double dRho, double dTheta)
{
deltaRho = dRho;
deltatheta = dTheta;
}
void SetLengthandGap(double Length, double Gap)
{
minLength = Length;
maxGap = Gap;
}
void SetMinVote(int minv)
{
minVote = minv;
}
vector<Vec4f>findLines(Mat &binary)
{
lines.clear();
HoughLinesP(binary, lines, deltaRho, deltatheta, minVote, minLength, maxGap);
return lines;
}
void drawDetectedLines(Mat &image, Scalar color = Scalar(255,255,255))
{
vector<Vec4f>::iterator it = lines.begin();
for (;it != lines.end();++it)
{
Point ptr1((*it)[0], (*it)[1]);
Point ptr2((*it)[2], (*it)[3]);
line(image, ptr1, ptr2, color);
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54


[/code]

main.cpp文件

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "LineFinder.h"
#define PI 3.141591653
using namespace std;
using namespace cv;

int main()
{
Mat image, result, result2;
image = imread("D:/road.jpg", 0);
Canny(image, result, 120, 200);
namedWindow("Canny");
imshow("Canny", result);
LineFinder finder;
finder.SetLengthandGap(100, 20);
finder.SetMinVote(200);
vector<Vec4f> lines = finder.findLines(result);
finder.drawDetectedLines(image);
namedWindow("HoughP");
imshow("HoughP", image);
waitKey(0);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25


[/code]

检测圆:

三个参数确定一个圆。

HoughCircles( InputArray image, OutputArray circles, int method, double dp,double minDist, double param1 = 100, double param2 = 100, int minRadius = 0, int maxRadius = 0 );

src_gray: 输入图像 (灰度图),无需canny变换

circles: 存储下面三个参数: x_{c}, y_{c}, r 集合的容器来表示每个检测到的圆.

CV_HOUGH_GRADIENT: 指定检测方法. 现在OpenCV中只有霍夫梯度法

dp = 1: 累加器图像的反比分辨率

min_dist = src_gray.rows/8: 检测到圆心之间的最小距离

param_1 = 200: Canny边缘函数的高阈值

param_2 = 100: 圆心检测阈值.投票数

min_radius = 0: 能检测到的最小圆半径, 默认为0.

max_radius = 0: 能检测到的最大圆半径, 默认为0

代码:

Mat image, result, result2;

image = imread(“D:/round.jpg”, 0);

namedWindow(“image”);

imshow(“image”, image);

GaussianBlur(image, image, Size(5, 5), 1.5);

vector circles;

HoughCircles(image, circles, HOUGH_GRADIENT, 2, 50, 200, 200, 25, 200);

vector::iterator it = circles.begin();

for (;it != circles.end();++it)

{

circle(image, Point((*it)[0], (*it)[1]), (*it)[2], Scalar(255), 2);

}

namedWindow(“circle”);

imshow(“circle”, image);

(function () {('pre.prettyprint code').each(function () {
var lines = (this).text().split(′\n′).length;varnumbering = $('').addClass('pre-numbering').hide();
(this).addClass(′has−numbering′).parent().append(numbering);
for (i = 1; i
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: