python Opencv实现停车位识别思路详解
作者:Keep_Trying_Go 发布时间:2023-10-20 21:54:25
1.实现的思路
(1)首先使用一个处理画框的程序,将图片中的有车和无车的停车位给画出来,并且保存坐标(如果画错了,将鼠标移至要删除的框中,右击鼠标,即可删除);
#定义回调函数
def mouseClick(events,x,y,flags,params):
#按下鼠标左键,将点击的坐标(x,y)保存到position列表中
if (events&cv2.EVENT_LBUTTONDOWN==cv2.EVENT_LBUTTONDOWN):
position.append((x,y))
#按下鼠标右键时,移除选中的框
if (events&cv2.EVENT_RBUTTONDOWN==cv2.EVENT_RBUTTONDOWN):
for i,pos in enumerate(position):
(x1,y1)=pos
if (x1<x<x1+img_width and y1<y<y1+img_height):
position.pop(i)
(2)画好之后,关闭窗口,即可看到已经保存好坐标的文件,下次再运行程序时,不用再画框;程序会读出当前文件,将之前保存好的坐标加载出画出框。
#首先查看文件是否已经包含了CarParkPos文件
try:
with open('CarParkPos','rb') as fp:
position=pickle.load(fp)
except:
# 存储所有停车位的坐标列表
position=[]
(3)主程序的思路
将摄像头读取的图片进行处理
Opencv基础知识点:
https://www.jb51.net/article/254006.htm
高斯去噪:
https://www.jb51.net/article/198212.htm
局部二值化:
https://www.jb51.net/article/248000.htm
中值滤波:
https://www.jb51.net/article/198212.htm
Opencv中获取卷积核:
https://www.jb51.net/article/254013.htm
腐蚀操作:
https://www.jb51.net/article/214725.htm
#转换为灰度图
gray=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2GRAY)
#高斯去噪
gauss=cv2.GaussianBlur(src=gray,ksize=(3,3),sigmaX=0)
#图像二值化处理
thresh=cv2.adaptiveThreshold(src=gauss,maxValue=255,adaptiveMethod=cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
thresholdType=cv2.THRESH_BINARY_INV,blockSize=21,C=16)
# 中值滤波操作
median=cv2.medianBlur(src=thresh,ksize=3)
#腐蚀操作
dilate=cv2.dilate(src=median,kernel=kernel,iterations=1)
for pos in position:
(x,y)=pos
mask=dilate[y:y+img_height,x:x+img_width]
# cv2.imshow(str(x*y),mask)
#返回灰度值不为0的像素数,可用来判断图像是否全黑。
count=cv2.countNonZero(mask)
#当计算的count低于800,表示是一个空位
if count<800:
countBlackCar+=1
color=(0,255,0)
thickness=3
else:
color=(0,0,255)
thickness=2
cv2.rectangle(img=frame, pt1=(pos[0], pos[1]),
pt2=(pos[0] + img_width, pos[1] + img_height),
color=color, thickness=thickness)
cvzone.putTextRect(img=frame, text=str(count), pos=(x + 3, y + img_height - 5),
scale=0.8, thickness=1, offset=0,colorR=color)
参考视频教程:https://www.bilibili.com/video/BV14Z4y1Q7au?t=3992.0(建议看懂视频中的思路)
注:代码不重要,主要是学会给出的链接中这位博主的思路。使用更加简单的方法解决问题,但是呢?这种方法我认为主要是为解决那种固定摄像头拍摄的停车位,因为我们标注的坐标是固定的(但是可以利用深度学习提取有车和无车的特征进行识别,定位的可以使用Opencv来解决)。
2.整体代码实战
(1)ParkingSpacePicker.py
import os
import cv2
import pickle
#首先查看文件是否已经包含了CarParkPos文件
try:
with open('CarParkPos','rb') as fp:
position=pickle.load(fp)
except:
# 存储所有停车位的坐标列表
position=[]
#停车位的高宽
img_width,img_height=47,88
#定义回调函数
def mouseClick(events,x,y,flags,params):
#按下鼠标左键,将点击的坐标(x,y)保存到position列表中
if (events&cv2.EVENT_LBUTTONDOWN==cv2.EVENT_LBUTTONDOWN):
position.append((x,y))
#按下鼠标右键时,移除选中的框
if (events&cv2.EVENT_RBUTTONDOWN==cv2.EVENT_RBUTTONDOWN):
for i,pos in enumerate(position):
(x1,y1)=pos
if (x1<x<x1+img_width and y1<y<y1+img_height):
position.pop(i)
with open('CarParkPos','wb') as fp:
pickle.dump(position,fp)
while True:
img=cv2.imread('images/packing.png')
for pos in position:
cv2.rectangle(img=img,pt1=(pos[0],pos[1]),
pt2=(pos[0]+img_width,pos[1]+img_height),
color=(0,255,0),thickness=2)
cv2.imshow('Packing',img)
#设置鼠标事件
cv2.setMouseCallback('Packing',mouseClick)
key=cv2.waitKey(1)
if key==27:
break
cv2.destroyAllWindows()
if __name__ == '__main__':
print('Pycharm')
(2)main.py
import os
import cv2
import pickle
import cvzone
with open('CarParkPos', 'rb') as fp:
position = pickle.load(fp)
#停车位的高宽
img_width,img_height=47,88
cap=cv2.VideoCapture('video/packing-3.mp4')
def checkParkingSpace(dilate):
countBlackCar=0
for pos in position:
(x,y)=pos
mask=dilate[y:y+img_height,x:x+img_width]
# cv2.imshow(str(x*y),mask)
#返回灰度值不为0的像素数,可用来判断图像是否全黑。
count=cv2.countNonZero(mask)
#当计算的count低于800,表示是一个空位
if count<800:
countBlackCar+=1
color=(0,255,0)
thickness=3
else:
color=(0,0,255)
thickness=2
cv2.rectangle(img=frame, pt1=(pos[0], pos[1]),
pt2=(pos[0] + img_width, pos[1] + img_height),
color=color, thickness=thickness)
cvzone.putTextRect(img=frame, text=str(count), pos=(x + 3, y + img_height - 5),
scale=0.8, thickness=1, offset=0,colorR=color)
return countBlackCar
#获取卷积核
kernel=cv2.getStructuringElement(shape=cv2.MORPH_RECT,ksize=(3,3))
while cap.isOpened():
#循环播放视频文件
if cap.get(cv2.CAP_PROP_POS_FRAMES)==cap.get(cv2.CAP_PROP_FRAME_COUNT):
cap.set(cv2.CAP_PROP_POS_FRAMES,0)
ret,frame=cap.read()
# frame=cv2.resize(src=frame,dsize=(750,600))
height,width,channel=frame.shape
if not ret:
break
#转换为灰度图
gray=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2GRAY)
#高斯去噪
gauss=cv2.GaussianBlur(src=gray,ksize=(3,3),sigmaX=0)
#图像二值化处理
thresh=cv2.adaptiveThreshold(src=gauss,maxValue=255,adaptiveMethod=cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
thresholdType=cv2.THRESH_BINARY_INV,blockSize=21,C=16)
# 中值滤波操作
median=cv2.medianBlur(src=thresh,ksize=3)
#腐蚀操作
dilate=cv2.dilate(src=median,kernel=kernel,iterations=1)
cntCar=checkParkingSpace(dilate)
cvzone.putTextRect(img=frame,text="BlackPosition: "+str(cntCar),
pos=(20,height-80),scale=1.0,thickness=2)
cv2.imshow('img',frame)
# cv2.imshow('thresh',thresh)
# cv2.imshow('median',median)
# cv2.imshow('dilate',dilate)
key=cv2.waitKey(30)
if key==27:
break
cv2.destroyAllWindows()
if __name__ == '__main__':
print('Pycharm')
(3)视频效果
停车位识别演示
注:视频自己做的比较差,建议读者最好自己尝试实现这个思路。
来源:https://blog.csdn.net/Keep_Trying_Go/article/details/125572539
猜你喜欢
- 给浏览器绑定事件有时候是非常痛苦的事情,不同的浏览器提供不尽相同的功能的同时,也提供了不同的事件。例如,IE 系列的浏览器支持 mousee
- 环境:windows10_x64python3.9_x64pjsua-2.10vs2015pjsua编译参考这里: https://www.
- 前言本文主要任务是使用通过 tf.keras.Sequential 搭建的模型进行各种花朵图像的分类,主要涉及到的内容有三个部分:使用 tf
- * address - 地址 * blockquote - 块引用 * center - 举中对齐块 * di
- 在 JavaScript 中,可以用 instanceof 来判断一个对象是不是某个类或其子类的实例。比如:// 代码
- 我们知道**代表次方。如下>>>12 * 12144>>>12 ** 2144>>>a
- 实现一个不规则窗体这里我们实现一个圆形窗体,实现其他形状的窗体与这个方法类似。首先,把窗口的高度(height)和宽度(width)值修改为
- 前言日常开发中,我们使用mysql来实现分页功能的时候,总是会用到mysql的limit语法.而怎么使用却很有讲究的,今天来总结一下.lim
- 最近一个开发需求中要求用pandas实现该需求:逐行对比两列,选出每行两列中较大的值加到第三列翻了下好像没有类似的函数,所以没办法要自己造轮
- 稀疏矩阵格式 coo_matrixcoo_matrix是最简单的稀疏矩阵存储方式,采用三元组(row, col, data)(或称为ijv
- 包 packageGo 包是 Go 语言的基本组成单元,一个 Go 程序就是一组包的集合,所有 Go 代码都位于包中Go 源码可以导入其他
- 如下所示:import itchat, timefrom itchat.content import TEXT#name = ' &
- laravel-admin后台框架的select选择框的默认选中,结合select2的js插件;文档http://laravel-admin
- 查询学生步骤1:设置导航 步骤2:添加路由步骤3:创建页面步骤:步骤1:准备2个变量(pageInfo、studentVo)步骤2
- 在制作登录页面时学习了TK弹窗的输入文本框的使用,下面让我们一起来学习一下TK弹窗中的输入框及文本框的使用方法吧!输入框要想制作一个输入弹窗
- 1、绘制简单曲线图思路:通过3个坐标点,绘制曲线import matplotlib.pyplot as plt plt.plot(
- 一、reversereverse()是python中列表的一个内置方法(在字典、字符串和元组中没有这个内置方法),用于列表中数据的反转例子:
- 1 读/写文件NumPy文件读写主要有二进制的文件读写和文件列表形式的数据读写两种形式1、二进制的文件读写save函数是以二进制的格式保存数
- 提取python字符串括号中的内容一些数据按字符串保存,如str1 = '(1, 0.123) (2, 0.234)',当我
- 本文主要用python实现了对网站的模拟登录。通过自己构造post数据来用Python实现登录过程。当你要模拟登录一个网站时,首先要搞清楚网