文章目录

  • 1.实现的思路
  • 2.整体代码实战
  • (1)ParkingSpacePicker.py
  • (2)main.py
  • (3)视频效果
  • 3.停车位视频下载
  • 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://blog.csdn.net/Keep_Trying_Go/article/details/125351256
    高斯去噪:
    https://mydreamambitious.blog.csdn.net/article/details/125203273
    局部二值化:
    https://mydreamambitious.blog.csdn.net/article/details/125249121
    中值滤波:
    https://mydreamambitious.blog.csdn.net/article/details/125204641
    Opencv中获取卷积核:
    https://mydreamambitious.blog.csdn.net/article/details/125265838
    腐蚀操作:
    https://mydreamambitious.blog.csdn.net/article/details/125265431

    #转换为灰度图
        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)视频效果

    停车位识别演示视频

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


    3.停车位视频下载

    https://699pic.com/movie/295567.html

    来源:Keep_Trying_Go

    物联沃分享整理
    物联沃-IOTWORD物联网 » Opencv实现停车位识别

    发表评论