实战 | 基于OpenCV的停车场空余车位实时监测系统(详细步骤 + 源码)
导 读
本文主要介绍如何使用Python和OpenCV实现一个停车场空余车位实时监测系统,并包含详细步骤和源码。
背景介绍
介绍实现步骤之前,先来看看测试视频(小型停车场实时监控画面):
,时长00:28
我们的目标是实时检测停车场剩余空位数量,以此来提示将要进入停车场的司机是否有空位。
实现步骤
完成一个停车场实时空位检测系统的主要步骤如下:
① 设定每个停车位ROI;
② 设计停车与空位的判断方法;
③ 对每个ROI分别判断状态;
④ 实时检测输出结果。
1
设定每个停车位ROI
停车位ROI的设定可以根据实际情况处理,一般停车位比较多且有规律的可以使用坐标间隔增加的方式自动设定。本文实例中停车位较少,且中间有部分特殊位置,所以采用手动框选设定方法。如下图所示:
鼠标左键按下,标记新的停车位;鼠标右键按下且点击位置位于矩形内,删除对应矩形。实现代码如下:
import cv2
import pickle
rectW,rectH=107,48
try:
with open('carParkPos','rb') as f:
posList=pickle.load(f)
except:
posList=[]
def mouseClick(events,x,y,flags,params):
if events==cv2.EVENT_LBUTTONDOWN:
posList.append((x,y))
if events==cv2.EVENT_RBUTTONDOWN:
for i,pos in enumerate(posList):
x1,y1=pos
if x1<x<x1+rectW and y1<y<y1+rectH:
posList.pop(i)
with open('carParkPos','wb') as f:
pickle.dump(posList,f)
while True:
img=cv2.imread("img.png")
for pos in posList: cv2.rectangle(img,pos,(pos[0]+rectW,pos[1]+rectH),(0,0,255),2)
cv2.imshow("Image",img)
cv2.setMouseCallback("Image",mouseClick)
if cv2.waitKey(1) == 27:
break
直至标记好所有的停车位ROI,并写入文件,效果如下:
2
为设计停车与空位的判断方法
选择停车状态和空位状态的图片各2张,做演示说明:
判断停车状态与空位状态的具体步骤如下:
① 转为灰度图;
② 高斯滤波;
③ 自适应二值化;
④ 中值滤波 + 膨胀;
⑤ 计算非0像素数量;
⑥ 判断结果:非0像素数量 < 900则为空位,否则表示停车状态。
代码与效果如下:
import cv2
import numpy as np
img = cv2.imread('2.png')
cv2.imshow('src', img)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
blur=cv2.GaussianBlur(gray,(3,3),1)
Thre=cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,25,16)
blur=cv2.medianBlur(Thre,5)
kernel=np.ones((3,3),np.uint8)
dilate=cv2.dilate(blur,kernel,iterations=1)
count=cv2.countNonZero(dilate)
cv2.imshow('dilate', dilate)
print(count)
if count<900:
cv2.rectangle(img, (0, 0), (img.shape[1],img.shape[0]), (0, 255, 0), 5)
else:
cv2.rectangle(img, (0, 0), (img.shape[1],img.shape[0]), (0, 0, 255), 5)
cv2.imshow('result', img)
cv2.waitKey()
cv2.destroyAllWindows()
绿色矩形表示空位,红色矩形表示停车,数量表示非0像素数。
3
对每个ROI分别判断状态
从坐标文件中循环读取位置信息,依次判断每个ROI的状态:
with open('carParkPos','rb') as f:
posList=pickle.load(f)
frame_counter = 0
def check(imgPro):
spaceCount=0
for pos in posList:
x,y=pos
crop=imgPro[y:y+rectH,x:x+rectW]
count=cv2.countNonZero(crop)
if count<900:
spaceCount+=1
color=(0,255,0)
thick=5
else:
color=(0,0,255)
thick=2
cv2.rectangle(img,pos,(x+rectW,y+rectH),color,thick)
cv2.rectangle(img,(45,30),(250,75),(180,0,180),-1)
cv2.putText(img,f'Free: {spaceCount}/{len(posList)}',(50,60),cv2.FONT_HERSHEY_SIMPLEX,0.9,(255,255,255),2)
4
实时检测输出结果
实时检测输出结果,代码和效果如下:
import cv2
import numpy as np
import pickle
rectW,rectH=107,48
cap=cv2.VideoCapture('carPark.mp4')
with open('carParkPos','rb') as f:
posList=pickle.load(f)
frame_counter = 0
def check(imgPro):
spaceCount=0
for pos in posList:
x,y=pos
crop=imgPro[y:y+rectH,x:x+rectW]
count=cv2.countNonZero(crop)
if count<900:
spaceCount+=1
color=(0,255,0)
thick=5
else:
color=(0,0,255)
thick=2
cv2.rectangle(img,pos,(x+rectW,y+rectH),color,thick)
cv2.rectangle(img,(45,30),(250,75),(180,0,180),-1)
cv2.putText(img,f'Free: {spaceCount}/{len(posList)}',(50,60),cv2.FONT_HERSHEY_SIMPLEX,0.9,(255,255,255),2)
while True:
_,img=cap.read()
if frame_counter == cap.get(cv2.CAP_PROP_FRAME_COUNT):
frame_counter = 0 #Or whatever as long as it is the same as next line
cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, 0)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
blur=cv2.GaussianBlur(gray,(3,3),1)
Thre=cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,25,16)
blur=cv2.medianBlur(Thre,5)
kernel=np.ones((3,3),np.uint8)
dilate=cv2.dilate(blur,kernel,iterations=1)
check(dilate)
cv2.imshow("Image",img)
cv2.waitKey(10)
参考链接 & 源码下载
https://github.com/creativekids11/Car-Parking-Space-Counter-Detector
实战 | 基于OpenCV的停车场空余车位实时监测系统(详细步骤 + 源码)相关推荐
- 实战 | 用Python和MediaPipe搭建一个嗜睡检测系统 (详细步骤 + 源码)
导读 本文将使用Python和MediaPipe搭建一个嗜睡检测系统 (包含详细步骤 + 源码). 背景介绍 疲劳驾驶的危害不堪设想,据了解,21%的交通事故都因此而生,尤其是高速路上,大多数车辆都是 ...
- 基于JAVA纺织代加工车间生产状态监测系统计算机毕业设计源码+系统+lw文档+部署
基于JAVA纺织代加工车间生产状态监测系统计算机毕业设计源码+系统+lw文档+部署 基于JAVA纺织代加工车间生产状态监测系统计算机毕业设计源码+系统+lw文档+部署 本源码技术栈: 项目架构:B/S ...
- 基于JAVA机票实时比价系统计算机毕业设计源码+数据库+lw文档+系统+部署
基于JAVA机票实时比价系统计算机毕业设计源码+数据库+lw文档+系统+部署 基于JAVA机票实时比价系统计算机毕业设计源码+数据库+lw文档+系统+部署 本源码技术栈: 项目架构:B/S架构 开发语 ...
- [智慧农业]Python基于改进YOLOv5的猕猴桃叶病害检测系统(完整源码&数据集&视频教程)
1.背景 现如今由于农作物病虫害的多样性和复杂性,在特定的条件下其很容易在大范围内发生,导致农产品产量急剧下降.因此,预防和监测农作物病虫害已成为农业生产活动中的重要环节.当前,耕地面积逐渐减少,世界 ...
- 基于改进YOLOv5的猕猴桃叶病害检测系统(完整源码&数据集&视频教程)
1.背景 现如今由于农作物病虫害的多样性和复杂性,在特定的条件下其很容易在大范围内发生,导致农产品产量急剧下降.因此,预防和监测农作物病虫害已成为农业生产活动中的重要环节.当前,耕地面积逐渐减少,世界 ...
- 基于JAVA诚越园区垃圾分类信息科普系统计算机毕业设计源码+系统+lw文档+部署
基于JAVA诚越园区垃圾分类信息科普系统计算机毕业设计源码+系统+lw文档+部署 基于JAVA诚越园区垃圾分类信息科普系统计算机毕业设计源码+系统+lw文档+部署 本源码技术栈: 项目架构:B/S架构 ...
- 基于java生物遗传病的治疗和防范系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
基于java生物遗传病的治疗和防范系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署 基于java生物遗传病的治疗和防范系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部 ...
- 基于JAVA甜趣网上蛋糕店订购系统计算机毕业设计源码+数据库+lw文档+系统+部署
基于JAVA甜趣网上蛋糕店订购系统计算机毕业设计源码+数据库+lw文档+系统+部署 基于JAVA甜趣网上蛋糕店订购系统计算机毕业设计源码+数据库+lw文档+系统+部署 本源码技术栈: 项目架构:B/S ...
- 基于JAVA深州市特色蜜桃产业电子商务系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
基于JAVA深州市特色蜜桃产业电子商务系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署 基于JAVA深州市特色蜜桃产业电子商务系统计算机毕业设计源码+系统+mysql数据库+lw文档+部 ...
最新文章
- 开坑,写点Polymer 1.0 教程第3篇——组件注册与创建
- matlab uitree update,elementUI tree 懒加载 更新节点
- docker中开启时运行多个不同进程,安装ssh,并在启动docker时与jenkins同时启动运行
- 94授权登录steam怎么用_Steam手机令牌如何绑定,绑定后好处多多
- 牛客竞赛语法入门班数组栈、队列和stl习题【未完成】
- 每天读一遍,不久你就会变
- 为什么说 Java 是按值传递的?
- imx6q 开发板_mplayer移植-迅为IMX6Q开发板
- 高级程序员和低级程序员的区别
- C++Primer学习笔记:第2章 变量和基本类型
- 批量更新数据(BatchUpdate)
- live555的安装 RTSP点播消息流程实例(客户端:VLC, RTSP服务器:LIVE555 Media Server)
- igs无法分配驱动器映射表_硬盘无法使用,用DiskPart进行分区和格式化,非常简单...
- 教你如何挑选深度学习GPU
- java 大文件上传_JAVA大文件上传分片上传方法(附带demo)
- CentOS 7中源码安装MySQL 5.7.16 ----已测试验证
- 计算机领域各个技术——汇总篇
- [Offer收割]编程练习赛42
- slackware简介
- java 封闭类型_java – 如何获取封闭类?
热门文章
- 原生JS实现全屏和退出全屏详解
- 都仿佛向人们宣告秋天到来了
- 属于计算机主机性能的指标是,内存的性能指标有哪些 主要参数是什么
- 【计算机网络】物理层 : 传输介质 ( 导向性传输介质 | 双绞线 | 同轴电缆 | 光纤 | 非导向性传输介质 | 无线电波 | 微波 | 红外线 、激光 )
- openresty服务器
- init java中什么用法_使用tkinter在GUI中__init__
- UVa 211 The Domino Effect 多米诺效应 暴力搜索
- Python学习之环境搭建
- 无锡会计培训——初级会计考试难吗?
- spark Standalone