本案例由DS小龙哥提供
1 概述
1.1 背景介绍
车牌识别技术作为智能停车场的重要管理组成部分,得到了广泛的应用。通过自动识别车辆的车牌信息,可以实现车辆的快速进出场记录与管理,有效减少人工干预,提高效率。结合云计算技术,车牌识别系统可以进一步实现数据的集中处理和管理,为停车场的计费、安防等功能提供强大的技术支撑。
通过实际操作,让大家深入了解如何利用华为云已有的服务进行调用,可以使开发者更加熟练的调用华为云相关的服务。
1.2 适用对象
- 个人开发者
- 高校学生
1.3 案例时间
本案例总时长预计60分钟。
1.4 资源总览
本案例预计花费总计0元。体验完成后请及时释放资源,避免产生多余的费用。
| 资源名称 | 规格 | 单价(元) | 时长(分钟) |
|---|---|---|---|
| 华为开发者空间 - 云主机 | 鲲鹏通用计算增强型 kc2 | 4vCPUs | 8G | Ubuntu | 0 | 60 |
2 配置环境
2.1 开通服务
本案例中,使用云主机作为代码编写平台,并使用华为云提供的车牌识别服务为依托进行案例的开发。
下面的操作需要涉及到API接口,需要进行token进行鉴权,会使用到项目凭证这个参数。
1. 获取项目凭证点击左上角用户名,选择下拉菜单里的我的凭证。

点击打开后会出现项目ID,这里需要记住,后面会用到。

获取token需要创建IAM子用户,将以下链接复制到浏览器。
https://console.huaweicloud.com/iam/?region=cn-north-4#/iam/users
右上角点击创建。

输入相关信息后点击下一步。

随后点击创建用户。

在浏览器复制以下链接开通车牌识别服务。
https://console.huaweicloud.com/ocr/?region=cn-north-4#/ocr/overview

2.2 下载相关工具包
打开云主机桌面的CodeArts IDE。

点击新建工程,工程名称-> number_demo,点击创建。
CodeArts IDE for Python配置自动激活虚拟环境。(如果之前配置过可忽略此步骤)
选择“文件”-“设置”,在搜索框中输入“active”,在下面筛选出的结果中找到“在使用插件创建的终端中激活Python环境。”并勾选。

在CodeArts IDE for Python中打开终端,关闭命令行窗口。

再次重新打开终端,如果命令行开头显示“(venv)”,则表示成功激活虚拟环境。

在终端输入以下命令,输入完毕后按下回车键进行下载。
pip install requests

下载完毕后继续输入以下命令:
pip3 install Pillow

下载完毕后再次将以下命令复制到终端进行下载:
pip install PyQt5

继续将以下命令复制到终端中:
pip install pyqt5-tools

3 代码编写
3.1 获取Token
Token的有效期为24小时。建议进行缓存,避免频繁调用。使用Token前请确保Token离过期有足够的时间,防止调用API的过程中Token过期导致调用API失败。重新获取Token,不影响已有Token有效性。
相关帮助文档请参考以下链接:
https://support.huaweicloud.com/api-iam/iam_30_0001.html
在CodeArts IDE中点击左上角新建文件,输入文件名-> token_demo.py。

将以下代码复制到文件中。
import requests
import json
# 主账号用户名
MAIN_USER = "[填你自己的]"
# IAM 子账户用户名
IAM_USER = "[填你自己的]"
# IAM 子账户密码
IAM_PASSWORD = "[填你自己的]"
# 项目 ID
PROJECT_ID = "[填你自己的]"
# 服务器区域代号
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"
# 构造请求头
headers = {
"Content-Type": "application/json;charset=UTF-8"
}
# 构造请求体
payload = {
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"domain": {
"name": MAIN_USER
},
"name": IAM_USER,
"password": IAM_PASSWORD
}
}
},
"scope": {
"project": {
"name": SERVER_ID
}
}
}
}
# 发出 POST 请求
try:
response = requests.post(request_url, headers=headers, data=json.dumps(payload))
# 打印状态码
print(f"状态码: {response.status_code}")
if response.status_code == 201:
# 读取 X-Subject-Token 响应头
token = response.headers.get("X-Subject-Token")
# 打印返回的数据和 Token
print(f"反馈的数据: {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"请求发生错误: {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 时发生错误: {e}")
def main():
# 获取 TOKEN
get_token()
if __name__ == "__main__":
main()
需要替换部分为:
# 主账号用户名
MAIN_USER = "[填你自己的]"
# IAM 子账户用户名
IAM_USER = "[填你自己的]"
# IAM 子账户密码
IAM_PASSWORD = "[填你自己的]"
# 项目 ID
PROJECT_ID = "[填你自己的]"
将代码中相应的部分进行替换,替换完毕后鼠标右击运行。

运行成功后会提示,token已保存到token.txt。

3.2 车牌识别代码编写
再次点击左上角新建文件,命名->car_number.py。

将以下代码复制到文件中:
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
# 将图片转换为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
# 车牌识别函数
def recognize_license_plate(image_path):
SERVER_ID = "cn-north-4"
项目ID替换为自己的项目ID
PROJECT_ID = "替换为自己的项目ID"
token = read_token()
if not token:
return "错误:无法读取Token文件。"
# 设置请求地址
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编码。"
# 构造请求头
headers = {
"Content-Type": "application/json;charset=UTF-8",
"X-Auth-Token": token
}
# 构造请求参数
payload = {
"image": img_data
}
# 发送POST请求
try:
response = requests.post(request_url, json=payload, headers=headers)
# 处理响应
if response.status_code == 200:
return response.json()
else:
return f"请求失败,状态码:{response.status_code}\n响应内容:{response.text}"
except requests.RequestException as e:
return f"请求过程中发生错误:{e}"
# 主窗口类
class LicensePlateRecognizer(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("车牌识别")
self.setGeometry(100, 100, 800, 600)
# 创建主布局
main_layout = QHBoxLayout()
# 左侧布局:显示图片
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)
# 右侧布局:显示结果
self.result_text = QTextEdit()
self.result_text.setReadOnly(True)
self.result_text.setStyleSheet("border: 1px solid black;")
main_layout.addWidget(self.result_text)
# 设置中央窗口
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("") # 清空上次的结果
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)
# 提取并显示结果
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("错误:未能正确解析返回的结果。")
else:
self.result_text.setText(str(result))
# 主程序入口
if __name__ == "__main__":
app = QApplication(sys.argv)
window = LicensePlateRecognizer()
window.show()
sys.exit(app.exec_())
涉及到的地址需要自行前往网上下载,下载完毕后,将图片放到与代码文件同一级目录下即可。
需要修改的地址,这里将None修改为需要识别的图片路径。
self.image_path = None \# 存储加载的图片路径

图片下载完毕后点击运行,点击加载车牌,将所需要识别的上传上去,再点击识别车牌。

至此,实验结束。
6万+

被折叠的 条评论
为什么被折叠?



