【开源项目】特斯拉+树莓派实现车牌识别检测系统
检测到车牌。
识别每个车牌边界框内的文本。
一个机器学习模型,以未标记的图像作为输入,从而检测到车牌;
某种硬件。简单地说,我需要连接了一个或多个摄像头的计算机系统来调用我的模型。
YOLOv3- 这是当下最快的模型之一,而且跟其他 SOTA 模型的 mAP 相当。我们用这个模型来检测物体;
CRAFT 文本检测器 - 我们用它来检测图像中的文本;
CRNN - 简单来说,它就是一个循环卷积神经网络模型。为了将检测到的字符按照正确的顺序排成单词,它必须是时序数据;
首先,YOLOv3 模型从摄像机处接收到一帧帧图像,然后在每个帧中找到车牌的边界框。这里不建议使用非常精确的预测边界框——边界框比实际检测对象大一些会更好。如果太挤,可能会影响到后续进程的性能;
文本检测器接收 YOLOv3 裁剪过的车牌。这时,如果边界框太小,那么很有可能车牌文本的一部分也被裁掉了,这样预测结果会惨不忍睹。但是当边界框变大时,我们可以让 CRAFT 模型检测字母的位置,这样每个字母的位置就可以非常精确;
最后,我们可以将每个单词的边界框从 CRAFT 传递到 CRNN 模型,以预测出实际单词。
在后视镜的方向上,树莓派+ GPS 模块+ 4G 模块将保留下来。关于我使用的 GPS 和 4G 天线,你可以去看一下我关于 EC25-E 模块的文章;
在另一侧,我用一个利用球关节活动的手臂来支撑 Pi Camera
Keras 实现:https://github.com/experiencor/keras-yolo3
提交合并请求:https://github.com/experiencor/keras-yolo3/pull/244
在本地进行所有的推理;
在云中进行推理。
定义 cortex.yaml 文件,它是我们的 api 的配置文件。每个 API 将处理一种类型的任务。我给 yolov3 的 API 分配的任务是检测给定帧上的车牌边界框,而 crnn API 则是在 CRAFT 文本检测器和 crnn 的帮助下预测车牌号码;
定义每个 API 的预测器。基本上你要做的就是在 cortex 中定义一个特定类的 predict 方法来接收一个有效负载(所有的 servy part 都已经被平台解决了),这个有效负载来可以来预测结果,然后返回预测结果。就这么简单!
import picklelabels = ["setosa", "versicolor", "virginica"]
class PythonPredictor:
def __init__(self, config):
s3 = boto3.client("s3")
s3.download_file(config["bucket"], config["key"], "model.pkl")
self.model = pickle.load(open("model.pkl", "rb")) def predict(self, payload):
measurements = [
payload["sepal_length"],
payload["sepal_width"],
payload["petal_length"],
payload["petal_width"],
] label_id = self.model.predict([measurements])[0]
return labels[label_id]
-X POST -H "Content-Type: application/json" \
-d '{"sepal_length": 5.2, "sepal_width": 3.6, "petal_length": 1.4, "petal_width": 0.3}'
从 Pi Camera 以可接受的分辨率(800x450 或 480x270)收集帧速率为 30 FPS 的帧,并将每个帧推入一个公共队列;
在一个单独的进程中,我将从队列中取出帧,并将它们分发给不同线程上的多个工作站;
每个工作线程(或者我称之为推断线程)都会向我的 cortex API 发出 API 请求。首先,一个请求到我的 yolov3API,然后,如果有任何车牌检测到,另一个请求会带着一批裁剪的车牌发到我的 crnn API。预测的车牌号码将以文本格式返回;
将每个检测到的牌照(带不带识别后的文本都可以)推到另一个队列,最终将其广播到浏览器页面。同时,还将车牌号码预测推到另一个队列,以便稍后将其以 csv 格式保存到磁盘;
广播队列将接收一组无序的帧。consumer 的任务是先把它们放在一个非常小的缓冲区(几个帧的大小),每次广播一个新的帧给 client 重新排序。这个 consumer 在另一个进程上单独运行,它还必须尝试保持队列的大小固定为指定值,以便以一致的帧速率显示帧。显然,如果队列大小下降,那么帧率的下降是成比例的,反之亦然;
与此同时,在主进程中还会运行另一个线程,从另一个队列获取预测和 GPS 数据。当客户端收到终止信号时,预测、GPS 数据和时间也会被转存到 csv 文件中。
将宽度减少到 416 像素,也就是 YOLOv3 模型所需要的大小,而且尺度显然是完好无损的;
将图像转换为灰度图;
移除图片顶部 45% 的部分。这里的想法是车牌不会出现在车架的顶部,因为汽车不会飞,对吧?据我所知,删除 45% 的图像并不影响预测器的性能;
再次转换图像为 JPEG,但此时的质量变低了很多。
推荐阅读
▼