霍夫变换的基本理解(第八天)

2024-05-28 20:18

本文主要是介绍霍夫变换的基本理解(第八天),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

千万注意:使用opencv自带的霍夫API

HoughLinesP():此函数输入的是一个二进制且八位的图像,例如:你不能用cvtcolor()变换之后直接输入。

HoughCircles():此函数输入的是一个灰度且八位的图像,例如:你不能经过threshold()、findcontours()等之后的图像进行输入。

我现在还不知道经过二值化的图像怎么转化为灰度图。。。。会了再补充。

 ---霍夫直线变换---

源程序没有分析,只是分析了基本的原理。。。等以后用到之后再进行分析

首先回顾一下坐标系的概念--->>>

1.直角坐标系(直线)<--->极坐标系(点),极坐标系(直线)<--->直角坐标系(点)。相互对应的关系

2.推导的公式很简单,看一下就懂了。

3.对于第三个公式,我们给定一个(x0,y0),就是图像的一个像素点(这个图是经过滤波、灰度、梯度等处理的),那么这个点在极坐标就可以画出一条直线。因为在极坐标看的不明显,把这个函数画在直角坐标系显示(图一),就类似三角函数的图像。现在我们再给定点(x1,y1)、(x2,y2)。。。进行同样的方法画图(图二),这个点在直角坐标系就是一条直线,那么多重合的点,就说明很多的像素点在这个直线上,我们设定一个阈值L,当点的重合率大于这个阈值就认定是直线。

4.有点饶人,直角和极坐标相互的转化实现。

 

图一

图二

上面的原理是可以运行的:

1.效率太低了,试想一下图像边缘非常的多,如果每一个像素点都进行计算的话,那太费时费事了。

2.线段的端点没办法检测。

3.对于相近的线段没办法区分。

HoughLinesP函数就是利用概率霍夫变换来检测直线的。它的一般步骤为:

1、随机抽取图像中的一个特征点,即边缘点,如果该点已经被标定为是某一条直线上的点,则继续在剩下的边缘点中随机抽取一个边缘点,直到所有边缘点都抽取完了为止;

2、对该点进行霍夫变换,并进行累加和计算;

3、选取在霍夫空间内值最大的点,如果该点大于阈值的,则进行步骤4,否则回到步骤1;

4、根据霍夫变换得到的最大值,从该点出发,沿着直线的方向位移,从而找到直线的两个端点;

5、计算直线的长度,如果大于某个阈值,则被认为是好的直线输出,回到步骤1。

opencv霍夫直线变换:

houghlines()--->>>

其返回的是(ρ,Θ),ρ代表距离(0,0)点到直线的欧几里得距离,也就是直线距离。Θ代表的是(0,0)点垂直直线然后与Y轴的夹角。

houghlinesP()--->>>

返回的是直线两个点:(x0,y0)(x1,y1)

刚开始我看不起houghlines函数,感觉效率低,后来基本上都是用houghlinesP的,但是这次实现文本的转正就用到了,这两个用途不一样吧!

---霍夫圆变换---

圆变换的想法和直线变化是一样的,就是把直角坐标系中的圆画在极坐标系中,然后求交点

第一阶段:检测圆心

1.1、对输入图像边缘检测;

1.2、计算图形的梯度,并确定圆周线,其中圆周的梯度就是它的法线;

1.3、在二维霍夫空间内,绘出所有图形的梯度直线,某坐标点上累加和的值越大,说明在该点上直线相交的次数越多,也就是越有可能是圆心;

1.4、在霍夫空间的4邻域内进行非最大值抑制;

1.5、设定一个阈值,霍夫空间内累加和大于该阈值的点就对应于圆心。

第二阶段:检测圆半径

2.1、计算某一个圆心到所有圆周线的距离,这些距离中就有该圆心所对应的圆的半径的值,这些半径值当然是相等的,并且这些圆半径的数量要远远大于其他距离值相等的数量;

2.2、设定两个阈值,定义为最大半径和最小半径,保留距离在这两个半径之间的值,这意味着我们检测的圆不能太大,也不能太小;

2.3、对保留下来的距离进行排序;

2.4、找到距离相同的那些值,并计算相同值的数量;

2.5、设定一个阈值,只有相同值的数量大于该阈值,才认为该值是该圆心对应的圆半径;

2.6、对每一个圆心,完成上面的2.1~2.5步骤,得到所有的圆半径。

 opencv实例:

 1 #include<iostream>2 #include <opencv2/opencv.hpp>3 #include <math.h>4 using namespace cv;5 using namespace std;6 7 int main(int argc,char**argv)8 {9     Mat input_image = imread("1.jpg");
10     if (input_image.data==NULL) {
11         return -1; cout << "can't open image.../";
12     }
13     imshow("Sourse image", input_image);
14     Mat mid_image,output_image, mid_image1;
15     mid_image.create(input_image.size(),input_image.type());
16     mid_image1.create(input_image.size(), input_image.type());
17     cvtColor(input_image,output_image,COLOR_BGR2GRAY);
18     GaussianBlur(output_image,output_image,Size(3,3),2,2);
19     Canny(output_image, output_image,50,200);
20     vector<Vec4i> lines;
21     vector<Vec3f> circles;
22     HoughLinesP(output_image,lines,1,CV_PI/180,80,50,10);
23     HoughCircles(output_image,circles,HOUGH_GRADIENT,1.5,10,200,100,0,0);
24     for (size_t i = 0; i < lines.size(); i++)
25     {
26         Vec4i l;
27         l = lines[i];
28         line(mid_image,Point(l[0],l[1]),Point(l[2],l[3]),Scalar(100,255,200),1,LINE_AA);
29     }
30     imshow("Destinate1 image", output_image);
31     imshow("Destinate2 image", mid_image);
32     for (size_t j = 0; j < circles.size(); j++)
33     {
34         Vec3f c;
35         c = circles[j];
36         circle(mid_image1, Point(cvRound(c[0]), cvRound(c[1])), 3, Scalar(0, 255, 50));
37         circle(mid_image1, Point(cvRound(c[0]), cvRound(c[1])), cvRound(c[2]), Scalar(0, 255, 50),3,8,0);
38     }
39     imshow("Destinate3 image", mid_image1);
40     waitKey(0);
41     return 0;
42 }

 opencv自带的API主要就是参数的设置,设置不好的参数要么检测的不好,要么根本检测不到直线和圆!

 1.圆的检测是找不到同心圆的

 2.很容易受噪声干扰

 3.必须非常的圆度,椭圆不行

主要参考:http://blog.csdn.net/zhaocj/article/details/50454847

这篇关于霍夫变换的基本理解(第八天)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1011587

相关文章

Java Spring的依赖注入理解及@Autowired用法示例详解

《JavaSpring的依赖注入理解及@Autowired用法示例详解》文章介绍了Spring依赖注入(DI)的概念、三种实现方式(构造器、Setter、字段注入),区分了@Autowired(注入... 目录一、什么是依赖注入(DI)?1. 定义2. 举个例子二、依赖注入的几种方式1. 构造器注入(Con

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

C#连接SQL server数据库命令的基本步骤

《C#连接SQLserver数据库命令的基本步骤》文章讲解了连接SQLServer数据库的步骤,包括引入命名空间、构建连接字符串、使用SqlConnection和SqlCommand执行SQL操作,... 目录建议配合使用:如何下载和安装SQL server数据库-CSDN博客1. 引入必要的命名空间2.

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

ModelMapper基本使用和常见场景示例详解

《ModelMapper基本使用和常见场景示例详解》ModelMapper是Java对象映射库,支持自动映射、自定义规则、集合转换及高级配置(如匹配策略、转换器),可集成SpringBoot,减少样板... 目录1. 添加依赖2. 基本用法示例:简单对象映射3. 自定义映射规则4. 集合映射5. 高级配置匹

SQL BETWEEN 语句的基本用法详解

《SQLBETWEEN语句的基本用法详解》SQLBETWEEN语句是一个用于在SQL查询中指定查询条件的重要工具,它允许用户指定一个范围,用于筛选符合特定条件的记录,本文将详细介绍BETWEEN语... 目录概述BETWEEN 语句的基本用法BETWEEN 语句的示例示例 1:查询年龄在 20 到 30 岁

mysql中insert into的基本用法和一些示例

《mysql中insertinto的基本用法和一些示例》INSERTINTO用于向MySQL表插入新行,支持单行/多行及部分列插入,下面给大家介绍mysql中insertinto的基本用法和一些示例... 目录基本语法插入单行数据插入多行数据插入部分列的数据插入默认值注意事项在mysql中,INSERT I