Python中使用Opencv开发停车位计数器功能


Posted in Python onApril 04, 2022

在这个项目中,我们将创建一个停车位计数器。我们会发现总共有多少辆车,以及有多少停车位是空的。关于本教程最好的一点是,我们将使用基本的图像处理技术来解决这个问题,没有使用机器学习、深度学习进行训练来识别。

1. 环境安装

1.1 安装并激活虚拟环境

python -m venv venv
cd venv\Scripts
.\activate.bat

1.2 python包安装

pip install opencv-python

2. 绘制停车位矩形框

2.1 导入停车场图片

import cv2
import pickle
img=cv2.imread('carParkImg.png')
cv2.imshow("image",img)

Python中使用Opencv开发停车位计数器功能

2.2 绘制矩形框 定位停车位

import cv2
import pickle
img=cv2.imread('carParkImg.png')
cv2.rectangle(img,(50,192),(157,240),(255,0,255),2)  #坐标位置可以多次尝试确定
cv2.imshow("image",img)
cv2.waitKey(0)

Python中使用Opencv开发停车位计数器功能

可以看出,每个停车位的估计宽、高为:

width=107  # 157-102
height = 48 # 240 - 192

2.3 鼠标添加、删除停车位

import cv2
import pickle
img=cv2.imread('carParkImg.png')
width,height = 107,48
posList = []   # 鼠标点击的坐标集合
def mouseClick(events,x,y,flags,params):
	if events == cv2.EVENT_LBUTTONDOWN:
		posList.append((x,y))
while True:
	img = cv2.imread("carParkImg.png")
	cv2.imshow("images",img)
	for pos in posList:
		cv2.rectangle(img,pos,(pos[0]+width,pos[1]+height),(255,0,255),2)  #坐标位置可以多次尝试确定
	cv2.imshow("image",img)
	cv2.setMouseCallback("images",mouseClick)
	if cv2.waitKey(10) & 0xFF== ord('q'):
		break

Python中使用Opencv开发停车位计数器功能

通过鼠标点击在任何位置添加矩形框,但当矩形框位置出错时,无法进行删除。因此通过添加鼠标右键的事件,删除错误的矩形框。

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 +width and y1 < y <y1 +height:
			posList.pop(i)

通过pickle.dump()保持保存鼠标点击的位置信息。

with open('CarParkPos','wb') as f:
	pickle.dump(posList,f)

通过pickle.load()加载保存好的位置信息,即在原有的停车位添加或删除停车位,而不是每一帧画面重新绘制。

with open('CarParkPos','wb') as f:
	posList = pickle.load(f)

完整代码如下:

import cv2
import pickle
img=cv2.imread('carParkImg.png')
width,height = 107,48
try:
	with open('CarParkPos','rb') as f:
		posList = pickle.load(f)
except:
	posList = []
# 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 +width and y1 < y <y1 +height:
			posList.pop(i)
	
	with open('CarParkPos','wb') as f:
		pickle.dump(posList,f)
while True:
	img = cv2.imread("carParkImg.png")
	for pos in posList:
		cv2.rectangle(img,pos,(pos[0]+width,pos[1]+height),(255,0,255),2)  #坐标位置可以多次尝试确定
	cv2.imshow("image",img)
	cv2.setMouseCallback("image",mouseClick)
	
	if cv2.waitKey(10) & 0xFF== ord('q'):
		break

3. 停车位视频分析

3. 1 停车监控视频

import cv2
import pickle
import cvzone
import numpy as np
# Video feed
cap = cv2.VideoCapture('carPark.mp4')
while True:
    success,img= cap.read()
    cv2.imshow("Image",img)
    if cv2.waitKey(10) & 0xFF== ord('q'):
        break

视频时间比较短,为了让视频循环播放,添加如下代码:

if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT):  
	cap.set(cv2.CAP_PROP_POS_FRAMES,0)
  • cv2.CAP_PROP_POS_FRAMES :视频播放当前帧
  • cv2.CAP_PROP_FRAME_COUNT :视频总帧数

即:当前视频播放到结尾时,重新播放

3. 2 截取停车位

截取停车位,回来对每个停车位进行图像处理,从而分析该停车位是否被占用

def checkParkingSpace():
    for pos in posList:
        x,y = pos
        imgCrop=img[y:y+height,x:x+width]
        cv2.imshow(str(x*y),imgCrop)

Python中使用Opencv开发停车位计数器功能

3. 3 图像处理

对图像二值化、高斯模糊处理

imgGray =cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imgBlur =cv2.GaussianBlur(imgGray,(3,3),1)

Python中使用Opencv开发停车位计数器功能

利用自适应二值化对图像进行处理

imgThreshold=cv2.adaptiveThreshold(imgBlur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,25,16)

cv2.adaptiveThreshold 参数的选择可以通过TrackBar拖到滚动条,直到选择合适的数值。

Python中使用Opencv开发停车位计数器功能

可以看出停车位上有车辆时白色像素点比较多,停车位没有车辆时,白色像素点很少甚至没有,因此我们可以基于白色像素点数量来确定该车为是否被占用。同时可以看到当停车位为空时存在一些椒盐噪声,通过medianBlur来处理椒盐噪声

imgMedian = cv2.medianBlur(imgThreshold,5)

Python中使用Opencv开发停车位计数器功能

可以看出椒盐噪声少了一部分。
使用dilate(膨胀)增强白色像素值,便于更好区分每个停车位是否被占用

kernel=np.ones((3,3),np.uint8);
 imgDilate=cv2.dilate(imgMedian,kernel,iterations=1)

Python中使用Opencv开发停车位计数器功能

可以看出白色的轮廓比之前加厚了

3. 4 判断停车位是否被占用

截取每个停车位,经过处理后的图像,统计白色像素的数量
修改checkParkingSpace函数,将处理好的图像传入函数

def checkParkingSpace(imgProc):
    for pos in posList:
        x,y = pos  
        imgCrop=imgProc[y:y+height,x:x+width]
        count=cv2.countNonZero(imgCrop)
        cvzone.putTextRect(img,str(count),(x,y+height-3,scale =1.5,thickness=2,offset=0)

Python中使用Opencv开发停车位计数器功能

对比可以看出,占有车位的数值比较大1000-2000,空车位的200-500,数值的差距比较大。

画出所有停车位,对比找出合适的阈值,区分停车位为空还是被占用了。

Python中使用Opencv开发停车位计数器功能

可以看出停车位为空时,值为0-600,而停车位被占用,值为:960-2300,因此我们设定阈值为750。所以低于750此时停车位没有车,高于950则停车位有车。

Python中使用Opencv开发停车位计数器功能

加上文字描述

代码

import cv2
import pickle
import cvzone
import numpy as np
# Video feed
cap = cv2.VideoCapture('carPark.mp4')
with open('CarParkPos','rb') as f:
    posList = pickle.load(f)
width,height=107,48
def checkParkingSpace(imgProc):
    spaceCounter=0
    for pos in posList:
        x,y = pos  
        imgCrop=imgProc[y:y+height,x:x+width]
        count=cv2.countNonZero(imgCrop)
        
        if count < 950:
            color = (0,255,0)
            thickness = 5
            spaceCounter +=1
        else:
            color = (0,0,255)
            thickness = 2
        cv2.rectangle(img,pos,(pos[0]+width,pos[1]+height),color,thickness=thickness)
        cvzone.putTextRect(img,str(count),(x,y+height-5),scale =1.5,thickness=2,offset=0,colorR=color)
    cvzone.putTextRect(img,f'Free{spaceCounter}/{len(posList)}',(100,50),scale =3,thickness=5,offset=20,colorR=(0,200,0))
            
while True:
    if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT):  
        cap.set(cv2.CAP_PROP_POS_FRAMES,0)
    
    success,img= cap.read()  
    imgGray =cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    imgBlur =cv2.GaussianBlur(imgGray,(3,3),1)  
    imgThreshold=cv2.adaptiveThreshold(imgBlur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,25,16)
    imgMedian = cv2.medianBlur(imgThreshold,5)
    kernel=np.ones((3,3),np.uint8);
    imgDilate=cv2.dilate(imgMedian,kernel,iterations=1)
    checkParkingSpace(imgDilate)
    # for pos in posList:
    #     cv2.rectangle(img,pos,(pos[0]+width,pos[1]+height),(255,0,255),2)
    cv2.imshow("Image",img)
    # cv2.imshow("imgBlur",imgBlur)
    # cv2.imshow("imgThreshold",imgThreshold)
    # cv2.imshow("imgMedian",imgMedian)
    # cv2.imshow("imgDilate",imgDilate)
    if cv2.waitKey(10) & 0xFF== ord('q'):
        break

最终效果如下:

Python中使用Opencv开发停车位计数器功能

源码链接:https://github.com/yuanxinshui/Opencv-project/tree/main/39%20Parking%20Space%20Counter

到此这篇关于Python中使用Opencv开发停车位计数器的文章就介绍到这了,更多相关python Opencv停车位计数器内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python获取Windows或Linux主机名称通用函数分享
Nov 22 Python
python破解zip加密文件的方法
May 31 Python
Python使用googletrans报错的解决方法
Sep 25 Python
Python实现最大子序和的方法示例
Jul 05 Python
如何使用Python自动控制windows桌面
Jul 11 Python
Python pip 安装与使用(安装、更新、删除)
Oct 06 Python
python 微信好友特征数据分析及可视化
Jan 07 Python
python GUI框架pyqt5 对图片进行流式布局的方法(瀑布流flowlayout)
Mar 12 Python
Python多线程正确用法实例解析
May 30 Python
python 使用xlsxwriter循环向excel中插入数据和图片的操作
Jan 01 Python
利用Python+OpenCV三步去除水印
May 28 Python
使用Django实现商城验证码模块的方法
Jun 01 Python
Python采集股票数据并制作可视化柱状图
python疲劳驾驶困倦低头检测功能的实现
Python实现自动玩连连看的脚本分享
Apr 04 #Python
Python利用Turtle绘制哆啦A梦和小猪佩奇
Python必备技巧之函数的使用详解
Python批量解压&压缩文件夹的示例代码
Apr 04 #Python
Python调用腾讯API实现人脸身份证比对功能
You might like
最小化数据传输――在客户端存储数据
2006/10/09 PHP
php实现表单提交上传文件功能
2018/05/28 PHP
php的扩展写法总结
2019/05/14 PHP
laravel Model 执行事务的实现
2019/10/10 PHP
利用json获取字符出现次数的代码
2012/03/22 Javascript
JavaScript开发Chrome浏览器扩展程序UI的教程
2016/05/16 Javascript
关于Jquery中的事件绑定总结
2016/10/26 Javascript
JavaScript利用正则表达式替换字符串中的内容
2016/12/12 Javascript
js 原生判断内容区域是否滚动到底部的实例代码
2017/11/15 Javascript
vue组件的写法汇总
2018/04/12 Javascript
vue实现商品加减计算总价的实例代码
2018/08/12 Javascript
webpack 从指定入口文件中提取公共文件的方法
2018/11/13 Javascript
JavaScript快速调试的两个技巧
2020/11/04 Javascript
python Django模板的使用方法
2016/01/14 Python
Python实现的排列组合计算操作示例
2017/10/13 Python
Python排序搜索基本算法之归并排序实例分析
2017/12/08 Python
用python的requests第三方模块抓取王者荣耀所有英雄的皮肤实例
2017/12/14 Python
python pandas写入excel文件的方法示例
2019/06/25 Python
python3安装crypto出错及解决方法
2019/07/30 Python
对YOLOv3模型调用时候的python接口详解
2019/08/26 Python
python IP地址转整数
2020/11/20 Python
HTML5中视频音频的使用详解
2017/07/07 HTML / CSS
html5基础标签(html5视频标签 html5新标签用法)
2013/12/30 HTML / CSS
Marlies Dekkers内衣荷兰官方网店:荷兰奢侈内衣品牌
2020/03/27 全球购物
String这个类型的class为何定义成final?
2012/11/13 面试题
Java如何读取CLOB字段
2013/10/10 面试题
四风问题自查报告剖析材料
2014/02/08 职场文书
中学教师教育感言
2014/02/21 职场文书
法人授权委托书
2014/04/03 职场文书
商场圣诞节活动总结
2015/05/06 职场文书
职场新人刚入职工作总结该怎么写?
2019/05/15 职场文书
Pytest allure 命令行参数的使用
2021/04/18 Python
python playwright 自动等待和断言详解
2021/11/27 Python
分享3个非常实用的 Python 模块
2022/03/03 Python
Oracle配置dblink访问PostgreSQL的操作方法
2022/03/21 PostgreSQL
Python中np.random.randint()参数详解及用法实例
2022/09/23 Python