
小編今天跟大家推薦的這篇文章是關(guān)于停車系統(tǒng)的。停車位問題一直是有車一族最為頭疼的,這篇文章基于python和OpenCV教大家簡單構(gòu)建一個智能停車系統(tǒng)。
文章來源: 小白學(xué)視覺
作者: 努比
當(dāng)今時代最令人頭疼的事情就是找不到停車位,尤其是找20分鐘還沒有找到停車位。
根據(jù)復(fù)雜性和效率的不同,任何問題都具有一個或多個解決方案。目前智能停車系統(tǒng)的解決方案,主要包括基于深度學(xué)習(xí)實現(xiàn),以及基于重量傳感器、光傳感器實現(xiàn)等。
本期我們將一起通過使用攝像頭和少量代碼來實現(xiàn)最簡單的智能停車系統(tǒng)。該解決方案所使用的概念非常簡單。它由具有以下兩個腳本組成:
1. 選擇停車位的坐標(biāo)并將其保存到文件中。
2. 從文件中獲取坐標(biāo),并確定該點是否可用。
將該解決方案分成兩個腳本的原因是,避免在每次確定是否有可用停車位的時候,就進(jìn)行停車位的選擇。
為了使這一過程盡可能簡單,從現(xiàn)在開始,我們將這兩個腳本稱為selector和detector。
相關(guān)依賴
在本文中,我們使用python 3.7.6,但其他版本(例如3.6或3.8)當(dāng)然也可以使用。首先我們要檢查python的版本,我們通過在控制臺中編寫python –version,即可返回已安裝的python版本。
C:\Users\Razvan>python --version Python 3.7.6
在開始構(gòu)建該系統(tǒng)依賴項之前,我們可以設(shè)置一個虛擬環(huán)境。通過以下鏈接我們可以了解更多有關(guān)虛擬環(huán)境的信息https://docs.python.org/3.7/tutorial/venv.html。
也可以使用conda創(chuàng)建和管理環(huán)境。有關(guān)更多信息見https://docs.anaconda.com/anaconda/。
在python中設(shè)置完所有內(nèi)容后, 最重要的依賴關(guān)系將是OpenCV庫。通過pip將其添加到虛擬環(huán)境中,可以運行pip install opencv-python。
要檢查所有設(shè)置是否正確,我們可以使用以下cv2.__version__命令打印環(huán)境中可用的當(dāng)前OpenCV版本。
(OpenCV) C:\Users\Razvan>python Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> print(cv2.__version__) 4.2.0 >>>
在第一行中,我們可以看到在該項目中使用了名為OpenCV的虛擬環(huán)境。
步驟
首先,我們需要安裝一個停車場攝像頭。由于我們并沒有一個窗戶可以看到的任何停車場,因此我們選擇使用舊汽車玩具和印刷紙。另外,我在停車場上方設(shè)置了一個網(wǎng)絡(luò)攝像頭,以獲取良好的圖像,因此我們正在處理的圖像如下所示:
selector選擇器
接下來,我們來介紹編碼部分。首先,我們需要構(gòu)建選擇器。我們從導(dǎo)入所需模塊開始
import cv2 import csv
之后,我們開始獲取圖像,在該圖像上選擇停車位。為此,我們可以選擇攝網(wǎng)絡(luò)攝像頭提供的第一幀,保存并使用該圖像選擇停車位。下面的代碼是這樣的:
1. 打開image變量中的視頻流;suc確定流是否成功打開。
2. 將第一幀寫入frame0.jpg。
3. 流被釋放,所有窗口都關(guān)閉。
4. 新保存的圖片將以img變量形式讀取。
VIDEO_SOURCE = 1 cap = cv2.VideoCapture(VIDEO_SOURCE) suc, image = cap.read() cv2.imwrite("frame0.jpg", image) cap.release() cv2.destroyAllWindows() img = cv2.imread("frame0.jpg")
現(xiàn)在,我們已經(jīng)保存了第一幀并在img變量中將其打開,可以使用selectROIs函數(shù)標(biāo)記停車位。ROI被定義為感興趣的區(qū)域,代表圖像的一部分,我們將在其上應(yīng)用不同的函數(shù)以及濾波器來獲取結(jié)果。
返回到selectROIs函數(shù),這將返回一個列表(類型:numpy.ndarray),其中包含我們組裝圖像所需的數(shù)字及其邊界ROI。
r = cv2.selectROIs('Selector', img, showCrosshair = False, fromCenter = False)
我們的列表將保存在變量r中。賦予cv2.selectROIs函數(shù)的參數(shù)如下:
1. “選擇器”是允許我們選擇投資回報率的窗口的名稱。
2. img是包含我們要選擇圖像的變量。
3. showCrosshair = Flase刪除選區(qū)內(nèi)部的中心線??梢詫⑵湓O(shè)置為True,因為對結(jié)果沒有影響。
4. fromCenter = False是一個非常重要的參數(shù),因為如果將其設(shè)置為True,則正確的選擇會困難得多。
選擇所有停車位之后,是時候?qū)⑺鼈儗懭?strong>.csv文件了。為此,我們需要將r變量轉(zhuǎn)換為python列表,可以使用rlist = r.tolist()命令實現(xiàn)。
擁有適當(dāng)?shù)臄?shù)據(jù)后,我們將其保存到.csv文件中,以備將來使用。
with open('data/rois.csv', 'w', newline='') as outf: csvw = csv.writer(outf) csvw.writerows(rlist)
detector探測器
現(xiàn)在我們已經(jīng)選擇了停車位,是時候進(jìn)行一些圖像處理了。解決這個問題的方法如下:
1. 從.csv文件獲取坐標(biāo)。
2. 從中構(gòu)建新圖像。
3. 應(yīng)用OpenCV中可用的Canny函數(shù)。
4. 計算新圖像內(nèi)的白色像素。
5. 建立一個點內(nèi)的像素范圍將被占用。
6. 在實時供稿上繪制一個紅色或綠色矩形。
對于所有這些操作,我們需要定義一個要應(yīng)用于每個位置的函數(shù)。該函數(shù)如下所示:
def drawRectangle(img, a, b, c, d): sub_img = img[b:b + d, a:a + c] edges = cv2.Canny(sub_img, lowThreshold, highThreshold) pix = cv2.countNonZero(edges) if pix in range(min, max): cv2.rectangle(img, (a, b), (a + c, b + d), (0, 255, 0), 3) spots.loc += 1 else: cv2.rectangle(img, (a, b), (a + c, b + d), (0, 0, 255), 3)
現(xiàn)在我們已經(jīng)實現(xiàn)了所需的功能,如果我們直接將其應(yīng)用于.csv文件中的每組坐標(biāo)效果可能并不好。因此我們做如下處理
首先,我們的有一些參數(shù)如果可以在腳本運行時(也可以在通過GUI)實時調(diào)整它們,那就更好了。為此,我們需要構(gòu)建一些軌跡欄。OpenCV為我們提供這項功能。
我們需要一個回調(diào)函數(shù),該函數(shù)不執(zhí)行任何操作,但作為使用OpenCV創(chuàng)建軌跡欄的參數(shù)是必需的。實際上,回調(diào)參數(shù)具有明確定義的用途,但我們在此不使用它。要了解有關(guān)此內(nèi)容的更多信息,查閱OpenCV文檔。
def callback(foo): pass
現(xiàn)在我們需要創(chuàng)建軌跡欄。我們將使用cv2.namedWindow和cv2.createTrackbar功能。
cv2.namedWindow('parameters') cv2.createTrackbar('Threshold1', 'parameters', 186, 700, callback) cv2.createTrackbar('Threshold2', 'parameters', 122, 700, callback) cv2.createTrackbar('Min pixels', 'parameters', 100, 1500, callback) cv2.createTrackbar('Max pixels', 'parameters', 323, 1500, callback)
現(xiàn)在,我們已經(jīng)創(chuàng)建了用于操作參數(shù)的GUI,只剩下一件事了。這就是圖像中可用斑點的數(shù)量。在drawRectangle中定義為spot.loc。這是一個靜態(tài)變量,必須在程序開始時進(jìn)行定義。該變量為靜態(tài)變量的原因是,我們希望調(diào)用的每個drawRectangle函數(shù)都將其寫入相同的全局變量,而不是每個函數(shù)都使用一個單獨的變量。這樣可以防止返回的可用空間數(shù)量大于實際的可用空間數(shù)量。
為了實現(xiàn)這一點,我們只需要使用它的loc靜態(tài)變量創(chuàng)建spots類。
class spots: loc = 0
現(xiàn)在我們已經(jīng)準(zhǔn)備就緒,只需要從.csv文件中獲取數(shù)據(jù),將其所有數(shù)據(jù)轉(zhuǎn)換為整數(shù),然后在無限循環(huán)中應(yīng)用構(gòu)建的函數(shù)即可。
with open('data/rois.csv', 'r', newline='') as inf: csvr = csv.reader(inf) rois = list(csvr) rois = [[int(float(j)) for j in i] for i in rois] VIDEO_SOURCE = 1 cap = cv2.VideoCapture(VIDEO_SOURCE) while True: spots.loc = 0 ret, frame = cap.read() ret2, frame2 = cap.read() min = cv2.getTrackbarPos('Min pixels', 'parameters') max = cv2.getTrackbarPos('Max pixels', 'parameters') lowThreshold = cv2.getTrackbarPos('Threshold1', 'parameters') highThreshold = cv2.getTrackbarPos('Threshold2', 'parameters') for i in range(len(rois)): drawRectangle(frame, rois[i][0], rois[i][1], rois[i][2], rois[i][3]) font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(frame, 'Available spots: ' + str(spots.loc), (10, 30), font, 1, (0, 255, 0), 3) cv2.imshow('Detector', frame) canny = cv2.Canny(frame2, lowThreshold, highThreshold) cv2.imshow('canny', canny) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
拓展
在我們的循環(huán)中實際上只是調(diào)用的構(gòu)建函數(shù)要復(fù)雜一點。
首先,我們將空間的數(shù)量初始化為0,以防止每幀添加數(shù)字。
其次,我們進(jìn)入兩個處理流以顯示真實圖像和已處理的圖像。這有助于更好地了解此腳本的工作方式以及圖像的處理方式。
然后,我們需要在每次迭代中獲取我們創(chuàng)建的參數(shù) GUI中的參數(shù)值。這是通過cv2.getTrackbarPos功能完成的。
接下來最重要的部分,將drawRectangle函數(shù)應(yīng)用到Selector腳本獲取的所有坐標(biāo)上。
最后,在結(jié)果圖像上寫下可用斑點的數(shù)量,顯示Canny函數(shù)的結(jié)果,顯然,這是一種眾所周知的停止循環(huán)的方法。
我們現(xiàn)在便完成了一個智能停車項目!
總結(jié)
如今,智能停車已成為熱門話題之一,并且有許多實現(xiàn)方式可以導(dǎo)致良好的功能系統(tǒng)。我們這處理方法并不是完美的,有許多方法可以更好地優(yōu)化結(jié)果,并且可以在更多情況下使用。但是,即使這不能解決停車場危機(jī),也可能是導(dǎo)致危機(jī) 的主要原因。
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動態(tài)隨機(jī)一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時,“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗與 t 檢驗:差異、適用場景與實踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計學(xué)領(lǐng)域,假設(shè)檢驗是驗證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對象的 text 與 content:區(qū)別、場景與實踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請求開發(fā)時(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請求工具對比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點數(shù)據(jù)的科學(xué)計數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點數(shù)據(jù)時的科學(xué)計數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運營問題、提升執(zhí)行效率的核心手段,其價值 ...
2025-09-12用 SQL 驗證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計” 與 “用戶體驗 ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當(dāng)下,精準(zhǔn)營銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價值 在數(shù)據(jù)驅(qū)動決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實踐到業(yè)務(wù)價值挖掘 在數(shù)據(jù)分析場景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價值導(dǎo)向 統(tǒng)計模型作為數(shù)據(jù)分析的核心工具,并非簡單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10