使用计算机视觉实现停车位(可用)自动计数(amazing)

 如何实现停车位自动计数?对于这个问题,第一个回答就是使用深度学习,构建卷积神经网络,通过使用大量的数据进行训练,使得程序具有识别停车位的能力。当然,这是一个方法。很显然,这个方法比较复杂,需要大量的数据集。对于,一般电脑的Gpu,处理时间太长。在这里,我将从另一个角度——图像角度,准确来说,应该是像素角度来进行这项工作。

前期准备:确保计算机中已安装下列第三方库

1,opencv-python

2,pickle

3,cvzone

4,numpy

5,pycharm或其它IDE(建议使用pycharm)

安装方法,通过命令行窗口安装(pip install 库名),对于pycharm,则可以通过file菜单,setting目录下的python Interpreter 窗口安装。(安装成功与否与网络好坏有较大关系)

 本项目分为两大部分

第一部分:检测位置标注(这里用的是手动标注,当然,要实现自动标注有较大的难度

要标注的场景图片:

标注后的图片:

也就是把要检测停车位都标注出来(用框框圈起来就行,大小要合适,不然影响检测)

代码实现:

import cv2
import pickle

width, height = 107, 48#经过标注尝试,得出的停车位大小

try:
    with open('CarParkPos', 'rb') as f:#rb,只读模式
        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 + width and y1 < y < y1 + height:
                posList.pop(i)#删除鼠标点击位置
    with open('CarParkPos', 'wb') as f:#wb,覆盖写模式,文件不存在则创建,存在则完全覆盖
        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)#监测鼠标函数
    cv2.waitKey(1)

注意:车位的高度和宽度,是通过数次标注实验来确定的

也就是不断通过改变width和height的值,如果发现框框非常合适时,那么这时的width和height就比较合适。

标注过程:

,时长00:47

第二部分:

有了第一部分的标注,准备工作也就完全做好了,接下来,就是如何判断,车位有车,和无车了。下面看一个视频,

,时长00:17

不难发现,在车位上有车时,该车位的像素点多,而无车时,像素点相当少。于是基本思想就是:

将视频进行转化,(原视频不变)再计算每个车位的像素数量,通过像素数量(设定一个阈值)的多少来判断车辆的有无。

代码如下:


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(imgPro):
    spaceCounter = 0

    for pos in posList:
        x, y = pos

        imgCrop = imgPro[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)
        cvzone.putTextRect(img, str(count), (x, y + height - 3), scale=1,
                           thickness=2, offset=0, colorR=color)

    cvzone.putTextRect(img, f'Free: {spaceCounter}/{len(posList)}', (100, 50), scale=3,
                           thickness=5, offset=20, colorR=(0,255,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)
    cv2.imshow("Image", img)
    #cv2.imshow("ImageBlur", imgBlur)
    #cv2.imshow("ImageThres", imgMedian)
    cv2.waitKey(10)

结果:

,时长00:25

(后期加工过,配上了音乐和一些字)

车位空余量与总量清晰的显示在了视频上。当然,由于这个视频拍摄时存在抖动,而实际中,大多都是固定的,所以检测效果会更好。

这也启发我们,在考虑问题时,一定要从多方面来考虑。尽量运用较为简单的知识去做出较为准确的结果。有时,简单反而是更加有效的!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值