首頁 > 軟體

python Opencv實現停車位識別思路詳解

2022-07-04 14:02:11

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)視訊效果

停車位識別演示

注:視訊自己做的比較差,建議讀者最好自己嘗試實現這個思路。

到此這篇關於Opencv實現停車位識別的文章就介紹到這了,更多相關Opencv實現停車位識別內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com