- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章OpenCV霍夫变换(Hough Transform)直线检测详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
霍夫变换(Hough Transform)的主要思想:
一条直线在平面直角坐标系(x-y)中可以用y=ax+b式表示,对于直线上一个确定的点(x0,y0),总符合y0-ax0=b,而它可以表示为参数平面坐标系(a-b)中的一条直线。因此,图像中的一个点对应参数平面的一条直线,同样,图像中的一条直线对应参数平面上的一个点.
基本Hough变换检测直线:
由于同一条直线上的不同点在参数平面中是会经过同一个点的多条线。对图像的所有点作霍夫变换,检测直线就意味着找到对应参数平面中的直线相交最多的点。对这些交点做票数累计,然后取出票数大于最小投票数的点,即为原坐标系里检测出的直线.
一般,直线的参数方程为 ρ=xcosθ+ysinθ 。
OpenCV中的基本霍夫变换直线检测函数 cv::HoughLines:
函数输入为一幅二值图像(有很多待检测点),其中一些点排列后形成直线,通常这是一幅边缘图像,比如来自Sobel算子或Canny算子。函数的输出是cv::Vec2f的向量,每个元素都是一对代表检测到的直线的浮点数(ρ, θ)。函数的作法是先求出原图像中每点的极坐标方程,若相交于一点的极坐标曲线的个数大于最小投票数,则将该点(ρ, θ)(参数坐标系点)放入输出向量.
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#define PI 3.1415926
class
LineFinder{
private
:
std::vector<cv::Vec2f> lines;
double
deltaRho;
// 参数坐标系的步长(theta表示与直线垂直的角度)
double
deltaTheta;
int
minVote;
// 判断是直线的最小投票数
public
:
LineFinder() {
deltaRho = 1;
deltaTheta = PI / 180;
minVote = 80;
}
void
setAccResolution(
double
dRho,
double
dTheta) {
deltaRho = dRho;
deltaTheta = dTheta;
}
void
setMinVote(
int
minv) {
minVote = minv;
}
// Hough变换检测直线;rho=1,theta=PI/180参数坐标系里的步长,threshold=最小投票数
void
findLines(cv::Mat& binary){
lines.clear();
cv::HoughLines(binary, lines, deltaRho, deltaTheta, minVote);
}
void
drawDetectedLines(cv::Mat& result){
std::vector<cv::Vec2f>::const_iterator it = lines.begin();
while
(it != lines.end())
{
// 以下两个参数用来检测直线属于垂直线还是水平线
float
rho = (*it)[0];
float
theta = (*it)[1];
if
(theta < PI / 4. || theta > 3.*PI / 4.)
{
// 若检测为垂直线,直线交于图片的上下两边,先找交点
cv::Point pt1(rho /
cos
(theta), 0);
cv::Point pt2((rho - result.rows*
sin
(theta)) /
cos
(theta), result.rows);
cv::line(result, pt1, pt2, cv::Scalar(255), 1);
//
}
else
// 若检测为水平线,直线交于图片的左右两边,先找交点
{
cv::Point pt1(0, rho /
sin
(theta));
cv::Point pt2(result.cols, (rho - result.cols*
cos
(theta)) /
sin
(theta));
cv::line(result, pt1, pt2, cv::Scalar(255), 1);
}
++it;
}
}
};
int
main(
int
argc,
char
*argv[])
{
cv::Mat image = cv::imread(
"D:/VS_exercise/images/road1.jpg"
);
cv::Mat imageGray;
cv::Mat contours;
cv::cvtColor(image, imageGray, cv::COLOR_RGB2GRAY);
cv::Canny(imageGray, contours, 190, 300);
// 在原图的拷贝上画直线
cv::Mat result(contours.rows, contours.cols, CV_8U, cv::Scalar(255));
image.copyTo(result);
// Hough变换检测
LineFinder finder;
finder.setMinVote(130);
finder.findLines(contours);
finder.drawDetectedLines(result);
// 显示
cv::namedWindow(
"Detected Lines with Hough"
);
cv::imshow(
"Detected Lines with Hough"
, result);
cv::waitKey(0);
return
0;
}
|
概率Hough变换检测线段:
霍夫变换检测直线的目的,是找到二值图像中经过足够多数量点的所有直线,当同一直线穿过许多点,便意味着这条线的存在足够明显.
概率霍夫变换在原算法的基础上增加了一些改动,主要是:
1. 不再系统地逐行扫描图像,而是随机挑选(轮廓图像的)前景点,一旦累加器中的某一项交点的票数达到给定的最小值,就搜索轮廓图像在对应直线上的前景点,连成线段(要小于maxLineGap),然后记录线段参数(起终点),最后删除所有经过的点(即使它们并未投过票).
2. 概率霍夫变换定义了两个额外的参数:一个是可以接受的最小线段长度(minLineLength),另一个是允许组成连续线段的最大像素间隔(maxLineGap),虽然额外步骤增加了算法的复杂度,但由于参与投票的点数有所减少,因此得到了一些补偿.
openCV中的概率霍夫变换直线检测函数 cv::HoughLinesP:
函数的输出是cv::Vec4i组成的向量,每个元素是检测到的线段的两个坐标点(pt1x, pt1y, pt2x, pt2y).
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#define PI 3.1415926
class
LineFinder{
private
:
std::vector<cv::Vec4i> lines;
double
deltaRho;
// 步长(theta表示与直线垂直的角度)
double
deltaTheta;
int
minVote;
// 判断是直线的最小投票数
double
minLength;
// 判断是直线的最小线段长度
double
maxGap;
// 允许组成连续线段的最大像素间隔
public
:
LineFinder() {
deltaRho = 1;
deltaTheta = PI / 180;
minVote = 10;
minLength = 0.0;
maxGap = 0.0;
}
void
setAccResolution(
double
dRho,
double
dTheta) {
deltaRho = dRho;
deltaTheta = dTheta;
}
void
setMinVote(
int
minv) {
minVote = minv;
}
void
setLineLengthAndGap(
double
length,
double
gap) {
minLength = length;
maxGap = gap;
}
// Hough变换检测线段
void
findLines(cv::Mat& binary) {
lines.clear();
cv::HoughLinesP(binary, lines, deltaRho, deltaTheta, minVote, minLength, maxGap);
}
void
drawDetectedLines(cv::Mat &image, cv::Scalar color = cv::Scalar(255)) {
std::vector<cv::Vec4i>::const_iterator it2 = lines.begin();
while
(it2 != lines.end()) {
cv::Point pt1((*it2)[0], (*it2)[1]);
cv::Point pt2((*it2)[2], (*it2)[3]);
cv::line(image, pt1, pt2, color, 1.5);
//画线段
++it2;
}
}
};
int
main(
int
argc,
char
*argv[])
{
cv::Mat image = cv::imread(
"D:/VS_exercise/images/road1.jpg"
);
cv::Mat imageGray;
cv::Mat contours;
cv::cvtColor(image, imageGray, cv::COLOR_RGB2GRAY);
// 边缘检测
cv::Canny(imageGray, contours, 190, 300);
// Hough变换检测
LineFinder finder;
finder.setMinVote(80);
finder.setLineLengthAndGap(100, 10);
//概率Hough变换增加的两个参数
finder.findLines(contours);
finder.drawDetectedLines(image);
// 显示
cv::imshow(
"Detected Lines with Hough"
, image);
cv::waitKey(0);
return
0;
}
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://blog.csdn.net/index20001/article/details/78299021 。
最后此篇关于OpenCV霍夫变换(Hough Transform)直线检测详解的文章就讲到这里了,如果你想了解更多关于OpenCV霍夫变换(Hough Transform)直线检测详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在 MATLAB 中找到了 Hough 变换的实现,地址是 Rosetta Code ,但我无法理解它。我还想修改它以显示原始图像和重建的线条(去霍夫)。 感谢任何有助于理解它和消除霍夫的帮助。谢谢
我在Hough Line转换方面遇到麻烦。我正在尝试确定厨房中的主要线条。我最初只是使用Canny,但它会拾取比我想要的更多的噪音,并且没有拾取墙壁和天花板的交集。但是,“霍夫线”变换仅识别一条根本不
我目前在HoughCircles上使用computer-vision,但无法使其正常工作。 如何解决此错误? Error : 'Traceback (most recent call last):
我正在尝试检测斯诺克 table 上的 22 个球。我有一张图像要测试,但程序 os 检测 2 个球,以及其他地方的随机圆圈。我的代码在圆检测算法下面。有谁知道应该调整哪些参数以获得我需要的检测?谢谢
OpenCV 中的 HoughLines 或 HoughLinesP 函数是否像 HoughCircles 函数那样返回累加器顺序的行列表?我想知道行的顺序。获取线条的累加器值也非常方便,因此可以使用
我想使用OpenCV Hough Circles的实现,但是我有一个问题: 该函数返回的圈子已经通过投票排序了吗? 由于霍夫变换基于投票机制,因此我想知道此圈子是按投票顺序从最高投票到最低投票,还是随
我正在尝试对实时视频源运行霍夫线变换。首先,提要通过一个精明的边缘检测器,它可以完美地工作并输出,然后我通过霍夫线变换运行图像,它导致“windows 触发了 openCv.exe 中的断点。”如果您
我有如下图片: 我正在尝试通过 HoughCircles 函数检测圆圈。在检测之前,我对图像进行阈值处理,并通过高斯技术对其进行模糊处理。结果如下: 倒置图像更大,因为我碰巧发现,如果我不以相同的纵横
我想找到下图中的圆圈。我尝试使用 OpenCV 的 Hough circle detection但它没有给出正确的结果。 还有其他方法可以找到圈子吗? 这里是示例代码 vector circles;
我正在尝试用我的函数重新创建 MATLAB 的 hough 函数。我的代码如下 function [H,T,R] = my_hough(x,dr,dtheta) rows = size(x,1
我正在尝试使用霍夫变换来检测圆圈。 使用我当前的代码,我可以检测到下面的代码 但我想在我检测到的圆圈内找到黑洞。然而,改变 houghcircle 方法的参数对我没有帮助。实际上它发现了不存在的圈子。
霍夫变换(Hough Transform)的主要思想: 一条直线在平面直角坐标系(x-y)中可以用y=ax+b式表示,对于直线上一个确定的点(x0,y0),总符合y0-ax0=b,而它可以表
我正在尝试从网络摄像头获取视频流,并使用HoughCircles()检测其中的圈子。但是,无论何时我尝试运行代码,视频都会花费一些时间来加载图像,或者根本不会加载图像。我们将非常感谢您提供有关如何获取
我正在编写代码以从图像中裁剪收据。我正在使用“opencv4nodejs”模块在javascript中开发解决方案,但我已经习惯了Python和C++。 我见过不同的方法,例如 this ,但如果检测
我目前正在与 Hough Circles 合作。有什么方法可以自动为霍夫圆找到合适的参数吗?现在,我只是手动更改值,直到它正确绘制圆圈。 最佳答案 我认为您还应该看看 http://www.cse.y
当我运行 cv2.HoughCircles() 时出现错误 Traceback (most recent call last): File "cv.py", line 1, in imp
我使用 HoughLinesP 来识别线条。但是,我的问题是我怎么知道什么时候没有检测到线。我尝试将矢量线与 null 进行比较,但没有任何反应。准确地说,这是我的代码: for(size_t k=0
我是 opencv 的新手。我想检测图像中非常小的线条并将它们存储为线条数组。我的图像中不会有超过 10 条线(对齐标记)。我已经使用 opencv 示例教程使用 canny 和 Hough 检测线条
我正在尝试使用 OpenCV 的 Hough Circles 函数从下图中检测圆 我的代码(OpenCV 和 Python) myImage = cv2.imread("C:\\sample.jpg"
我正在尝试实现 this paper 中介绍的广义 Hough 变换在 MATLAB 中。我也试过使用 this document理解算法。我一直在研究如何计算梯度角以找到要在 R 表中使用的 Φ。
我是一名优秀的程序员,十分优秀!