构建实时车辆分析应用

PaliGemma模型以其较小的规模(三十亿参数)、商业使用条款的支持以及微调能力,成为计算机视觉任务中令人兴奋的模型。作为一名计算机视觉应用开发者,对这款模型在实际应用中可能带来的改进充满好奇。让通过构建一个应用来一探究竟。

要构建什么

为了展示PaliGemma模型的优势,将构建一个车辆分析应用。该应用将检测车辆,分析车辆信息(包括品牌、颜色和款式),读取车牌号,并将这些信息保存到电子表格中以供历史查看。以下是运行中的应用程序的一个小预览。

为了构建这个应用,需要将问题分解为几个较小的步骤,并讨论系统的一些要求。

  • 检测车辆和车牌。
  • 裁剪并保存独特的检测结果。
  • 对车辆颜色、品牌和类型进行分类。
  • 读取车牌。
  • 将结果保存到CSV文件中。

希望应用能够实时运行,并能够在硬件上自行托管。

检测车辆和车牌

在这个应用中,将使用一个微调过的Yolov8模型来检测车牌和车辆。使用Roboflow自动标记数据,并在30分钟内训练了一个模型。然后,使用推理来在模型上运行视频流。还将使用Supervision包作为计算机视觉瑞士军刀,以显示边界框并使用cv2显示帧。

from inference import InferencePipeline import supervision as sv import cv2 bb = sv.BoundingBoxAnnotator() def call_back(results, frame): detections = sv.Detections.from_inference(results)  annotated_frame = bb.annotate(         scene=frame.image.copy(),          detections=detections,     )          cv2.imshow("Vehicle Analytics", annotated_frame)     cv2.waitKey(1) pipeline = InferencePipeline.init(     model_id="vehicle-recognition-z5mpj/4",     api_key="ROBOFLOW_API_KEY",     video_reference=["output.MOV"],     on_prediction=call_back, ) pipeline.start() pipeline.join()

裁剪并保存独特检测

这部分应用是最复杂的,因此让一步一步地进行。首先,需要一个机制来跟踪独特车辆,并在这些特定检测上触发分类和OCR任务。为了给PaliGemma一个更高的机会进行准确的OCR和分类任务,希望在车辆清晰可见时抓住车辆的一帧。为此,将使用ByteTrack在车辆进入视频最右侧的多边形区域时保存独特车辆。

import numpy as np import threading ... tracker = sv.ByteTrack() detection_polygon = np.array([[717, 6], [717, 1270], [681, 1271], [683, 9], [714, 9]]) detection_zone = sv.PolygonZone(polygon=detection_polygon, triggering_anchors=(sv.Position.BOTTOM_RIGHT,)) unique_cars = set() def background_task(results, frame): print(results, frame) def call_back(results, frame): ... tracked_detections = tracker.update_with_detections(detections) detected_cars = tracked_detections[tracked_detections.class_id == 2] cars_in_zone = detected_cars[detection_zone.trigger(detected_cars)] global unique_cars for car in cars_in_zone.tracker_id:  if not car in unique_cars:  unique_cars.add(car) background_thread = threading.Thread(target=backgroud_task, args=(results, frame)) ...

使用PaliGemma

现在到了有趣的部分!将使用推理来加载PaliGemma权重,并利用该模型进行分类和OCR任务!首先,让确保已经安装了正确的依赖项,按照Roboflow PaliGemma训练笔记本中的设置步骤进行。由于这个模型是一个VLM,可以通过传递一个图像和一个提示来与之交互。注意,在初次运行时,下载权重需要几分钟。

from inference.models.paligemma.paligemma import PaliGemma ... pg = PaliGemma(api_key="ROBOFLOW_API_KEY") def call_pali(prompt, image): global pg response = pg.predict(image, prompt) return response[0] ...

PaliGemma用于分类和OCR任务

现在已经有一个使用PaliGemma的机制,让看看分类和OCR任务是什么样子的。只需将车辆和车牌裁剪传递给函数`call_pali`,并提出具体的问题。在这里,可以尝试调整提示,但发现下面的方法对这种用例效果很好。

def background_task(results, frame): ... # 之前的代码 color = call_pali("What color is the car?", vehicle_img) brand = call_pali("car make", vehicle_img) car_type = call_pali("car;van;suv;truck", vehicle_img) plate = call_pali("read", plate_img) print(color, brand, car_type)

保存结果

最后,将裁剪结果保存到一个名为vehicles的目录中。还将创建一个CSV文件来保存数据。

import csv report = "path_to_csv.csv" with open(report, mode="w", newline='') as f: fieldnames = ["Color", "Brand", "Car Type", "Plate"] writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() def background_task(results, frame): ... # 之前的代码 with open(report, mode="a", newline='') as f: fieldnames = ["Color", "Brand", "Car Type", "Plate"] data = [{"Color": color, "Brand":brand, "Car Type": car_type, "Plate": plate}] writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writerows(data) file_name = f"./vehicles/{color}-{brand}-{car_type}-{plate}.jpg" combined_img.save(file_name)

做到了!一个本地托管的实时车辆分析应用。在PaliGemma之前,可能会选择使用CLIP来完成分类任务,以及使用众多OCR模型之一来读取车牌。有了PaliGemma,可以减少使用的模型数量,同时也简化了逻辑。还认为,这个演示完全在硬件上以近乎实时的速度运行,使用Nvidia RTX 3090,这是相当不可思议的。预测,这些VLM将随着时间的推移不断变得更好,硬件也会变得更便宜,这将解锁今天略有难度的企业级和业余爱好者应用。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485