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)

python Opencv实现停车位识别思路详解

(2)画好之后,关闭窗口,即可看到已经保存好坐标的文件,下次再运行程序时,不用再画框;程序会读出当前文件,将之前保存好的坐标加载出画出框。

#首先查看文件是否已经包含了CarParkPos文件
try:
   with open('CarParkPos','rb') as fp:
       position=pickle.load(fp)
except:
   # 存储所有停车位的坐标列表
   position=[]

python Opencv实现停车位识别思路详解

(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.整体代码实战

python Opencv实现停车位识别思路详解

(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)视频效果

停车位识别演示

python Opencv实现停车位识别思路详解

注:视频自己做的比较差,建议读者最好自己尝试实现这个思路。

来源:https://blog.csdn.net/Keep_Trying_Go/article/details/125572539

标签:python,Opencv,停车位,识别
0
投稿

猜你喜欢

  • SQL处理时间戳时如何解决时区问题实例详解

    2024-01-22 15:23:11
  • golang 实现每隔几分钟执行一个函数

    2024-05-22 17:48:14
  • Tortoise-orm信号实现及使用场景源码详解

    2021-12-18 23:01:45
  • 利用Math.js解决JS计算小数精度丢失问题

    2024-04-29 13:44:04
  • Python编程实现二分法和牛顿迭代法求平方根代码

    2022-01-03 12:24:46
  • .NET 6中为record类型自定义Equals方法

    2023-07-15 21:29:29
  • 解决vscode中golang插件依赖安装失败问题

    2024-04-26 17:23:15
  • PHP获取客户端及服务器端IP的封装类

    2024-05-03 15:48:38
  • 关于document.cookie的使用javascript

    2024-04-30 08:55:32
  • Python调用高德API实现批量地址转经纬度并写入表格的功能

    2023-12-26 03:22:20
  • Python 元组(Tuple)操作详解

    2023-06-28 15:36:39
  • Python使用smtplib 实现单发和群发邮件验证码

    2023-07-10 13:56:50
  • Python实现实时显示进度条的六种方法

    2022-03-27 02:09:35
  • 详解django中视图函数的FBV和CBV

    2022-05-26 01:11:10
  • Django 设置多环境配置文件载入问题

    2023-09-08 09:16:19
  • 使用c#构造date数据类型

    2024-01-15 22:19:15
  • 定时备份 Mysql并上传到七牛的方法

    2024-01-25 14:11:13
  • Python 错误和异常小结

    2021-08-19 12:17:58
  • 从源码解析Python的Flask框架中request对象的用法

    2021-02-20 02:15:57
  • 基于Python搭建人脸识别考勤系统

    2021-07-08 10:17:42
  • asp之家 网络编程 m.aspxhome.com