计算机视觉:使用opencv进行直线检测

1 直线检测介绍

在图像处理中,直线检测是一种常见的算法,它通常获取n个边缘点的集合,并找到通过这些边缘点的直线。其中用于直线检测,最为流行的检测器是基于霍夫变换的直线检测技术。

1.1 什么是霍夫变换

霍夫变换(Hough Transform)是图像处理中的一种特征提取方法,可以识别图像中的几何形状。它将在参数空间内进行投票来决定其物体形状,通过检测累计结果找到一极大值所对应的解,利用此解即可得到一个符合特定形状的参数。

1.2 霍夫变换原理

一条直线可由两个点A=(X1,Y1)和B=(X2,Y2)确定(笛卡尔坐标)

另一方面,y = kx + q 也可以写成关于(k,q)的函数表达式(霍夫空间):

对应的变换可以通过图形直观表示:

变换后的空间成为霍夫空间。即:笛卡尔坐标系中一条直线,对应霍夫空间的一个点

反过来同样成立(霍夫空间的一条直线,对应笛卡尔坐标系的一个点):

 再来看看A、B两个点,对应霍夫空间的情形:

接下来,再看一下三个点共线的情况: 

 

可以看出如果笛卡尔坐标系的点共线,这些点在霍夫空间对应的直线交于一点:这也是必然,共线只有一种取值可能。

如果不止一条直线呢?再看看多个点的情况(有两条直线):

其实(3,2)与(4,1)也可以组成直线,只不过它有两个点确定,而图中A、B两点是由三条直线汇成,这也是霍夫变换的后处理的基本方式选择由尽可能多直线汇成的点

霍夫空间:选择由三条交汇直线确定的点(中间图),对应的笛卡尔坐标系的直线(右图)。

到这里问题似乎解决了,已经完成了霍夫变换的求解,但是如果像下图这种情况呢?

k=∞是不方便表示的,而且q怎么取值呢,这样不是办法。因此考虑将笛卡尔坐标系换为:极坐标表示

在极坐标系下,其实是一样的:极坐标的点→霍夫空间的直线,只不过霍夫空间不再是[k,q]的参数,而是[\rho, \theta ]的参数,给出对比图: 

2 使用opencv进行直线检测

在使用霍夫变换侦测直线前,须先利用边缘检测算法来减少图像的数据量、剔掉不相关的信息,保留图像中重要的结构特征。

2.1 图像灰度化

原始图像与灰度化的图像如下:

2.2 边缘检测

利用边缘检测算法(Canny、Sobel、Laplacian等)来检测物体边缘,代码如下:

canny = cv2.Canny(gray_img, 30, 150)

2.3 霍夫变换

使用霍夫变换来得出直线检测结果,代码如下:

lines = cv2.HoughLines(canny, 1, np.pi / 180, 180)
lines1 = lines[:, 0, :]
for rho, theta in lines1[:]:a = np.cos(theta)b = np.sin(theta)x0 = a * rhoy0 = b * rhox1 = int(x0 + 3000 * (-b))y1 = int(y0 + 3000 * (a))x2 = int(x0 - 3000 * (-b))y2 = int(y0 - 3000 * (a))cv2.line(im, (x1, y1), (x2, y2), (0, 0, 255), 2)

运行结果显示如下:

2.4 完整代码

import cv2
import numpy as npim = cv2.imread("../data/ladder.jpg")cv2.imshow('original', im)
cv2.waitKey(0)gray_img = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray', gray_img)
cv2.waitKey(0)canny = cv2.Canny(gray_img, 30, 150)
cv2.imshow('canny', canny)
cv2.waitKey(0)lines = cv2.HoughLines(canny, 1, np.pi / 180, 180)
lines1 = lines[:, 0, :]
for rho, theta in lines1[:]:a = np.cos(theta)b = np.sin(theta)x0 = a * rhoy0 = b * rhox1 = int(x0 + 3000 * (-b))y1 = int(y0 + 3000 * (a))x2 = int(x0 - 3000 * (-b))y2 = int(y0 - 3000 * (a))cv2.line(im, (x1, y1), (x2, y2), (0, 0, 255), 2)cv2.imshow('original', im)
cv2.waitKey(0)

3 使用opencv检测倾角

import cv2
import numpy as npdef line_detect(image):# 将图片转换为HSVhsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)# 设置阈值lowera = np.array([0, 0, 221])uppera = np.array([180, 30, 255])mask1 = cv2.inRange(hsv, lowera, uppera)kernel = np.ones((3, 3), np.uint8)# 对得到的图像进行形态学操作(闭运算和开运算)mask = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, kernel) #闭运算:表示先进行膨胀操作,再进行腐蚀操作mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)  #开运算:表示的是先进行腐蚀,再进行膨胀操作# 绘制轮廓edges = cv2.Canny(mask, 50, 150, apertureSize=3)# 显示图片cv2.imshow("edges", edges)# 检测白线  这里是设置检测直线的条件,可以去读一读HoughLinesP()函数,然后根据自己的要求设置检测条件lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 40,minLineLength=10,maxLineGap=10)print "lines=",linesprint "========================================================"i=1# 对通过霍夫变换得到的数据进行遍历for line in lines:# newlines1 = lines[:, 0, :]print "line["+str(i-1)+"]=",linex1,y1,x2,y2 = line[0]  #两点确定一条直线,这里就是通过遍历得到的两个点的数据 (x1,y1)(x2,y2)cv2.line(image,(x1,y1),(x2,y2),(0,0,255),2)   #在原图上画线# 转换为浮点数,计算斜率x1 = float(x1)x2 = float(x2)y1 = float(y1)y2 = float(y2)print "x1=%s,x2=%s,y1=%s,y2=%s" % (x1, x2, y1, y2)if x2 - x1 == 0:print "直线是竖直的"result=90elif y2 - y1 == 0 :print "直线是水平的"result=0else:# 计算斜率k = -(y2 - y1) / (x2 - x1)# 求反正切,再将得到的弧度转换为度result = np.arctan(k) * 57.29577print "直线倾斜角度为:" + str(result) + "度"i = i+1#   显示最后的成果图cv2.imshow("line_detect",image)return resultif __name__ == '__main__':# 读入图片src = cv2.imread("lines/line6.jpg")# 设置窗口大小cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE)# 显示原始图片cv2.imshow("input image", src)# 调用函数line_detect(src)cv2.waitKey(0)

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

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

相关文章

企业年报API:打开企业经营大数据的新视角

引言 随着数字化转型的深入推进,企业年报API作为企业信息化建设中的重要组成部分,受到了越来越多企业和机构的关注和重视。而且,随着中国经济的快速发展,企业年报也成为投资者、监管机构以及相关利益方了解企业经营状况的重要途径…

页面的动静分离

动静分离: 访问静态和动态页面分开 实现动态和静态页面负载均衡 实验1: 准备三台虚拟机: 1台nginx代理服务器: 192.168.120.30 2台tomcat: tomcat1:192.168.120.20 tomcat2:192.168.12…

DBeaver clickhouse 时区不对 时间少了8小时,本人的有效,网上好多都是扯犊子

特别注意:use_time_zone Asia/Shanghai use_server_time_zone true

Maven介绍及配置

目录 一.Maven 1.介绍 坐标 仓库 1)中央仓库 2)本地仓库 3)私服 配置国内源 配置过程 二.Maven功能 2.项目构建 3.依赖管理 Maven Help插件 安装 ​使用 一.Maven 1.介绍 坐标 唯一的,通过以下代码的三个键值对确…

大数据治理运营整体解决方案:PPT全文39页,附下载

关键词:大数据,数据治理,数据治理解决方案,数据治理的目的和意义 一、数据治理的定义 数据治理专注于将数据作为企事业单位数据资产进行应用和管理的一套管理机制,能够消除数据的不一致性,建立规范的数据应…

github使用手册

核心代码 配置用户名/邮箱 best practice git init #在本地初始化一个仓库 git add . #将当前目录所有的文件加入&#xff08;注意这里是加入&#xff09;到缓存区 git commit -m "xxx" #将当前缓存区里的内容提交到本地仓库 git remote add <remote_rep_name&g…

人工智能与发电玻璃:未来能源技术的融合

人工智能与发电玻璃&#xff1a;未来能源技术的融合 摘要&#xff1a;本文探讨人工智能与发电玻璃这两项技术的结合&#xff0c;共同推动能源领域的创新。本文将介绍发电玻璃工作原理及应用、人工智能在发电玻璃的应用领域以及共同为可持续能源发展做出贡献。 一、引言 随着科…

熊海CMS 靶场

熊海CMS 靶场 0x01 前言 初步了解cms&#xff0c;Content Management System 内容管理系统。它是一种用于创建、编辑、管理和发布内容的软件程序或工具。内容管理系统通常用于网站、博客、企业内部系统等各种应用中&#xff0c;可以帮助用户管理和发布各种类型的内容&#xf…

YOLO目标检测——苹果缺陷检测数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;苹果质量检测和自动化分拣系统数据集说明&#xff1a;苹果缺陷检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富&#xff0c;含有缺陷图片和没缺陷图片。标签说明&#xff1a;使用lableimg标注软件标注&#xff0c;标注框质量…

【Linux网络】本地DNS服务器搭建

目录 一、什么是DNS&#xff0c;相关介绍 1、dns是什么&#xff1a; 2、域名的分类&#xff1a; 3、服务器的类型 二、DNS解析的过程 三、DNS的相关配置文件学习 1、本地主机有关的DNS文件学习 2、本地的DNS缓存服务器的文件 3、bind软件的相关配置文件&#xff1a; 4…

LinuxMySql

结构化查询语言 DDL&#xff08;数据定义语言&#xff09; 删除数据库drop database DbName; 创建数据库create database DbName; 使用数据库use DbName; 查看创建数据库语句以及字符编码show create database 43th; 修改数据库属性&#xff08;字符编码改为gbk&#xff09;…

μC/OS-II---信号量管理1(os_sem.c)

目录 信号量管理信号量创建信号量删除获取/等待信号量发出信号量 信号量管理 信号量创建 OS_EVENT *OSSemCreate (INT16U cnt) {OS_EVENT *pevent; #if OS_CRITICAL_METHOD 3u /* Allocate storage for CPU status register */OS_CPU_SR cp…