实战 | 基于OpenCV的停车场空余车位实时监测系统(详细步骤 + 源码)

news/2024/12/25 8:19:52/

导  读

    本文主要介绍如何使用Python和OpenCV实现一个停车场空余车位实时监测系统,并包含详细步骤和源码。

      

背景介绍

    介绍实现步骤之前,先来看看测试视频(小型停车场实时监控画面):

,时长00:28

    我们的目标是实时检测停车场剩余空位数量,以此来提示将要进入停车场的司机是否有空位。

      

实现步骤

    完成一个停车场实时空位检测系统的主要步骤如下:

    ① 设定每个停车位ROI;

    ② 设计停车与空位的判断方法;

    ③ 对每个ROI分别判断状态;

    ④ 实时检测输出结果。

1

设定每个停车位ROI

    停车位ROI的设定可以根据实际情况处理,一般停车位比较多且有规律的可以使用坐标间隔增加的方式自动设定。本文实例中停车位较少,且中间有部分特殊位置,所以采用手动框选设定方法。如下图所示:

    鼠标左键按下,标记新的停车位;鼠标右键按下且点击位置位于矩形内,删除对应矩形。实现代码如下:

import cv2import 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 cv2import 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 = 0def 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 cv2import numpy as npimport pickle
rectW,rectH=107,48
cap=cv2.VideoCapture('carPark.mp4')
with open('carParkPos','rb') as f:    posList=pickle.load(f)frame_counter = 0def 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


http://www.ppmy.cn/news/3599.html

相关文章

centos开发环境配置

文章目录一、更新yum源二、安装必要软件三、系统设置三、开发环境搭建3.1 docker3.2 k8s系列3.2.1 kubectl3.2.2 rke3.3 软件存放目录3.4 go3.5 java3.6 x11 图形界面3.7 goland3.8 git 升级到2.x一、更新yum源 # 对于 CentOS 7 sudo sed -e s|^mirrorlist|#mirrorlist|g \-e …

Android -- 每日一问:回调函数和观察者模式的区别?

知识点 观察者模式 网上很容易查到观察者模式的定义&#xff1a; 观察者模式定义了对象间的一种一对多依赖关系&#xff0c;使得每当一个对象改变状态&#xff0c;则所有依赖于它的对象都会得到通知并被自动更新。 Android中大量的使用了观察者模式。你可能已经用过ListView…

Java+Servlet电商购物系统(含源码+论文+答辩PPT等)

项目功能简介: 本项目含代码详细讲解视频&#xff0c;手把手带同学们敲代码从0到1完成项目 该项目采用技术MyBatis、Tomcat服务器、MySQL数据库 项目含有源码、配套开发软件、软件安装教程、项目发布教程。 项目涉及的技术&#xff1a; 1、前端&#xff1a;JSP、css、Javascrip…

水果FLStudio21.0.0软件最新版有哪些新增功能变化?

FL Studio(水果软件)21 引入更快、更精确的音频编辑、改进的内容发现、对 DAW 情绪的控制以及更多鼓舞人心的创意工具。FL Studio是一款功能非常强大的音乐创作编辑软件它就是FL Studio(水果软件)。使用FL Studio中文版可以轻松帮我们制作自己的音乐唱片&#xff0c;拥有强大且…

【操作系统】模式切换篇

CPU的模式 什么是CPU的模式&#xff1f;这和CPU的发展过程有关&#xff0c;最开始CPU是8位的&#xff0c;后来发展到16位&#xff0c;然后是32位&#xff0c;现在是64位&#xff0c;多少多少位指的是寄存器的位宽。CPU能使用的寄存器宽度以及CPU使用的指令等就构成了CPU的模式…

Python使用Selenium Webdriver爬取网页所有内容

Python使用Selenium Webdriver爬取网页所有内容一、为什么我抓不到网页的全部html内容二、Selenium的基本使用三、使用Selenium抓取全部HTML一、为什么我抓不到网页的全部html内容 有时候&#xff0c;我们在用urllib或者requests库抓取页面时&#xff0c;得到的html源代码和浏…

Sysmac Studio使用Tortoise和Git实现版本控制

Sysmac Studio使用Tortoise和Git实现版本控制 实验时间:2022/11/16 实验软件:Sysmac Studio(1.52,需要软件授权支持版本控制)、Git(2.38.1)、Tortoise(2.13.0)、gitee(代码仓库) 实验目的:Sysmac Studio实现版本控制、多人同时开发(需要有Git和tortoris使用基础) 实验…

endo BCN-PEG4-COOH,1881221-47-1,endo BCN-四聚乙二醇-羧酸特点分享

●外观以及性质&#xff1a; endo BCN-PEG4-acid含有BCN基团和羧酸基团&#xff0c;酸基团可以在偶联条件下与胺反应形成酰胺键。BCN基团可以发生点击化学反应。 【产品理化指标】&#xff1a; ●中文名&#xff1a;endo BCN-四聚乙二醇-羧酸 ●英文名&#xff1a;endo BCN-P…