手把手的技術(shù)干貨教程,記錄從0到1的開發(fā)過程。
一、前言
1.1 內(nèi)容簡介
隨著城市化進程的不斷加快,私家車數(shù)量迅猛增長,停車場管理面臨著巨大的壓力。傳統(tǒng)的人工管理方式效率低下,容易出現(xiàn)疏漏,不僅浪費了人力資源,還導(dǎo)致了用戶體驗的下降。在這種背景下,智能化停車場管理系統(tǒng)應(yīng)運而生,為提升停車場的運營效率和用戶服務(wù)質(zhì)量提供了可能。
近年來,車牌識別技術(shù)作為智能停車場的重要組成部分,得到了廣泛應(yīng)用。通過自動識別車輛的車牌信息,可以實現(xiàn)車輛的快速進出場記錄與管理,有效減少人工干預(yù),提高效率。結(jié)合云計算技術(shù),車牌識別系統(tǒng)可以進一步實現(xiàn)數(shù)據(jù)的集中處理和管理,為停車場的計費、安防等功能提供強大的技術(shù)支撐。
華為云作為國內(nèi)領(lǐng)先的云計算服務(wù)提供商,其提供的車牌識別服務(wù)具備高效、精準(zhǔn)的特點,能夠滿足停車場系統(tǒng)對實時性和可靠性的要求。通過華為開發(fā)者空間的云主機,開發(fā)者可以快速部署應(yīng)用,利用云端強大的計算能力和穩(wěn)定的環(huán)境,降低開發(fā)難度,提高開發(fā)效率。
本項目利用華為云的車牌識別服務(wù),設(shè)計并實現(xiàn)一個停車場自動計費系統(tǒng)。通過對車輛進入和離開時間的記錄和識別,系統(tǒng)能夠自動計算停車費用,減少人工干預(yù),提升用戶體驗。項目采用Python語言進行開發(fā),結(jié)合PyQt5進行用戶界面設(shè)計,為系統(tǒng)提供簡潔友好的操作界面,同時依托Ubuntu操作系統(tǒng)的穩(wěn)定性和開放性,確保系統(tǒng)運行的高效性和安全性。
采用華為云開發(fā)者空間的云主機里,調(diào)用華為云服務(wù)器,快速開發(fā)一款車牌識別系統(tǒng),完成停車場自動計費系統(tǒng)。
下面是運行效果
【1】加載圖片測試階段
【2】實時視頻測試階段
1.2 云主機
這里使用的華為云開發(fā)者空間云主機,是華為云為全球開發(fā)者打造的一個云端開發(fā)環(huán)境,簡化開發(fā)流程、提高開發(fā)效率,并促進技術(shù)創(chuàng)新。這個平臺提供了一個無需成本即可探索和使用華為云服務(wù)的機會,每位注冊的開發(fā)者在年度內(nèi)都能享有數(shù)百小時的云主機使用權(quán)。云主機預(yù)裝了CodeArts IDE(華為云的集成開發(fā)環(huán)境)、代碼倉庫以及JDK、Python等關(guān)鍵運行時插件,從而避免了本地環(huán)境配置的復(fù)雜性,讓開發(fā)者能夠快速上手并立即開始工作。
除了云主機外,華為云還提供了5GB的云存儲容量及定制化的場景模擬沙箱,這些資源幫助開發(fā)者在安全隔離的環(huán)境中進行實驗和測試。華為云開發(fā)者空間提供了豐富的技術(shù)培訓(xùn)課程和專業(yè)認證資料,助力開發(fā)者提升技能,并通過認證來證明自己的能力。該空間特別注重于應(yīng)用全周期管理,涵蓋從應(yīng)用構(gòu)建到運維的全過程,確保開發(fā)者可以高效地完成云端應(yīng)用搭建。
華為云開發(fā)者空間云主機圍繞CodeArts IDE打造了一個全面的開發(fā)工具生態(tài)系統(tǒng),整合了鯤鵬、昇騰、鴻蒙等核心生態(tài)的開發(fā)資源,提供廣泛的開源軟件庫和實用開發(fā)插件,支持從代碼托管到應(yīng)用運維的各個階段。這不僅提升了開發(fā)效率,也方便了開發(fā)者與華為先進技術(shù)和全球開發(fā)者社區(qū)互動,共同推動技術(shù)進步和應(yīng)用創(chuàng)新。
華為云開發(fā)者空間云主機的操作系統(tǒng)版本為Ubuntu 22.04.4 LTS,并且內(nèi)置了一些常用的應(yīng)用程序如Gitcode等,為開發(fā)者提供了一個穩(wěn)定而高效的開發(fā)環(huán)境。
1.3 開發(fā)環(huán)境
本項目的開發(fā)環(huán)境主要依托華為開發(fā)者空間提供的云主機環(huán)境進行設(shè)計與實現(xiàn),以下是開發(fā)環(huán)境的詳細說明:
(1)云主機環(huán)境:華為開發(fā)者空間
華為開發(fā)者空間是華為云為全球開發(fā)者提供的一個云端開發(fā)環(huán)境,旨在幫助開發(fā)者快速構(gòu)建、測試和部署應(yīng)用。云主機具有高性能的計算能力、靈活的擴展性以及安全穩(wěn)定的運行環(huán)境,適合各種開發(fā)需求。在本項目中,云主機作為停車場計費系統(tǒng)的運行平臺,提供了便捷的資源管理和穩(wěn)定的服務(wù)支持。
(2)操作系統(tǒng):Ubuntu 22.04.4
云主機的操作系統(tǒng)選擇了Ubuntu 22.04.4,這是目前廣泛使用的Linux發(fā)行版之一。Ubuntu以其高度的穩(wěn)定性、安全性以及豐富的軟件包支持而聞名,非常適合開發(fā)者在云端環(huán)境中進行開發(fā)和部署。Ubuntu 22.04.4版本支持最新的開發(fā)工具和庫,確保開發(fā)者能夠利用最新的技術(shù)和功能構(gòu)建項目。
(3)開發(fā)語言:Python
本項目采用Python作為開發(fā)語言。Python以其簡單易用、功能強大以及豐富的庫生態(tài)而受到廣泛歡迎,尤其適合人工智能、數(shù)據(jù)處理和自動化任務(wù)的開發(fā)。在本項目中,Python不僅用于調(diào)用華為云提供的車牌識別服務(wù)API,還負責(zé)處理停車場進出車輛數(shù)據(jù)的管理、費用計算邏輯的實現(xiàn)以及與用戶界面的交互。
(4)用戶界面:PyQt5
項目的用戶界面設(shè)計采用了PyQt5,這是一個基于Qt框架的Python庫,用于開發(fā)跨平臺的桌面圖形用戶界面。PyQt5提供了豐富的組件和功能,可以快速構(gòu)建交互性強、界面美觀的桌面應(yīng)用。在本項目中,PyQt5被用來設(shè)計停車場計費系統(tǒng)的用戶界面,包括車輛信息顯示、計費結(jié)果展示和操作按鈕等,為用戶提供了直觀易用的交互體驗。
(4)代碼編輯和調(diào)試:CodeArts IDE
CodeArts IDE是華為開發(fā)者空間云主機自帶的在線開發(fā)環(huán)境。
- 零配置開發(fā)環(huán)境:CodeArts IDE已預(yù)裝Python開發(fā)工具和相關(guān)依賴,開箱即用,開發(fā)者無需額外配置環(huán)境。
- 集成功能:提供代碼補全、調(diào)試器、版本控制等功能,大大提高開發(fā)效率。
1.4 功能說明
功能需求:
- 自動記錄車輛進出時間。
- 實現(xiàn)停車費用的自動計算和展示。
- 支持數(shù)據(jù)存儲與歷史記錄查詢。
系統(tǒng)架構(gòu):
- 前端界面:基于PyQt5,提供車輛信息展示和操作界面。
- 后端邏輯:采用Python處理車牌識別、計費計算和數(shù)據(jù)管理。
- 云端支持:調(diào)用華為云車牌識別API完成車牌信息提取,使用云存儲保存停車數(shù)據(jù)。
硬件集成。最終可以與閘機聯(lián)動,完成繳費自動抬桿。
二、華為云開發(fā)者空間
這一個章節(jié)介紹華為云主機的配置與使用。
2.1 進入開發(fā)者空間
鏈接地址:https://developer.huaweicloud.com/space/devportal/desktop
登錄華為云賬號,進去之后看到的頁面如下:
2.2 配置云主機
在左上角可以看到云主機的配置提醒,目前默認是基礎(chǔ)版。
點擊配置云主機
,會彈出對話框,讓你選擇云主機的配置,進行安裝系統(tǒng)。我這里選擇ubuntu 22.04
.
2.3 安裝系統(tǒng)
點擊安裝
后,會進行安裝系統(tǒng)。需要等等一段時間。
2.4 啟動云主機
安裝完畢之后,直接可以在瀏覽器里啟動云主機。
啟動需要一段時間初始環(huán)境。
進去之后會有引導(dǎo)界面,提示云主機的使用技巧。
進入桌面后的默認效果如下。
2.5 全屏切換
在桌面頁面上有個按鈕可以全屏切換,切換全屏后,可視化空間更大,開發(fā)更加方便。
2.6 共享桌面
云主機還有共享桌面功能,如果需要遠程演示項目,共享開發(fā)過程,對方還可以遠程操作,這個功能非常的方便。 直接雙擊666
。
2.5 測試Python開發(fā)環(huán)境
點擊左下角的所有應(yīng)用程序
,可以看到開發(fā)
菜單里,有安裝好的Python環(huán)境,可以直接使用。
啟動之后的效果如下。
進去之后,點擊左上角,新建一個文件。
然后保存文件,名字叫:test.py
然后編寫一段簡單的python
代碼,測試當(dāng)前的開發(fā)環(huán)境是否正常。
代碼如下:
import socket
def get_local_ip():
"""
獲取本地 IP 地址
"""
try:
# 創(chuàng)建一個 socket 對象,并連接到一個公共地址
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
local_ip = s.getsockname()[0]
s.close()
return local_ip
except Exception as e:
return f"無法獲取本地 IP 地址: {e}"
if __name__ == '__main__':
print("本地 IP 地址是:", get_local_ip())
點擊左上角運行。
結(jié)果如下:
2.6 安裝requests庫
接下來需要使用Python代碼的requests庫,發(fā)起HTTP請求。先提前安裝環(huán)境。
2.7 安裝Pillow庫
Pillow
是 PIL
(Python Imaging Library)的一個分支,提供了圖片處理功能。
pip3 install Pillow
到此,云主機的開發(fā)環(huán)境已經(jīng)測試OK。
三、車牌服務(wù)使用
本章節(jié)講解,完整調(diào)用車牌識別服務(wù)接口,應(yīng)該怎么做。
3.1 項目憑證
接下來調(diào)用車牌服務(wù)的API接口,都需要token進行鑒權(quán),需要使用項目憑證
這個參數(shù)。
【1】獲取項目憑證 點擊左上角用戶名,選擇下拉菜單里的我的憑證
。 記住這個項目ID
,后面會用到。
3.2 創(chuàng)建IAM賬戶
創(chuàng)建一個IAM賬戶,因為接下來使用人臉服務(wù)的API接口,這些接口都需要token進行鑒權(quán)。簡單來說,就是身份的認證。 調(diào)用接口獲取Token時,就需要填寫IAM賬號信息。所以,接下來演示一下過程。
地址: https://console.huaweicloud.com/iam/?region=cn-north-4#/iam/users
鼠標(biāo)放在左上角頭像上,在下拉菜單里選擇統(tǒng)一身份認證
。
點擊右上角創(chuàng)建用戶
。
填寫用戶名和密碼信息:
繼續(xù)點擊下一步:
然后點擊創(chuàng)建用戶
。
創(chuàng)建成功:
創(chuàng)建完成
用戶信息如下:
主用戶名 xiao_ping_ping
IAM用戶 ds_abc
密碼 DS12345678
3.3 獲取token鑒權(quán)
【1】Token介紹
為了方便接下來調(diào)用華為云的API接口,這里先完成token
參數(shù)的獲取。
幫助文檔:https://support.huaweicloud.com/api-iam/iam_30_0001.html
獲取的Token有效性說明:
Token的有效期為24小時。建議進行緩存,避免頻繁調(diào)用。使用Token前請確保Token離過期有足夠的時間,防止調(diào)用API的過程中Token過期導(dǎo)致調(diào)用API失敗。重新獲取Token,不影響已有Token有效性。
【2】接口使用說明
在文檔頁面,向下翻,可以看到對于此接口的詳細說明。還支持使用在線調(diào)試。
【3】編寫代碼獲取token
import requests
import json
# 主賬號用戶名
MAIN_USER = "[填你自己的]"
# IAM 子賬戶用戶名
IAM_USER = "[填你自己的]"
# IAM 子賬戶密碼
IAM_PASSWORD = "[填你自己的]"
# 項目 ID
PROJECT_ID = "[填你自己的]"
# 服務(wù)器區(qū)域代號
SERVER_ID = "cn-north-4"
# 保存 TOKEN 的文件路徑
TOKEN_FILE_PATH = "token.txt"
def get_token():
"""
功能: 獲取 TOKEN 并保存到本地文件
"""
# 請求地址
request_url = f"https://iam.{SERVER_ID}.myhuaweicloud.com/v3/auth/tokens"
# 構(gòu)造請求頭
headers = {
"Content-Type": "application/json;charset=UTF-8"
}
# 構(gòu)造請求體
payload = {
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"domain": {
"name": MAIN_USER
},
"name": IAM_USER,
"password": IAM_PASSWORD
}
}
},
"scope": {
"project": {
"name": SERVER_ID
}
}
}
}
# 發(fā)出 POST 請求
try:
response = requests.post(request_url, headers=headers, data=json.dumps(payload))
# 打印狀態(tài)碼
print(f"狀態(tài)碼: {response.status_code}")
if response.status_code == 201:
# 讀取 X-Subject-Token 響應(yīng)頭
token = response.headers.get("X-Subject-Token")
# 打印返回的數(shù)據(jù)和 Token
print(f"反饋的數(shù)據(jù): {response.json()}")
print(f"Token: {token}")
# 保存 TOKEN 到本地文件
if token:
save_token_to_file(token)
print(f"TOKEN 已保存到 {TOKEN_FILE_PATH}")
else:
print("未能獲取到 TOKEN")
else:
print(f"獲取 TOKEN 失敗: {response.text}")
except Exception as e:
print(f"請求發(fā)生錯誤: {e}")
def save_token_to_file(token):
"""
保存 TOKEN 到本地文件
"""
try:
with open(TOKEN_FILE_PATH, "w") as file:
file.write(token)
except Exception as e:
print(f"保存 TOKEN 時發(fā)生錯誤: {e}")
def main():
# 獲取 TOKEN
get_token()
if __name__ == "__main__":
main()
代碼說明:
(1)依賴庫:使用requests庫發(fā)起 HTTP 請求。 如果沒有安裝,在運行代碼前安裝依賴庫:
pip install requests
(2)主要邏輯:構(gòu)造請求頭和請求體。發(fā)起 POST
請求,獲取響應(yīng)。從響應(yīng)頭中提取 X-Subject-Token
并保存到本地文件。
(3)TOKEN 保存: TOKEN 被保存到 token.txt
文件中,方便后續(xù)直接讀取使用。
(4)運行方式: 將代碼保存為get_token.py,可以通過命令運行:
python get_token.py
也可以直接在終端運行,更加方便。 代碼編寫完畢,點擊右上角的綠色三角形
按鈕,運行。 得到了Token
然后保存到本地文件里。
3.4 開通車牌識別服務(wù)
鏈接地址: https://console.huaweicloud.com/ocr/?region=cn-north-4#/ocr/overview
點擊開通車牌識別服務(wù)。
用戶點擊全部選擇,點擊批量開通。
開通之后。
3.5 接口文檔
在控制臺頁面中,可以看到每個功能都有一個接口文檔
按鈕,點擊可以一鍵翻到對應(yīng)的幫助文檔頁面??焖倭私獯斯δ艿氖褂棉k法。
產(chǎn)品文檔的地址: https://support.huaweicloud.com/api-ocr/ocr_03_0040.html
向下翻,可以看到此接口如何調(diào)用,需要傳入什么參數(shù)。
在下面可以看到一個請求參數(shù)
的說明。第一個參數(shù)是:X-Auth-Token
,這個很重要,調(diào)用華為云的API接口都需要填這個參數(shù)。 關(guān)于如何獲取這個X-Auth-Token
參數(shù)。 下面章節(jié)里會詳細介紹。
【1】接口
POST /v2/{project_id}/ocr/license-plate
參數(shù) | 是否必選 | 說明 |
---|---|---|
endpoint | 華北-北京四”區(qū)域的endpoint為ocr.cn-north-4.myhuaweicloud.com | |
project_id | 是 | 項目ID,可以從獲取項目ID中獲取。 |
【2】請求參數(shù)
參數(shù) | 是否必選 | 參數(shù)類型 | 描述 |
---|---|---|---|
X-Auth-Token | 是 | String | 用戶Token。用于獲取操作API的權(quán)限。獲取Token接口響應(yīng)消息頭中X-Subject-Token的值即為Token。 |
Content-Type | 是 | String | 發(fā)送的實體的MIME類型,參數(shù)值為“application/json”。 |
參數(shù) | 是否必選 | 參數(shù)類型 | 說明 |
---|---|---|---|
image | 否 | String | 圖片的Base64編碼,要求Base64編碼后大小不超過10MB。圖片最短邊不小于15px,最長邊不超過4096px,支持JPEG、JPG、PNG、BMP、TIFF格式。圖片Base64編碼示例如/9j/4AAQSkZJRgABAg…,帶有多余前綴會產(chǎn)生The image format is not supported報錯。 |
【3】響應(yīng)參數(shù)
根據(jù)識別的結(jié)果,可能有不同的HTTP響應(yīng)狀態(tài)碼(status code)。例如,200表示API調(diào)用成功,400表示調(diào)用失敗,詳細的狀態(tài)碼和響應(yīng)參數(shù)說明如下。
狀態(tài)碼: 200
參數(shù) | 參數(shù)類型 | 描述 |
---|---|---|
result | Array of LicensePlateResult objects | 識別結(jié)果。調(diào)用失敗時不返回此字段。 |
參數(shù) | 參數(shù)類型 | 描述 |
---|---|---|
plate_number | String | 車牌內(nèi)容。 |
plate_color | String | 當(dāng)前版本支持的車牌底色類型:blue:藍色green:綠色(小型新能源車牌)black:黑色white:白色yellow:黃色yellow_green: 黃綠(大型新能源車牌) |
plate_location | Array of integers | 車牌的區(qū)域位置信息,列表形式,包含文字區(qū)域四個頂點的二維坐標(biāo)(x,y);采用圖像坐標(biāo)系,坐標(biāo)原點為圖片左上角,x軸沿水平方向,y軸沿豎直方向。 |
confidence | Float | 字段的置信度,取值范圍0~1。置信度越大,本次識別的字段的可靠性越高,在統(tǒng)計意義上,置信度越大,準(zhǔn)確率越高。置信度由算法給出,不直接等價于字段的準(zhǔn)確率。 |
狀態(tài)碼: 400
參數(shù) | 參數(shù)類型 | 說明 |
---|---|---|
error_code | String | 調(diào)用失敗時的錯誤碼。調(diào)用成功時不返回此字段。 |
error_msg | String | 調(diào)用失敗時返回的錯誤信息。調(diào)用成功時不返回此字段。 |
3.6 準(zhǔn)備車牌
直接打開瀏覽器,網(wǎng)絡(luò)上找?guī)讖堒嚺茍D片下載下來備用。
下載幾張下來。
為了方便訪問路徑,這里先給圖片改個名字。
3.6 編寫代碼實測
【1】完整源代碼
代碼讀取 token.txt
文件中的 Token、將圖片進行 Base64 編碼并通過 requests
庫發(fā)送 HTTP POST 請求到車牌識別接口。
import base64
import requests
import os
# 從文件中讀取Token
def read_token():
try:
with open("token.txt", "r") as file:
token = file.read().strip()
return token
except FileNotFoundError:
print("Error: token.txt file not found!")
return None
# 將圖片轉(zhuǎn)換為Base64編碼
def image_to_base64(image_path):
try:
with open(image_path, "rb") as image_file:
base64_image = base64.b64encode(image_file.read()).decode("utf-8")
return base64_image
except FileNotFoundError:
print(f"Error: Image file {image_path} not found!")
return None
# 車牌識別函數(shù)
def car_distinguish(image_path):
SERVER_ID = "cn-north-4"
PROJECT_ID = "ff981a50957a403cb68d906e0d424eed"
token = read_token()
if not token:
return
# 設(shè)置請求地址
request_url = f"https://ocr.{SERVER_ID}.myhuaweicloud.com/v2/{PROJECT_ID}/ocr/license-plate"
# 編碼圖片
img_data = image_to_base64(image_path)
if not img_data:
return
# 構(gòu)造請求頭
headers = {
"Content-Type": "application/json;charset=UTF-8",
"X-Auth-Token": token
}
# 構(gòu)造請求參數(shù)
payload = {
"image": img_data
}
# 發(fā)送POST請求
try:
response = requests.post(request_url, json=payload, headers=headers)
# 處理響應(yīng)
if response.status_code == 200:
print("Request successful!")
print("Response Data:", response.json())
else:
print(f"Request failed with status code {response.status_code}")
print("Response:", response.text)
except requests.RequestException as e:
print("Error during the request:", e)
# 測試代碼
if __name__ == "__main__":
# 替換為你的圖片路徑
image_path = "/home/developer/Downloads/1.jpeg"
car_distinguish(image_path)
【2】代碼功能解釋
(1)read_token
函數(shù)
從當(dāng)前目錄下的 token.txt
文件讀取 Token。如果文件不存在,打印錯誤信息。
(2)image_to_base64
函數(shù)
將指定路徑的圖片轉(zhuǎn)換為 Base64 編碼。需要確保圖片文件大小不超過 2MB。
(3)car_distinguish
函數(shù)
- 構(gòu)造 API 的 URL 和請求頭。
- 將圖片進行 Base64 編碼,并作為 POST 請求的參數(shù)發(fā)送到華為云 OCR 服務(wù)。
- 處理并打印返回結(jié)果。如果請求失敗,會打印相應(yīng)的錯誤消息。
(4)依賴
需要安裝 requests
庫,可以通過以下命令安裝:
pip install requests
(5)如何運行
將 token.txt
文件放在同一個目錄下,和 修改測試的圖片的路徑,然后運行該腳本。
3.7 運行結(jié)果
運行代碼可以看到已經(jīng)識別出結(jié)果。
運行結(jié)果如下:
{'result': [{'plate_number': '京A88888', 'plate_color': 'blue', 'confidence': 0.9999, 'plate_location': [[25, 164], [634, 168], [633, 334], [24, 330]]}]}
從返回值就可以看到,車牌已經(jīng)解析出來了。
四、圖形化界面開發(fā)
4.1 安裝PyQt5
為了方便能直觀的展示項目的整體功能,接下來安裝PyQt,完成車牌計費系統(tǒng)的系列功能的設(shè)計。
在Python中安裝PyQt庫非常簡單,可以使用pip
這個包管理工具來完成。PyQt有兩個主要版本:PyQt5(基于Qt 5)和PyQt6(基于Qt 6)。
我這里安裝Qt5,以Qt5為例進行開發(fā)。
要安裝PyQt5,打開命令行界面,然后運行以下命令:
pip install PyQt5
安裝過程中:
安裝完畢。
4.2 安裝QtDesigner
如果想使用PyQt5的設(shè)計工具(Qt Designer),用圖形方式設(shè)計界面,可以安裝pyqt5-tools
:
pip install pyqt5-tools
安裝過程如下:
安裝過程中
安裝完畢。
4.3 測試Qt環(huán)境
安裝完成后,先寫一份測試代碼,創(chuàng)建一個窗口,運行測試Qt環(huán)境是否正常。
新建一個文件:hello_pyqt.py
編寫代碼如下:
import sys
from PyQt5.QtWidgets import QApplication, QWidget # 如果使用PyQt6,這里改為 from PyQt6.QtWidgets import QApplication, QWidget
app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle('Hello PyQt')
window.show()
sys.exit(app.exec_())
在終端命令行中運行:
python3 hello_pyqt.py
如果一切正常,應(yīng)該能看到一個標(biāo)題為Hello PyQt
的空白窗口。這表明PyQt已經(jīng)成功安裝并且可以正常使用了。
運行效果如下:
4.4 編寫車牌識別代碼
下面是基于PyQt5 的設(shè)計的完整代碼。
包含一個圖形界面,具備加載圖片和識別車牌功能。界面布局中,左側(cè)顯示加載的圖片,右側(cè)顯示車牌識別的結(jié)果。
import sys
import base64
import requests
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QHBoxLayout, QWidget, QFileDialog, QTextEdit
)
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt
# 從文件中讀取Token
def read_token():
try:
with open("token.txt", "r") as file:
token = file.read().strip()
return token
except FileNotFoundError:
print("Error: token.txt file not found!")
return None
# 將圖片轉(zhuǎn)換為Base64編碼
def image_to_base64(image_path):
try:
with open(image_path, "rb") as image_file:
base64_image = base64.b64encode(image_file.read()).decode("utf-8")
return base64_image
except FileNotFoundError:
print(f"Error: Image file {image_path} not found!")
return None
# 車牌識別函數(shù)
def recognize_license_plate(image_path):
SERVER_ID = "cn-north-4"
PROJECT_ID = "ff981a50957a403cb68d906e0d424eed"
token = read_token()
if not token:
return "錯誤:無法讀取Token文件。"
# 設(shè)置請求地址
request_url = f"https://ocr.{SERVER_ID}.myhuaweicloud.com/v2/{PROJECT_ID}/ocr/license-plate"
# 編碼圖片
img_data = image_to_base64(image_path)
if not img_data:
return "錯誤:無法對圖片進行Base64編碼。"
# 構(gòu)造請求頭
headers = {
"Content-Type": "application/json;charset=UTF-8",
"X-Auth-Token": token
}
# 構(gòu)造請求參數(shù)
payload = {
"image": img_data
}
# 發(fā)送POST請求
try:
response = requests.post(request_url, json=payload, headers=headers)
# 處理響應(yīng)
if response.status_code == 200:
return response.json()
else:
return f"請求失敗,狀態(tài)碼:{response.status_code}n響應(yīng)內(nèi)容:{response.text}"
except requests.RequestException as e:
return f"請求過程中發(fā)生錯誤:{e}"
# 主窗口類
class LicensePlateRecognizer(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("車牌識別")
self.setGeometry(100, 100, 800, 600)
# 創(chuàng)建主布局
main_layout = QHBoxLayout()
# 左側(cè)布局:顯示圖片
self.image_label = QLabel("未加載圖片")
self.image_label.setAlignment(Qt.AlignCenter)
self.image_label.setStyleSheet("border: 1px solid black;")
self.image_label.setFixedSize(300, 400)
main_layout.addWidget(self.image_label)
# 中間布局:按鈕
button_layout = QVBoxLayout()
self.load_button = QPushButton("加載圖片")
self.load_button.clicked.connect(self.load_image)
button_layout.addWidget(self.load_button)
self.recognize_button = QPushButton("識別車牌")
self.recognize_button.clicked.connect(self.recognize_image)
button_layout.addWidget(self.recognize_button)
button_layout.addStretch()
main_layout.addLayout(button_layout)
# 右側(cè)布局:顯示結(jié)果
self.result_text = QTextEdit()
self.result_text.setReadOnly(True)
self.result_text.setStyleSheet("border: 1px solid black;")
main_layout.addWidget(self.result_text)
# 設(shè)置中央窗口
central_widget = QWidget()
central_widget.setLayout(main_layout)
self.setCentralWidget(central_widget)
self.image_path = None # 存儲加載的圖片路徑
# 加載圖片
def load_image(self):
options = QFileDialog.Options()
file_path, _ = QFileDialog.getOpenFileName(self, "打開圖片文件", "", "圖片文件 (*.png *.jpg *.jpeg)", options=options)
if file_path:
self.image_path = file_path
pixmap = QPixmap(file_path)
scaled_pixmap = pixmap.scaled(300, 400, Qt.KeepAspectRatio, Qt.SmoothTransformation)
self.image_label.setPixmap(scaled_pixmap)
self.result_text.setText("") # 清空上次的結(jié)果
else:
self.image_label.setText("未加載圖片")
# 識別車牌
def recognize_image(self):
if not self.image_path:
self.result_text.setText("錯誤:未加載圖片!")
return
self.result_text.setText("識別中...")
result = recognize_license_plate(self.image_path)
# 提取并顯示結(jié)果
if isinstance(result, dict) and "result" in result:
try:
plate_number = result["result"][0]["plate_number"]
plate_color = result["result"][0]["plate_color"]
self.result_text.setText(f"車牌號碼:{plate_number}n車牌顏色:{plate_color}")
except (IndexError, KeyError):
self.result_text.setText("錯誤:未能正確解析返回的結(jié)果。")
else:
self.result_text.setText(str(result))
# 主程序入口
if __name__ == "__main__":
app = QApplication(sys.argv)
window = LicensePlateRecognizer()
window.show()
sys.exit(app.exec_())
4.5 運行結(jié)果
彈出的界面。
識別的結(jié)果。
再換一張車牌。
五、總結(jié)
本項目基于華為云提供的車牌識別服務(wù),設(shè)計并實現(xiàn)了一套高效、智能的停車場計費系統(tǒng),成功完成了車輛進出自動識別、停車時間記錄、費用計算、數(shù)據(jù)存儲與查詢等核心功能。借助華為開發(fā)者空間的云主機和開發(fā)工具,結(jié)合Python的強大生態(tài)和PyQt5的優(yōu)秀界面開發(fā)能力,項目實現(xiàn)了從需求分析到系統(tǒng)部署的完整流程。
該系統(tǒng)通過云端車牌識別服務(wù),大幅提升了停車場管理的自動化和智能化水平,不僅降低了人工干預(yù)成本,還提高了用戶體驗。同時,系統(tǒng)支持靈活的計費規(guī)則和數(shù)據(jù)查詢功能,為停車場的管理和運營提供了便捷、高效的解決方案。
未來,該系統(tǒng)可進一步擴展,集成移動端應(yīng)用、在線支付功能以及與硬件設(shè)備的聯(lián)動,構(gòu)建更完善的智慧停車管理生態(tài)體系。項目的完成不僅展示了云服務(wù)與本地開發(fā)相結(jié)合的優(yōu)勢,也為智能化停車場建設(shè)提供了一個可行的實施案例。