当前位置:网站首页>Opencv——霍夫变换以及遇到的一些问题
Opencv——霍夫变换以及遇到的一些问题
2022-06-28 00:39:00 【51CTO】
目录
- 问题1 :颜色空间转换函数参数问题:CV_BGR2GRAY vs CV_GRAY2BGR
- 问题2:cvRound()、cvFloor()、cvCeil()函数用法
- 霍夫变换的含义
- 标准霍夫直线变换
- 累计概率霍夫变换
- 霍夫变换圆变换
- 原理和算法步骤:
- 霍夫圆变换函数参数讲解
问题1 :颜色空间转换函数参数问题:CV_BGR2GRAY vs CV_GRAY2BGR
OpenCV的颜色空间转换函数:
dstCn现在已经改成COLOR_GRAY2BGR之类的以COLOR开头的。
CV_BGR2GRAY :将RGB图转换成GRAY图
CV_GRAY2BGR:将GRAY图转换成RGB图
浅墨源码
cvtColor(midImage, dstImage, COLOR_GRAY2BGR);
//将canny算子扫描后的二值图转化为RGB图,原因是后面你可视化霍夫变换效果时,画的曲线是彩色的。
问题2:cvRound()、cvFloor()、cvCeil()函数用法
cvRound():返回跟参数最接近的整数值,即四舍五入;
cvFloor():返回不大于参数的最大整数值,即向下取整;
cvCeil():返回不小于参数的最小整数值,即向上取整;
霍夫变换的含义
这个我在边缘的文章中有涉及过,直接贴链接:
javascript:void(0) 还有我参考的一个链接:
javascript:void(0)
标准霍夫直线变换
霍夫线变换函数参数讲解
●第一个参数,InputArray类型的image, 输入图像,即源图像。需为8位的单通道二进制图像
●第二个参数,InputArray类型的lines,经过调用HoughLines函数后储存了霍 夫线变换检测到线条的输出矢量。每一条线由具有两个元素的矢量( ρ, 0) 表示,其中,ρ是离坐标原点(0,0) (也就是图像的左上角)的距离,θ是弧度线条旋转角度(0度表示垂直线,π/2 度表示水平线)。
●第三个参数,double类型的rho,以像素为单位的距离精度。另-种表述方
式是直线搜索时的进步尺寸的单位半径。(Latex 中/rho即表示ρ )
●第四个参数,double 类型的theta,
以弧度为单位的角度精度。另一种表述 方式是直线搜索时的进步尺寸的单位角度。
●第五个参数,int类型的threshold,累加平面的阈值参数,即识别某部分为 图中的一条直线时它在累加平面中必须达到的值。大于國值threshold的线段才可以被检测通过并返回到结果中。
●第六个参数,double类型的srn,, 有默认值0。对于多尺度的霍夫变换,这 是第三个参数进步尺寸rho的除数距离。粗略的累加器进步尺寸直接是第三个参数rho,而精确的累加器进步尺寸为rho/sm。
●第七个参数,double 类型的stn, 有默认值0,对于多尺度霍夫变换,sm表示第四个参数进步尺寸的单位角度theta的除数距离。且如果sr和 stn同时为0,就表示使用经典的霍夫变换。否则,这两个参数应该都为正数。
理解:在XY平面,直线有两个参数:K、B(斜率和截距),可视化直线,需要构造x,y轴,假设XY轴的最小精度为1,则勾画出的直线其实是一系列离散的点。随着XY精度升高,所可视化出来的数据将越来越像一条线。
同理,在rho/theta平面,一条直线对应平面上以rho为横坐标,tehta为纵坐标的一个点。
rho/theta的精度越高,所表示的直线越精准。我想这边是第三参数和第四参数的含义。
我们一般以rho=1,theta=1度的精度来构造投票空间。
//为窗口标题定义的宏
using
namespace
cv;
using
namespace
std;
//==================================标准霍夫变换============================================
int
main()
{
SetConsoleTextAttribute(
GetStdHandle(
STD_OUTPUT_HANDLE),
FOREGROUND_INTENSITY
|
FOREGROUND_GREEN);
//字体为绿色
Mat
srcImage
=
imread(
"D:\\opencv_picture_test\\霍夫变换.png");
//判断图像是否加载成功
if (
srcImage.
empty())
{
cout
<<
"图像加载失败!"
<<
endl;
return
-
1;
}
else
cout
<<
"图像加载成功!"
<<
endl
<<
endl;
Mat
midImage,
dstImage;
Canny(
srcImage,
midImage,
50,
200,
3);
//进行一此canny边缘检测
//【3】进行霍夫线变换
vector
<
Vec2f
>
lines;
//定义一个矢量结构lines用于存放得到的线段矢量集合
HoughLines(
midImage,
lines,
1,
CV_PI
/
180,
150,
0,
0);
//【4】依次在图中绘制出每条线段
for (
size_t
i
=
0;
i
<
lines.
size();
i
++)
{
float
rho
=
lines[
i][
0],
theta
=
lines[
i][
1];
Point
pt1,
pt2;
double
a
=
cos(
theta),
b
=
sin(
theta);
double
x0
=
a
*
rho,
y0
=
b
*
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));
line(
midImage,
pt1,
pt2,
Scalar(
255,
255,
255),
1,
LINE_AA);
}
//【5】显示原始图
imshow(
"【原始图】",
srcImage);
//【6】边缘检测后的图
imshow(
"【边缘检测后的图】",
midImage);
//【7】显示效果图
//imshow("【效果图】", dstImage);
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.
- 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.
累计概率霍夫变换
第一个参数,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。
第二个参数,InputArray类型的lines,经过调用HoughLinesP函数后后存储了检测到的线条的输出矢量,每一条线由具有四个元素的矢量(x_1,y_1, x_2, y_2) 表示,其中,(x_1, y_1)和(x_2, y_2) 是是每个检测到的线段的结束点。
第三个参数,double类型的rho,以像素为单位的距离精度。另一种形容方式是直线搜索时的进步尺寸的单位半径。
第四个参数,double类型的theta,以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度。
第五个参数,int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中。
第六个参数,double类型的minLineLength,有默认值0,表示最低线段的长度,比这个设定参数短的线段就不能被显现出来。
第七个参数,double类型的maxLineGap,有默认值0,允许将同一行点与点之间连接起来的最大的距离。
通过设定直线长度阈值,对过长或过短的直线不予理会。
//==================================累计概率霍夫变换============================================
int
main()
{
//读取原图片
Mat
Image
=
imread(
"D:\\opencv_picture_test\\霍夫变换.png");
//显示原图片
namedWindow(
"【原图】");
imshow(
"【原图】",
Image);
Mat
srcImage
=
Image.
clone();
Mat
midImage,
dstImage;
//进行边缘检测和转化为将灰度图转为RGB图
Canny(
srcImage,
midImage,
50,
200,
3);
cvtColor(
midImage,
dstImage,
COLOR_GRAY2BGR);
//定义矢量结构lines用于存放得到的线段矢量集合
vector
<
Vec4i
>
lines;
//进行霍夫变换
HoughLinesP(
midImage,
lines,
1,
CV_PI
/
180,
80,
50,
10);
//依次在图中绘制每条线段
for (
size_t
i
=
0;
i
<
lines.
size();
i
++) {
Vec4i
l
=
lines[
i];
line(
dstImage,
Point(
l[
0],
l[
1]),
Point(
l[
2],
l[
3]),
Scalar(
0,
0,
255),
1,
LINE_AA);
}
imshow(
"【边缘检测后的图】",
midImage);
imshow(
"【效果图】",
dstImage);
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.
- 26.
- 27.
- 28.
- 29.
- 30.
霍夫变换圆变换
原理和算法步骤:

霍夫圆变换函数参数讲解
输入:输入 8-bit、单通道灰度图像. circle_storage:检测到的圆存储仓. 可以是内存存储仓 (此种情况下,一个线段序列在存储仓中被创建,并且由函数返回)或者是包含圆参数的特殊类型的具有单行/单列的CV_32FC3型矩阵(CvMat*).矩阵头为函数所修改,使得它的 cols/rows 将包含一组检测到的圆。如果 circle_storage是矩阵,而实际圆的数目超过矩阵尺寸,那么最大可能数目的圆被返回。 每个圆由三个浮点数表示:圆心坐标(x,y)和半径.
method:Hough 变换方式,目前 只支持HOUGH_GRADIENT
dp:累加器图像的分辨率。这个参数允许创建一个比输入图像分辨率低的累加器。(这样做是因为有理由认为图像中存在的圆会自然降低到与图像宽高相同数量的范畴)。如果dp设置为1,则分辨率是相同的;如果设置为更大的值(比如2),累加器的分辨率受此影响会变小(此情况下为一半)。dp的值不能比1小。
min_dist:该参数是让算法能明显区分的两个不同圆之间的最小距离。
param1:用于Canny的边缘阀值上限,下限被置为上限的一半。
param2:累加器的阀值。
min_radius:最小圆半径。
max_radius:最大圆半径。
==================================
霍夫变换圆变换
============================================
int
main()
{
//载入原始图和Mat变量定义
Mat
srcImage
=
imread(
"D:\\opencv_picture_test\\形态学操作\\孔洞.png");
Mat
midImage,
dstImage;
//显示原始图
imshow(
"【原始图】",
srcImage);
//转为灰度图,进行图像平滑
cvtColor(
srcImage,
midImage,
COLOR_BGR2GRAY);
//转化边缘检测后的图为灰度图
GaussianBlur(
midImage,
midImage,
Size(
9,
9),
2,
2);
//模糊去噪
//进行霍夫圆变换
vector
<
Vec3f
>
circles;
//圆存储器,存储圆的数量,圆心坐标和半径
HoughCircles(
midImage,
circles,
HOUGH_GRADIENT,
1.5,
10,
200,
100,
0,
0);
//inputImage circle_storage 霍夫变换的方式 累加器图像的分辨率 两个不同圆之间的距离
//依次在图中绘制出圆
for (
size_t
i
=
0;
i
<
circles.
size();
i
++)
{
Point
center(
cvRound(
circles[
i][
0]),
cvRound(
circles[
i][
1]));
int
radius
=
cvRound(
circles[
i][
2]);
//绘制圆心
circle(
srcImage,
center,
3,
Scalar(
0,
0,
255),
3,
8,
0);
//绘制圆轮廓
circle(
srcImage,
center,
radius,
Scalar(
0,
0,
255),
3,
8,
0);
}
//显示效果图
imshow(
"【效果图】",
srcImage);
while ((
char)
waitKey(
1)
!=
'q') {}
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.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
霍夫变换总结
1、为什么在霍夫变换求直线方程时,要用极坐标的形式
斜截式不能表示垂直于x轴的直线,而极坐标形式可以表达。
2、霍夫变换求直线方程,和使用最小二乘法求直线最小方程相比,有什么优缺点
优点:当出现离群采样点时最小二乘法会有很大误差而霍夫变换不会
缺点:时间复杂度和空间复杂度都很高,只能检测线段的方向,而不能确定线段的长度
参考链接
http://www.manongjc.com/article/42132.html https://stackoverflow.com/questions/5929125/opencv-houghcircles-param1-param2 javascript:void(0) 浅墨大神博客
边栏推荐
- Flask基础:模板渲染+模板过滤使用+控制语句
- Redis~geospatial (geospatial), hyperloglog (cardinality Statistics)
- Jenkins - Pipeline concept and creation method
- Jenkins - accédez à la variable de paramètre personnalisée Jenkins, en traitant les espaces dans la valeur de la variable
- OSI 7层模型讲解(大白话 通俗易懂)
- 外盘期货哪里可以开户?哪个平台出入金比较安全?
- Jenkins - data sharing and transfer between copy artifact plug-in builds
- mysql面试百题集
- Teach you how to realize pynq-z2 bar code recognition
- Wangxinling, tanweiwei Shanhai (extended version of Chorus) online audition lossless FLAC Download
猜你喜欢

Jenkins - access the Jenkins user-defined parameter variable, and handle the variable value containing spaces

The system administrator has set the system policy to prohibit this installation. Solution

图灵机启动顺序

SQL injection bypass (2)

【历史上的今天】6 月 13 日:分组交换网路的“亲子纠纷”;博弈论创始人出生;交互式电视初现雏形

Mysql大合集,你要内容的这里全都有

Dynamic Host Configuration Protocol

How to handle computer security certificate errors

MySQL优化小技巧

Complex and inefficient logistics? Three steps to solve problems in enterprise administration
随机推荐
【历史上的今天】6 月 13 日:分组交换网路的“亲子纠纷”;博弈论创始人出生;交互式电视初现雏形
Solutions to st link USB communication error
【历史上的今天】6 月 16 日:甲骨文成立;微软 MSX 诞生;快速傅里叶变换发明者出生
Jenkins - data sharing and transfer between copy artifact plug-in builds
SQL injection bypass (3)
Architecture high reliability application knowledge map ----- microservice architecture map
Keil "St link USB communication error" solution
SQL injection bypass (IV)
Scoped attribute and lang attribute in style
Cesium Click to obtain longitude and latitude (2D coordinates)
JS实现滑动拼图验证
数智学习|湖仓一体实践与探索
架构高可靠性应用知识图谱 ----- 微服务架构图谱
yarn下载报错There appears to be trouble with your network connection. Retrying.
《低代码解决方案》——覆盖工单、维修和财务全流程的数字化售后服务低代码解决方案
Embedded must learn! Detailed explanation of hardware resource interface - based on arm am335x development board (Part 2)
Domain Name System
Redis~geospatial (geospatial), hyperloglog (cardinality Statistics)
Jenkins - 内置变量访问
Cesium Color 颜色(赋值)随机颜色