当前位置: 首页 > 编程日记 > 正文

基于 Python 和 OpenCV 构建智能停车系统

360d9999a12fc1c005cc396fefb99080.gif

作者 | 努比

来源 | 小白学视觉

50b1418ed5653e502df109341f1c1ce9.png

当今时代最令人头疼的事情就是找不到停车位,尤其是找20分钟还没有找到停车位。

根据复杂性和效率的不同,任何问题都具有一个或多个解决方案。目前智能停车系统的解决方案,主要包括基于深度学习实现,以及基于重量传感器、光传感器实现等。

本期我们将一起通过使用摄像头和少量代码来实现最简单的智能停车系统。该解决方案所使用的概念非常简单。它由具有以下两个脚本组成:

1. 选择停车位的坐标并将其保存到文件中。

2. 从文件中获取坐标,并确定该点是否可用。

将该解决方案分成两个脚本的原因是,避免在每次确定是否有可用停车位的时候,就进行停车位的选择。

为了使这一过程尽可能简单,从现在开始,我们将这两个脚本称为selector和detector。

相关依赖

在本文中,我们使用python 3.7.6,但其他版本(例如3.6或3.8)当然也可以使用。首先我们要检查python的版本,我们通过在控制台中编写python –version,即可返回已安装的python版本。

C:\Users\Razvan>python --version
Python 3.7.6

在开始构建该系统依赖项之前,我们可以设置一个虚拟环境。通过以下链接我们可以了解更多有关虚拟环境的信息https://docs.python.org/3.7/tutorial/venv.html。

也可以使用conda创建和管理环境。有关更多信息见:

https://docs.anaconda.com/anaconda/。

在python中设置完所有内容后, 最重要的依赖关系将是OpenCV库。通过pip将其添加到虚拟环境中,可以运行pip install opencv-python。

要检查所有设置是否正确,我们可以使用以下cv2.__version__命令打印环境中可用的当前OpenCV版本。

(OpenCV) C:\Users\Razvan>python
Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> print(cv2.__version__)
4.2.0
>>>

在第一行中,我们可以看到在该项目中使用了名为OpenCV的虚拟环境。

步骤

首先,我们需要安装一个停车场摄像头。由于我们并没有一个窗户可以看到的任何停车场,因此我们选择使用旧汽车玩具和印刷纸。另外,我在停车场上方设置了一个网络摄像头,以获取良好的图像,因此我们正在处理的图像如下所示:

4a250f5a6e2f048fe07403e9a6cdd360.png

selector选择器

接下来,我们来介绍编码部分。首先,我们需要构建选择器。我们从导入所需模块开始

import cv2
import csv

之后,我们开始获取图像,在该图像上选择停车位。为此,我们可以选择摄网络摄像头提供的第一帧,保存并使用该图像选择停车位。下面的代码是这样的:

1. 打开image变量中的视频流;suc确定流是否成功打开。

2. 将第一帧写入frame0.jpg。

3. 流被释放,所有窗口都关闭。

4. 新保存的图片将以img变量形式读取。

VIDEO_SOURCE = 1cap = cv2.VideoCapture(VIDEO_SOURCE)
suc, image = cap.read()
cv2.imwrite("frame0.jpg", image)
cap.release()
cv2.destroyAllWindows()
img = cv2.imread("frame0.jpg")

现在,我们已经保存了第一帧并在img变量中将其打开,可以使用selectROIs函数标记停车位。ROI被定义为感兴趣的区域,代表图像的一部分,我们将在其上应用不同的函数以及滤波器来获取结果。

返回到selectROIs函数,这将返回一个列表(类型:numpy.ndarray),其中包含我们组装图像所需的数字及其边界ROI。

r = cv2.selectROIs('Selector', img, showCrosshair = False, fromCenter = False)

我们的列表将保存在变量r中。赋予cv2.selectROIs函数的参数如下:

1. “选择器”是允许我们选择投资回报率的窗口的名称。

2. img是包含我们要选择图像的变量。

3. showCrosshair = Flase删除选区内部的中心线。可以将其设置为True,因为对结果没有影响。

4. fromCenter = False是一个非常重要的参数,因为如果将其设置为True,则正确的选择会困难得多。

724a8e201fa23d183ecdb7edc921e118.png

选择所有停车位之后,是时候将它们写入.csv文件了。为此,我们需要将r变量转换为python列表,可以使用rlist = r.tolist()命令实现。

拥有适当的数据后,我们将其保存到.csv文件中,以备将来使用。

with open('data/rois.csv', 'w', newline='') as outf:csvw = csv.writer(outf)csvw.writerows(rlist)

detector探测器

现在我们已经选择了停车位,是时候进行一些图像处理了。解决这个问题的方法如下:

1. 从.csv文件获取坐标。

2. 从中构建新图像。

3. 应用OpenCV中可用的Canny函数。

4. 计算新图像内的白色像素。

5. 建立一个点内的像素范围将被占用。

6. 在实时供稿上绘制一个红色或绿色矩形。

对于所有这些操作,我们需要定义一个要应用于每个位置的函数。该函数如下所示:

def drawRectangle(img, a, b, c, d):sub_img = img[b:b + d, a:a + c]edges = cv2.Canny(sub_img, lowThreshold, highThreshold)pix = cv2.countNonZero(edges)if pix in range(min, max):cv2.rectangle(img, (a, b), (a + c, b + d), (0, 255, 0), 3)spots.loc += 1else:cv2.rectangle(img, (a, b), (a + c, b + d), (0, 0, 255), 3)

现在我们已经实现了所需的功能,如果我们直接将其应用于.csv文件中的每组坐标效果可能并不好。因此我们做如下处理

首先,我们的有一些参数如果可以在脚本运行时(也可以在通过GUI)实时调整它们,那就更好了。为此,我们需要构建一些轨迹栏。OpenCV为我们提供这项功能。

我们需要一个回调函数,该函数不执行任何操作,但作为使用OpenCV创建轨迹栏的参数是必需的。实际上,回调参数具有明确定义的用途,但我们在此不使用它。要了解有关此内容的更多信息,查阅OpenCV文档。

def callback(foo):pass

现在我们需要创建轨迹栏。我们将使用cv2.namedWindow和cv2.createTrackbar功能。

cv2.namedWindow('parameters')
cv2.createTrackbar('Threshold1', 'parameters', 186, 700, callback)
cv2.createTrackbar('Threshold2', 'parameters', 122, 700, callback)
cv2.createTrackbar('Min pixels', 'parameters', 100, 1500, callback)
cv2.createTrackbar('Max pixels', 'parameters', 323, 1500, callback)

现在,我们已经创建了用于操作参数的GUI,只剩下一件事了。这就是图像中可用斑点的数量。在drawRectangle中定义为spot.loc。这是一个静态变量,必须在程序开始时进行定义。该变量为静态变量的原因是,我们希望调用的每个drawRectangle函数都将其写入相同的全局变量,而不是每个函数都使用一个单独的变量。这样可以防止返回的可用空间数量大于实际的可用空间数量。

为了实现这一点,我们只需要使用它的loc静态变量创建spots类。

class spots:loc = 0

现在我们已经准备就绪,只需要从.csv文件中获取数据,将其所有数据转换为整数,然后在无限循环中应用构建的函数即可。

with open('data/rois.csv', 'r', newline='') as inf:csvr = csv.reader(inf)rois = list(csvr)rois = [[int(float(j)) for j in i] for i in rois]
VIDEO_SOURCE = 1
cap = cv2.VideoCapture(VIDEO_SOURCE)while True:spots.loc = 0ret, frame = cap.read()ret2, frame2 = cap.read()min = cv2.getTrackbarPos('Min pixels', 'parameters')max = cv2.getTrackbarPos('Max pixels', 'parameters')lowThreshold = cv2.getTrackbarPos('Threshold1', 'parameters')highThreshold = cv2.getTrackbarPos('Threshold2', 'parameters')for i in range(len(rois)):drawRectangle(frame, rois[i][0], rois[i][1], rois[i][2], rois[i][3])font = cv2.FONT_HERSHEY_SIMPLEXcv2.putText(frame, 'Available spots: ' + str(spots.loc), (10, 30), font, 1, (0, 255, 0), 3)cv2.imshow('Detector', frame)canny = cv2.Canny(frame2, lowThreshold, highThreshold)cv2.imshow('canny', canny)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()
cv2.destroyAllWindows()

拓展

在我们的循环中实际上只是调用的构建函数要复杂一点。

首先,我们将空间的数量初始化为0,以防止每帧添加数字。

其次,我们进入两个处理流以显示真实图像和已处理的图像。这有助于更好地了解此脚本的工作方式以及图像的处理方式。

然后,我们需要在每次迭代中获取我们创建的参数 GUI中的参数值。这是通过cv2.getTrackbarPos功能完成的。

接下来最重要的部分,将drawRectangle函数应用到Selector脚本获取的所有坐标上。

最后,在结果图像上写下可用斑点的数量,显示Canny函数的结果,显然,这是一种众所周知的停止循环的方法。

我们现在便完成了一个智能停车项目!

36a2f70e9420a6f2601d4949dfa122cc.png

总结

如今,智能停车已成为热门话题之一,并且有许多实现方式可以导致良好的功能系统。我们这处理方法并不是完美的,有许多方法可以更好地优化结果,并且可以在更多情况下使用。但是,即使这不能解决停车场危机,也可能是导致危机 的主要原因。

6ff648c5e638e7adb874760fb78374cb.gif

技术

用python写3D游戏,太赞了

资讯

算力超越iPhone,芯片堪比Mac

技术

31个好用的Python字符串方法

资讯

游戏圈地震级消息,微软收购动视暴雪

98981540413e2cf2accca84fcfd350c0.png

分享

21fbcfae0bf07b3bcb4919bba29a7924.png

点收藏

510e06fa0a816fba7df88a22aea6551f.png

点点赞

3138adba0e624e00ba8f5cd854507173.png

点在看

相关文章:

js获取鼠标位置

1.PageX/PageX:鼠标在页面上的位置,从页面左上角开始,即是以页面为参考点,不随滑动条移动而变化2.clientX/clientY:鼠标在页面上可视区域的位置,从浏览器可视区域左上角开始,即是以浏览器滑动条此刻的滑动到的位置为参考点,随滑动条移动 而变化. 可是悲剧的是,PageX只有FF…

Lua保留指定小数位数

默认会四舍五入 比如:%0.2f 会四舍五入后,保留小数点后2位print(string.format("%.1f",0.26)) ---会输出0.3,而不是0.2 Lua保留一位小数 --- nNum 源数字 --- n 小数位数 function Tool. GetPreciseDecimal(nNum, n)if type(nNum)…

htaccess文件用法收集整理

1.时区设置有些时候,当你在PHP里使用date或mktime函数时,由于时区的不同,它会显示出一些很奇怪的信息。下面是解决这个问题的方法之一。就是设置你的服务器的时区。你可以在这里找到所有支持的时区的清单。 1.SetEnv TZ Australia/Melbourne …

手把手教你使用 YOLOV5 训练目标检测模型

作者 | 肆十二来源 | CSDN博客这次要使用YOLOV5来训练一个口罩检测模型,比较契合当下的疫情,并且目标检测涉及到的知识点也比较多。先来看看我们要实现的效果,我们将会通过数据来训练一个口罩检测的模型,并用pyqt5进行封装&#x…

数据仓库数据模型之:极限存储--历史拉链表

摘要: 在数据仓库的数据模型设计过程中,经常会遇到文内所提到的这样的需求。而历史拉链表,既能满足对历史数据的需求,又能很大程度的节省存储资源。在数据仓库的数据模型设计过程中,经常会遇到这样的需求:1. 数据量比较…

super的用法(带了解)

super的用法(带了解) super的用法(带了解)posted on 2018-05-11 21:31 leolaosao 阅读(...) 评论(...) 编辑 收藏 转载于:https://www.cnblogs.com/leolaosao/p/9026686.html

Posted content type isn't multipart/form-data

版权声明&#xff1a;欢迎转载&#xff0c;请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/48712507 在有文件上传的表单提交过程中&#xff0c;搞不好就会报Posted content type isnt multipart/form-data的错误。 解决办法 <form class"form-…

CSDN 十大技术主题盘点-AI篇

关于2021&#xff0c;我们能看到的技术变化有很多。当云原生向下而生&#xff0c;当分布式数据库席卷而至&#xff0c;当低代码平台扩展了开发的边界&#xff0c;当万物互联蔚然成风……我们看到了太多在2021年形成的变化&#xff0c;但也能看到这些趋势非但没有结束&#xff0…

PHP编程问题集锦

1. Win32下apache2用get方法传递中文参数会出错 test.php?a你好&b你也好传递参数是会导致一个内部错误解决办法:"test.php?a".urlencode(你好)."&b".urlencode(你也好)2. win32下的session不能正常工作 php.ini默认的session.save_path /tmp 这…

jsonp详解

json相信大家都用的多&#xff0c;jsonp我就一直没有机会用到&#xff0c;但也经常看到&#xff0c;只知道是“用来跨域的”&#xff0c;一直不知道具体是个什么东西。今天总算搞明白了。下面一步步来搞清楚jsonp是个什么玩意。 同源策略 首先基于安全的原因&#xff0c;浏览器…

PHP面向对象精华

PHP面向对象精华1 使用extends实现继承以及重载、魔术方法的含义 class B extends A 声明的时候B里可以没有A里的方法 调用的时候$bnew B(); $b->A里的方法(); $b->A里的属性1; $b->B里的方法(); $b->B里的方法(); 如果$anew A(); 可以 $a->A里的方法(); $a->…

springmvc和mybatis整合关键配置

springmvcmybaits的系统架构&#xff1a; 第一步&#xff1a;整合dao层 mybatis和spring整合&#xff0c;通过spring管理mapper接口。 使用mapper的扫描器自动扫描mapper接口在spring中进行注册。 第二步&#xff1a;整合service层 通过spring管理 service接口。 使用配置方式将…

阿里亲制明信片,字节、百度直接发锅……这些公司的新年礼盒越来越会玩~

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍整理 | 王晓曼出品 | 程序人生&#xff08;ID&#xff1a;coder _life&#xff09;每到年末&#xff0c;各大互联网大厂的新年礼盒都会作为…

html中radio、checkbox选中状态研究(静下心来看,静下心来总结)

html中radio、checkbox选中状态研究&#xff08;静下心来看&#xff0c;静下心来总结&#xff09; 一、总结 1、单选框的如果有多个checked 会以最后一个为准 2、js动态添加checked属性&#xff1a;不行&#xff1a;通过 $("[namesex]:eq(1)").attr("checked&q…

新年新气象,100 行 Python 代码制作动态鞭炮

作者 | FrigidWinter来源 | CSDN博客放鞭炮贺新春&#xff0c;在我国有两千多年历史。关于鞭炮的起源&#xff0c;有个有趣的传说。西方山中有焉&#xff0c;长尺余&#xff0c;一足&#xff0c;性不畏人。犯之令人寒热&#xff0c;名曰年惊惮&#xff0c;后人遂象其形&#xf…

php 反射类简介

反射是操纵面向对象范型中元模型的API&#xff0c;其功能十分强大&#xff0c;可帮助我们构建复 杂&#xff0c;可扩展的应用。其用途如&#xff1a;自动加载插件&#xff0c;自动生成文档&#xff0c;甚至可用来扩充 PHP 语言。php 反射api 由若干类组成&#xff0c;可帮助我们…

shell时间

Shell 调用系统时间变量 Linux常用命令获取今天时期&#xff1a;date %Y%m%d 或 date %F 或 $(date %y%m%d) 获取昨天时期&#xff1a;date -d yesterday %Y%m%d 获取前天日期&#xff1a;date -d -2day %Y%m%d 依次类推比如获取10天前的日期&#xff1a;date -d -10day %Y%m%d…

杨老师课堂_Java核心技术下之控制台模拟记事本案例...

预览效果图&#xff1a; 背景介绍&#xff1a; 编写一个模拟记事本的程序通过在控制台输入指令&#xff0c;实现在本地新建文件打开文件和修改文件等功能。 要求在程序中&#xff1a; 用户输入指令1代表“新建文件”&#xff0c;此时可以从控制台获取用户输入的文件内容&#x…

PHP的URL处理

完整URL地址&#xff1a; http://username:passwordhostname/path?argvalue#auchor 协议&#xff1a;http:// 用户名和密码&#xff1a; username:password 以&#xff1a;将两者分隔 主机名&#xff1a;hostname 和/为分隔符 路径&#xff1a; /path 以/开头、包含/符号 参…

UnitOfWork以及其在ABP中的应用

Unit Of Work&#xff08;UoW&#xff09;模式在企业应用架构中被广泛使用&#xff0c;它能够将Domain Model中对象状态的变化收集起来&#xff0c;并在适当的时候在同一数据库连接和事务处理上下文中一次性将对象的变更提交到数据中。 从字面上我们可以我们可以把UnitOfWork叫…

分享3个好用到爆的 Python 模块,点赞收藏

作者 | 俊欣来源 | 关于数据分析与可视化今天给大家介绍3个特别好用的Python模块&#xff0c;知道的人可能不多&#xff0c;但是特别的好用。PsutilPendulumPyfigletPsutilPython当中的Psutil模块是个跨平台库&#xff0c;它能够轻松获取系统运行的进程和系统利用率&#xff0c…

使用XHProf分析PHP性能瓶颈(二)

上一篇文章里&#xff0c;我们介绍了如何基于xhprof扩展来分析PHP性能&#xff0c;并记录到日志里&#xff0c;最后使用xhprof扩展自带的UI在web里展示出来。本篇文章将讲述2个知识点&#xff1a; 使用xhgui代替xhprof的默认UI界面&#xff0c;更便于分析使用tideways扩展替换x…

PHP自动加载类—__autoload()和spl_autoload_register()

test.php <?phpfunction __autoload($class_name) {require_once $class_name . .php;}$obj new j();?> 当前目录下有j.php <?phpclass j{function __construct() {echo "成功加载";} }?> 正常输出&#xff1a;成功加载修改test.php代码<?phpf…

二分 + 模拟 - Carries

Carries Problems Link Mean: 给你n个数&#xff0c;让你计算这n个数两两组合相加的和进位的次数. analyse: 脑洞题. 首先要知道&#xff1a;对于两个数的第k位相加会进位的条件是&#xff1a;a%(10^k)b%(10^k)>10^k. 想到这一点后就简单了&#xff0c;枚举每一位&#…

机器学习的出现,是否意味着“古典科学”的过时?

作者&#xff1a;Laura Spinney译者&#xff1a;刘媛媛原文&#xff1a;Are we witnessing the dawn of post-theory science?让我们回忆一下&#xff0c;Isaac Newton 被一个苹果砸中头部&#xff0c;然后是怎么提出牛顿第二定律——万有引力的&#xff1f;大概过程是这样的&…

MySQL5.6.16二进制源码安装详解及一键安装实现

一、系统环境 1.1操作系统 [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) [rootlocalhost ~]# uname -rm 10.0-693.el7.x86_64 x86_64 [rootlocalhost ~]# 1.2 安装前环境监测 1.2.1.SELinux和系统防火墙关闭 检查selinux [rootlocalho…

基于 OpenCV 的表格文本内容提取

作者 | 小白来源 | 小白学视觉小伙伴们可能会觉得从图像中提取文本是一件很麻烦的事情&#xff0c;尤其是需要提取大量文本时。PyTesseract是一种光学字符识别&#xff08;OCR&#xff09;&#xff0c;该库提了供文本图像。PyTesseract确实有一定的效果&#xff0c;用PyTessera…

Redis以及Redis的php扩展安装无错版

安装Redis 下载最新的 官网&#xff1a;http://redis.io/ 或者 http://code.google.com/p/redis/downloads/list第一步&#xff1a;下载安装编译 #wget http://redis.googlecode.com/files/redis-2.4.4.tar.gz#tar zxvf redis-2.4.4.tar.gz#cd redis-2.4.4#make #make instal…

Android UI SurfaceView的使用-绘制组合图型,并使其移动

绘制容器类&#xff1a; //图形绘制容器 public class Contanier {private List<Contanier> list;private float x0,y0;public Contanier(){listnew ArrayList<Contanier>();}public void draw(Canvas canvas){canvas.save();canvas.translate(getX(), getY());chi…

新型混合共识机制及抗量子特性的 Hcash 主链测试链即将上线

由上海交通大学密码与计算机安全实验室&#xff08;LoCCS&#xff09;及上海观源信息科技有限公司负责研发的、具有新型混合共识机制及抗量子特性的 Hcash 主链代码已完成并在 2017 年 12 月18 日之前上传至github&#xff1a; https://github.com/HcashOrg/hcashd https://git…