訂閱
糾錯(cuò)
加入自媒體

車位數(shù)量檢測(cè)

該項(xiàng)目基于圖像處理來(lái)檢測(cè)停車場(chǎng)中的空間。

該項(xiàng)目將使用 openCV 和 CVzone 庫(kù)來(lái)執(zhí)行圖像處理任務(wù)。

如何運(yùn)行

用鼠標(biāo)單擊功能在停車場(chǎng)的靜止圖像上繪制框在這些單獨(dú)的框上裁剪和執(zhí)行 opencv 轉(zhuǎn)換結(jié)合這兩個(gè)步驟并將它們應(yīng)用于視頻以檢查可用的可用空間

過(guò)程

1. 安裝和導(dǎo)入依賴項(xiàng)

openCV 將允許我們導(dǎo)入圖像和視頻,然后我們可以對(duì)它們應(yīng)用轉(zhuǎn)換,CVzone作為基于 openCV  的庫(kù),它還允許我們使用與 openCV  相比所需語(yǔ)法更少的轉(zhuǎn)換,“Pickel”用于存儲(chǔ)在圖片上繪制的方框的位置,“numpy”用于應(yīng)用簡(jiǎn)單的轉(zhuǎn)換。

import cv2

import pickle

import cvzone

import numpy as np

我們將處理使用 parkingspacepicker.py 繪制框并存儲(chǔ)位置,并通過(guò) pickel 在我們的 main.py 中使用這些位置

2.  繪制方框

在此圖像中,我們可以看到空間分布不均,并且間隔各不相同。

我們稍后將使用的視頻的相機(jī)處于靜態(tài)狀態(tài),因此我們可以通過(guò)在框上手動(dòng)繪制框來(lái)接近它。

為此,我們需要知道單個(gè)框的高度和寬度,然后我們將不得不嘗試不同的值以獲得完美形狀的框

import cv2

import pickle

import cvzone

import numpy as np

img = cv2.imread('carParkImg.png')

while True:

    cv2.rectangle(img,(50,1920),(157,240),(255,0,255),2)

    cv2.imshow("image", img)

    cv2.waitKey(1)

在此之后,我們得到 width 和 height = 107, 48 你也可以嘗試不同的值。

我們啟動(dòng)一個(gè)列表來(lái)存儲(chǔ)這些值并編寫一個(gè)函數(shù)來(lái)檢測(cè)鼠標(biāo)點(diǎn)擊操作,你可以在下一個(gè)片段中看到

img = cv2.imread('carParkImg.png')

width, height = 107, 48

def mouse_click(events, x, y, flags, params):

    if events == cv2.EVENT_LBUTTONDOWN:

        posList.append((x, y))

#and to see what we are drwaing on the screen 

while True:

    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", mouse_click)

    cv2.waitKey(1)

在 mouse_click 函數(shù)中,我們將events, x, y, flags, params作為參數(shù)傳遞,如果events == cv2.EVENT_LBUTTONDOWN,則將值 (x, y) 附加到 posList 并查看我們?cè)谄聊簧侠L制的內(nèi)容,我們將在我們的 posList 值上編寫一個(gè) for 循環(huán)。

我在這里遇到了兩個(gè)問(wèn)題:

在錯(cuò)誤的位置繪制框加載圖像后只生成一幀,因此對(duì)該圖像的任何修改都不會(huì)顯示

對(duì)于第 1 個(gè)問(wèn)題的解決方案,我修改了mouse_click函數(shù),將右鍵單擊按鈕作為一個(gè)事件,然后我們將檢查我們的單擊點(diǎn)是否位于其中一個(gè)位置之間,我們將刪除它。

def mouse_click(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)

我們將檢查當(dāng)前的x是否在x1<x<x1+width和y1<y<y1+height之間,如果在其中,則刪除它。我們需要知道要進(jìn)行多少次迭代才能刪除它,為此我們可以使用enumerate獲取i并彈出i。

對(duì)于問(wèn)題2-因?yàn)槲覀兊膱D像只被導(dǎo)入一次,所以無(wú)論在其上繪制什么都將保持不變,我們?cè)诰W(wǎng)絡(luò)攝像頭或相機(jī)中不會(huì)遇到此問(wèn)題,并且我們正在處理的是靜態(tài)圖像,因此我們必須在循環(huán)中導(dǎo)入它以獲得刪除框。

在繪制所有框后,現(xiàn)在我們必須將它們存儲(chǔ)為pickle對(duì)象并以一種方式存儲(chǔ)它們,以便我們不必每次都進(jìn)行制作,并且我們可以使用先前的對(duì)象或修改現(xiàn)有的對(duì)象。

img = cv2.imread('carParkImg.png')

width, height = 107, 48

try:

    with open('CarParkPos', 'rb') as f:

        posList = pickle.load(f)

except:

    posList = []

def mouse_click(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:

        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", mouse_click)

    cv2.waitKey(1)

這將創(chuàng)建一個(gè)對(duì)象 CarParkPos 并檢查該對(duì)象是否已經(jīng)存在

圖像處理(main.py)

加載視頻饋送并循環(huán)進(jìn)行循環(huán),我們將對(duì)幀進(jìn)行計(jì)數(shù),當(dāng)幀到達(dá)時(shí),我們將重置它,以便獲得連續(xù)的視頻

import cv2

import pickle

import cvzone

import numpy as np

# video feed

cap = cv2.VideoCapture('carPark.mp4')

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()

 cv2.imshow("Image", img)

 cv2.waitKey(10)

將框位置加載到我們將使用 pickle 對(duì)象的視頻上,并定義我們之前找到的寬度和高度with open('CarParkPos', 'rb') as f:

    posList = pickle.load(f)

width, height = 107, 48

我們需要裁剪這些位置以供以后轉(zhuǎn)換,為此我們將編寫一個(gè)函數(shù)def checkParkingSpace(imgPro):

  for pos in posList:

    x, y = pos

      imgCrop = imgPro[y:y + height, x:x + width]

      cv2.imshow(str(x * y), imgCrop)

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)

 for pos in posList:

     cv2.rectangle(img, pos, (pos[0] + width, pos[1] + height), (255, 0, 255), 2)

 success, img = cap.read()

 cv2.imshow("Image", img)

 cv2.waitKey(10)

裁剪后繪制出方框,這將為裁剪區(qū)域提供完美的視角,現(xiàn)在我們需要找出其中哪個(gè)區(qū)域有汽車。

我們可以通過(guò)查看像素計(jì)數(shù)來(lái)做到這一點(diǎn),在圖像處理中,我們可以使用邊緣和角點(diǎn)檢測(cè)算法來(lái)將圖像轉(zhuǎn)換為二進(jìn)制形式,并計(jì)算出圖像中的邊緣和角點(diǎn)數(shù)量。在二值化后的圖像中,黑色像素表示背景,白色像素表示前景。通過(guò)分析這些二值化后的圖像中的邊緣和角點(diǎn)數(shù)目,我們可以了解到關(guān)于該圖像的一些信息,如圖像是否具有結(jié)構(gòu)性、復(fù)雜度等信息,來(lái)確定圖像的特點(diǎn)。在此基礎(chǔ)上,我們可以繼續(xù)下一步的分析或處理。

為了確定該區(qū)域是否包含汽車,我們必須首先使用 OpenCV 和 CVzone 進(jìn)行一些閾值處理,我們將圖像轉(zhuǎn)換為灰度并應(yīng)用高斯模糊,然后我們將其轉(zhuǎn)換為二值圖像,我們將使用自適應(yīng)閾值和去除椒鹽噪聲,我們使用“medianBlur”和主動(dòng)內(nèi)核來(lái)去除噪聲,有時(shí)這些像素非常小,為了更好地區(qū)分,我們將使用膨脹操作。

應(yīng)用所有濾鏡后的圖像

    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)

所有的值都作為參數(shù)傳遞,通過(guò)嘗試不同的值來(lái)獲得,現(xiàn)在我們將這個(gè)處理過(guò)的圖像傳遞給我們的裁剪函數(shù)

做出預(yù)測(cè)def checkParkingSpace(imgPro):

    spaceCounter = 0

    for pos in posList:

        x, y = pos

        imgCrop = imgPro[y:y + height, x:x + width]

        # cv2.imshow(str(x * y), imgCrop)

        count = cv2.countNonZero(imgCrop)

        if count < 900:

            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, 200, 0))

我們將處理后的圖像傳遞給此函數(shù)并計(jì)算像素,如果像素密度小于 900,則表明沒(méi)有汽車,如果大于900,則包含汽車并顯示文本,我們將使用 CVzone 庫(kù),并使用 python f string Free:{spaceCounter}/{len(posList)} 來(lái)顯示計(jì)數(shù)器。

github:https://github.com/Tejaswi-kashyap-006/computervision_projects

       原文標(biāo)題 : 車位數(shù)量檢測(cè)

聲明: 本文由入駐維科號(hào)的作者撰寫,觀點(diǎn)僅代表作者本人,不代表OFweek立場(chǎng)。如有侵權(quán)或其他問(wèn)題,請(qǐng)聯(lián)系舉報(bào)。

發(fā)表評(píng)論

0條評(píng)論,0人參與

請(qǐng)輸入評(píng)論內(nèi)容...

請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字

您提交的評(píng)論過(guò)于頻繁,請(qǐng)輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無(wú)評(píng)論

暫無(wú)評(píng)論

    人工智能 獵頭職位 更多
    掃碼關(guān)注公眾號(hào)
    OFweek人工智能網(wǎng)
    獲取更多精彩內(nèi)容
    文章糾錯(cuò)
    x
    *文字標(biāo)題:
    *糾錯(cuò)內(nèi)容:
    聯(lián)系郵箱:
    *驗(yàn) 證 碼:

    粵公網(wǎng)安備 44030502002758號(hào)