OpenCV(三十六):霍夫直线检测

1.检测直线的霍夫变换原理

2.检测直线函数HoughLines()

检测直线流程:

Step1:将参数空间的坐标轴离散化。

Step2:将图像中每个非0像素通过映射关系求取在参数空间通过的方格

Step3:统计参数空间内每个方格出现的次数,选取次数大于某一值的方格作为表示直线的方格

Step4:将参数空间中表示直线的方格的参数作为图像中直线的参数

void cv::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

)

参数说明:

  • image:输入的二值图像,通常是经过边缘检测后的图像。
  • lines:输出参数,包含检测到的直线的向量。
  • rho:极径参数ρ的精确度,以像素为单位。
  • theta:角度参数θ的精确度,以弧度为单位。
  • threshold:参数空间中投票阈值,用于确定检测到的直线。
  • srn、stn、min_theta、max_theta:这些参数是可选的,用于进一步细化直线检测的精度和范围。

示例代码:

void drawLine(Mat &img,//要标记直线的图像vector<Vec2f> lines,//检测的直线数据double rows,//原图像的行数(高)double cols,//原图像的列数(宽)Scalar scalar,//绘制直线的颜色int n//绘制直线的线宽){Point pt1,pt2;for(size_t i=0;i<lines.size();i++){float rho=lines[i][0];//直线距离坐标原点的距离float theta=lines[i][1];//直线过坐标原点垂线double a=cos(theta);//夹角的余弦值double b=sin(theta);//夹角的正弦值double x0=a*rho,y0=b*rho;//直线与坐标原点的垂线的交点double length=max(rows,cols);//图像高宽的最大值//计算直线上的一点pt1.x= cvRound(x0+length*(-b));pt1.y= cvRound(y0+length*(a));//计算直线上的另一点pt2.x= cvRound(x0-length*(-b));pt2.y= cvRound(y0-length*(a));//两点绘制一条直线line(img,pt1,pt2,scalar,n);}
}
//霍夫直线检测
void Hough_linear_detection(Mat image){Mat gray;cvtColor(image,gray,COLOR_BGR2GRAY);Mat edge;//检测边缘图像,并二值化Canny(gray,edge,80,180,3, false);//用不同的累加器进行检测直线vector<Vec2f> lines1,lines2;HoughLines(edge, lines1,1,CV_PI/180,50,0,0);HoughLines(edge, lines2,1,CV_PI/180,150,0,0);//在原图像中绘制直线Mat img1,img2;image.copyTo(img1);image.copyTo(img2);drawLine(img1,lines1,edge.rows,edge.cols,Scalar(255),2);drawLine(img2,lines2,edge.rows,edge.cols,Scalar(255),2);//显示图像imwrite("/sdcard/DCIM/edge.png",edge);imwrite("/sdcard/DCIM/img1.png",img1);imwrite("/sdcard/DCIM/img2.png",img2);
}

Canny算子边缘检测后图片 :

用累加器为50进行检测直线:

用累加器为150进行检测直线:

3.检测直线函数 HoughLinesP()

void cv::HoughLinesP ( InputArray   image,

OutputArray lines,

double     rho,

double    theta,

int        threshold,

double   minLineLength =0,

double   maxLineGap = 0

)

  • image:待检测直线的原图像,必须是CV_8C的单通道二值图像
  • lines:霍夫变换检测到的直线输出量,每一条直线都由4个参数进行描述,分别是直线两个端点的坐标
  • rho:以像素为单位的距离分辨率。
  • theta: 以弧度为单位的角度分辨率
  • threshold:累加器的阈值
  • minLineLength: 直线的最小长度,当检测直线的长度小于该数值时将会被剔除
  • maxLineGap:允许将同一行两个点连接起来的最大距离。

示例代码:

//霍夫直线检测
void Hough_linearP_detection(Mat image){Mat gray;cvtColor(image,gray,COLOR_BGR2GRAY);Mat edge;//检测边缘图像,并二值化Canny(gray,edge,80,180,3, false);//利用渐进概率式霍夫变换提取直线vector<Vec4i> linesP1,linesP2;HoughLinesP(edge, linesP1,1,CV_PI/180,150,30,10);//两个点连接最大距离10HoughLinesP(edge, linesP2,1,CV_PI/180,150,30,30);//两个点连接最大距离30//绘制两个点连接最大距离10直线检测结果Mat img1;image.copyTo(img1);for(size_t i=0;i<linesP1.size();i++){line(img1,Point(linesP1[i][0],linesP1[i][1]),Point(linesP1[i][2],linesP1[i][3]),Scalar(255),3);}//绘制两个点连接最大距离30直线检测结果Mat img2;image.copyTo(img2);for(size_t i=0;i<linesP2.size();i++){line(img2,Point(linesP2[i][0],linesP2[i][1]),Point(linesP2[i][2],linesP2[i][3]),Scalar(255),3);}//显示图像imwrite("/sdcard/DCIM/img10.png",img1);imwrite("/sdcard/DCIM/img20.png",img2);
}

绘制两个点连接最大距离10直线检测结果:

绘制两个点连接最大距离30直线检测结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/76433.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Electron】electron与cljs的处理

实现效果: 前言&#xff1a; 如何用cljs的方式&#xff0c;编写electron应用&#xff0c;可以实现多窗体应用 要使用ClojureScript&#xff08;CLJS&#xff09;编写一个 Electron 应用程序&#xff0c;并实现多窗体功能&#xff0c;您可以按照以下步骤进行操作&#xff1a; …

C语言实现扫雷小游戏

1.首先扫雷游戏要存储布置好的雷信息&#xff0c;需要一个二维数组 不是雷放* 雷&#xff1a;# 不是雷&#xff1a;0 雷&#xff1a;1 2. 给2个二维数组 9*9 一个存放雷的信息&#xff0c;一个存放布置好雷的信息 3.为了防止在统计坐标周围的…

基于人工智能与边缘计算Aidlux的工业表面缺陷检测

一&#xff1a;训练yolov8得到onnx模型&#xff08;相关教程有很多&#xff09; 二&#xff1a;模型转化&#xff1a; 网站&#xff1a; https://aimo.aidlux.com/ 输入试用账号和密码: 账号:AIMOTC001&#xff0c;密码:AIMOTC001 我们选择 TensorFlowLite 一步步完成转化 …

TCP的三次握手与四次挥手

首先&#xff0c;源端口号和目标端口号是不可少的&#xff0c;这一点和 UDP 是一样的。如果没有这两个端口号。数据就不知道应该发给哪个应用。 接下来是包的序号。为什么要给包编号呢&#xff1f;当然是为了解决乱序的问题。不编好号怎么确认哪个应该先来&#xff0c;哪个应该…

跨站请求伪造

1.CSRF 概述 1.1 CSRF 原理 1.1.1 基本概念 ​ 跨站请求伪造&#xff08;Cross Site Request Forgery&#xff0c;CSRF&#xff09;是一种攻击&#xff0c;它强制浏览器客户端用户在当前对其进行身份验证后的Web 应用程序上执行非本意操作的攻击&#xff0c;攻击的重点在于更…

选择排序——直接选择排序

直接选择排序&#xff1a;&#xff08;以重复选择的思想为基础进行排序&#xff09; 1、简述 顾名思义就是选出一个数&#xff0c;再去抉择放哪里去。 设记录R1&#xff0c;R2…&#xff0c;Rn&#xff0c;对i1&#xff0c;2&#xff0c;…&#xff0c;n-1&#xff0c;重复下…

分布式、锁、延时任务

1. redission redission 原理 Redis分布式锁-这一篇全了解(Redission实现分布式锁完美方案) 2.zk 2.1 指令 ls / / 下有哪些子节点 get /zookeeper 查看某个子节点内容 create /aa “test” delete /aa set /aa “test01” 2.2 创建节点 模式 默认创建永久 create -e …

Python基础: with模式和__enter__ 和 __exit__

一、说明 有一些任务&#xff0c;可能事先需要设置&#xff0c;事后做清理工作。 with方法就是python的非常酷的语句&#xff0c;安全可靠&#xff0c;方便。我们自己的类如何具备with的能力?必须拥有__enter__()方法&#xff0c;另一个__exit__()&#xff0c;因此&#xff0c…

黑马JVM总结(五)

&#xff08;1&#xff09;方法区 它是所有java虚拟机 线程共享的区&#xff0c;存储着跟类的结构相关的信息&#xff0c;类的成员变量&#xff0c;方法数据&#xff0c;成员方法&#xff0c;构造器方法&#xff0c;特殊方法&#xff08;类的构造器&#xff09; 方法区在虚拟机…

【算法专题突破】双指针 - 最大连续1的个数 III(11)

目录 1. 题目解析 2. 算法原理 3. 代码编写 写在最后&#xff1a; 1. 题目解析 题目链接&#xff1a;1004. 最大连续1的个数 III - 力扣&#xff08;Leetcode&#xff09; 这道题不难理解&#xff0c;其实就是求出最长的连续是1的子数组&#xff0c; 但是&#xff0c;他支…

用vagrant快速创建linux虚拟机

参考B站&#xff1a;https://www.bilibili.com/video/BV1np4y1C7Yf 1、下载VirtualBox 2、下载vagrant 3、vagrant官网下载.box文件 官网&#xff1a;https://app.vagrantup.com/boxes/search 例如要下载这个centos/7 点进去&#xff0c;点击下载 下载后放到一个指定目录…

OSCP系列靶场-Esay-SunsetNoontide保姆级

OSCP系列靶场-Esay-SunsetNoontide 目录 OSCP系列靶场-Esay-SunsetNoontide总结准备工作信息收集-端口扫描目标开放端口收集目标端口对应服务探测 信息收集-端口测试chatgpt学习 漏洞利用-getwebshell漏洞利用-unrealircd 内网遨游-getshell交互shellFLAG1获取信息收集-内网基础…

【C++进阶】二叉树进阶之二叉搜索树

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

Vector底层原理——面试之我答

Vector概述 vector是STL中最常用的容器&#xff0c;vector主要功能是作动态数组来弥补传统数组的缺点&#xff0c;如&#xff1a;不灵活&#xff0c;不方便插入等等。 Vector支持随机访问&#xff0c;因此访问某一个元素的时间复杂度是O(1)。 vector中存储着许多易用的函数方法…

Azure + React + ASP.NET Core 项目笔记一:项目环境搭建(二)

有意义的标题 pnpm 安装umi4 脚手架搭建打包语句变更Visual Studio调试Azure 设置变更发布 pnpm 安装 参考官网&#xff0c;或者直接使用npm安装 npm install -g pnpmumi4 脚手架搭建 我这里用的umi4&#xff0c;官网已附上 这里需要把clientapp清空&#xff0c;之后 cd Cl…

【JAVA】String类

作者主页&#xff1a;paper jie_的博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JAVASE语法系列》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和…

基于SSM的高校共享单车管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Redis原理:IntSet

&#xff08;笔记总结自b站黑马程序员课程&#xff09; 一、结构 IntSet是Redis中set集合的一种实现方式&#xff0c;基于整数数组来实现&#xff0c;并且具备长度可变、有序等特征。 结构如下&#xff1a; typedef struct intset {uint32_t encoding; //编码方式uint32_t l…

读取XML的几种方式

一、为什么使用XML 1、便于不同应用程序之间通信。 2、便于不同平台之间通信。 3、便于不同平台之间数据共享。 二、Dom读取 xml文件内容 <?xml version"1.0" encoding"UTF-8"?> <bookstore><book id"1"><name>冰…

python main 函数-启动-传递参数 python 打包 exe C# 进程传参

Part1:Python main 传递参数 在Python编程中&#xff0c;我们经常需要从命令行或其他外部环境中获取参数。Python提供了一种简单而灵活的方式来处理这些参数&#xff0c;即通过main函数传参 1.python main 函数-启动-传递参数 test.py import sysdef main():# 获取命令行参…