译者 | 李睿
审校 | 重楼
本文首先概述典型的计算机视觉应用程序的要求。然后,介绍Pipeless这一为嵌入式计算机视觉提供无服务器开发体验的开源框架。最后,提供一个详细的步骤指南,介绍如何创建和执行一个简单的对象检测应用程序,该应用程序只需采用几个Python函数和一个模型进行创建。
创建计算机视觉应用程序
如果有人希望用一句话描述“计算机视觉”的话,那么给出回答是“通过摄像头界面识别视觉事件并对其做出反应的艺术。”但这可能不是他想听到的答案。因此,以下将深入了解计算机视觉应用程序是如何构建的,以及每个子系统需要实现的功能。
•真正快速的帧处理:如要实时处理60 fps的视频流,只有16毫秒的时间来处理每帧。这在一定程度上是通过多线程和多处理进程实现的。在许多情况下,希望在前一个帧完成之前开始处理一个帧。
•在每一帧上运行推理并执行对象检测、分割、姿态估计等的人工智能模型:幸运的是,有越来越多优秀的开源模型,所以不必从头开始创建自己的模型,通常只需微调模型的参数以匹配用例。
•推理运行时间:推理运行时间负责加载模型,并在不同的可用设备(GPU或CPU)上高效运行。
•GPU:为了使模型足够快地运行推理,我们需要采用GPU。这是因为GPU可以处理比CPU多几个数量级的并行操作,而最低级别的模型只是大量的数学运算。你需要处理帧所在的内存。它们可以位于 GPU 内存或 CPU 内存 (RAM) 中,在这些内存之间复制帧是一项非常繁重的操作,因为帧大小会使处理速度变慢。
•多媒体管道:这些部件允许从数据源获取视频流,将它们分割成帧,将它们作为模型的输入,有时修改和重建视频流以转发。
•视频流管理:开发人员可能希望应用程序能够抵抗视频流的中断、重新连接、动态添加和删除视频流、同时处理多个视频流,等等。
所有这些系统都需要创建或合并到项目中,因此,需要维护代码。然而,面临的问题是最终维护的大量代码并非特定于应用程序,而是围绕实际案例特定代码的子系统。
Pipeless框架
为了避免从头开始构建上述所有内容,可以代用Pipeless框架。这是一个用于计算机视觉的开源框架,允许提供一些特定于案例的功能,并且能够处理其他事物。
Pipeless框架将应用程序的逻辑划分为“阶段”,其中的一个阶段就像单个模型的微型应用程序。一个阶段可以包括预处理、使用预处理的输入运行推理,以及对模型输出进行后处理以采取行动。然后,可以链接尽可能多的阶段,以组成完整的应用程序,甚至使用多个模型。
为了提供每个阶段的逻辑,只需添加一个特定于应用程序的代码函数,然后在需要时由Pipeless负责调用它。这就是可以将Pipeless视为一个框架的原因,它为嵌入式计算机视觉提供类似服务器的开发体验,并且提供了一些功能,不必担心需要其他的子系统。
Pipeless的另一个重要特性是,可以通过CLI或REST API动态地添加、删除和更新视频流,从而实现视频流处理的自动化。甚至可以指定重新启动策略,指示何时应该重新启动视频流的处理,是否应该在出现错误后重新启动,等等。
最后,部署Pipeless框架,只需要在任何设备上安装它并与代码函数一起运行,无论是在云计算虚拟机或容器化模式中,还是直接在Nvidia Jetson、Raspberry等边缘设备中。
创建对象检测应用程序
以下深入地了解如何使用Pipeless框架创建一个简单的对象检测应用程序。
第一就是安装。安装脚本,使其安装非常简单:
Curl https://raw.githubusercontent.com/pipeless-ai/pipeless/main/install.sh | bash
现在,必须创建一个项目。Pipeless项目是一个包含阶段的目录。每个阶段都在子目录下,在每个子目录中,创建包含hooks(特定的代码函数)的文件。为每个阶段文件夹提供的名称是稍后要为视频流运行该阶段时,必须向Pipeless框指示的阶段名称。
pipeless init my-project --template empty
cd my-project
在这里,空模板告诉CLI只创建目录,如果不提供任何模板,CLI将提示几个问题以交互式地创建阶段。
如上所述,现在需要为项目添加一个阶段。采用下面的命令从GitHub下载一个阶段示例:
wget -O - https://github.com/pipeless-ai/pipeless/archive/main.tar.gz |
tar -xz --strip=2 "pipeless-main/examples/onnx-yolo"
这将创建一个阶段目录onnx-yolo,其中包含应用程序函数。
然后,检查每个阶段文件的内容,也就是应用程序hooks。
这里有一个pre-process.py文件,它定义了一个接受一个框架和一个场景的函数(hooks)。该函数执行一些操作来准备接收RGB帧的输入数据,以便与模型期望的格式匹配。该数据被添加到frame_data[' interence_input ']中,这是Pipeless将传递给模型的数据。
def hook(frame_data, context):
frame = frame_data["original"].view()
yolo_input_shape = (640, 640, 3) # h,w,c
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = resize_rgb_frame(frame, yolo_input_shape)
frame = cv2.normalize(frame, None, 0.0, 1.0, cv2.NORM_MINMAX)
frame = np.transpose(frame, axes=(2,0,1)) # Convert to c,h,w
inference_inputs = frame.astype("float32")
frame_data['inference_input'] = inference_inputs
... (some other auxiliar functions that we call from the hook function)
还有process.json文件,它指示要使用的Pipeless推理运行时间(在本例中为ONNX运行时间),在哪里可以找到它应该加载的模型,以及它的一些可选参数,例如要使用的execution_provider,即CPU、CUDA、TensortRT等。
{
"runtime": "onnx",
"model_uri": "https://pipeless-public.s3.eu-west-3.amazonaws.com/yolov8n.onnx",
"inference_params": {
"execution_provider": "tensorrt"
}
}
最后,post-process.py文件定义了一个类似于pre-process.py中的函数。这一次,它接受Pipeless存储在frame_data["inference_output"]中的推理输出,并执行将该输出解析为边界框的操作。稍后,它在框架上绘制边界框,最后将修改后的框架分配给frame_data['modified']。这样,Pipeless将转发提供的视频流,但带有修改后的帧,其中包括边界框。
def hook(frame_data, _):
frame = frame_data['original']
model_output = frame_data['inference_output']
yolo_input_shape = (640, 640, 3) # h,w,c
boxes, scores, class_ids =
parse_yolo_output(model_output, frame.shape, yolo_input_shape)
class_labels = [yolo_classes[id] for id in class_ids]
for i in range(len(boxes)):
draw_bbox(frame, boxes[i], class_labels[i], scores[i])
frame_data['modified'] = frame
... (some other auxiliar functions that we call from the hook function)
最后一步是启动Pipeless并提供一个视频流。要启动Pipeless,只需在my-project目录下运行以下命令:
pipeless start --stages-dir .
一旦运行,将提供来自网络摄像头(v4l2)的视频流,并直接在屏幕上显示输出。需要注意的是,必须提供视频流按顺序执行的阶段列表。在这个例子中,它只是onnx-yolo阶段:
pipeless add stream --input-uri "v4l2" --output-uri "screen" --frame-path "onnx-yolo"
结论
创建计算机视觉应用程序是一项复杂的任务,因为有许多因素和必须围绕它实现的子系统。使用像Pipeless这样的框架,启动和运行只需要几分钟,可以专注于为特定用例编写代码。此外,Pipeless的“阶段”是高度可重用的,易于维护,因此维护将会很容易,可以非常快速地迭代。
如果希望参与Pipeless的开发,可以通过它的GitHub存储库来实现。
原文标题:Create a Complete Computer Vision App in Minutes With Just Two Python Functions,作者:Miguel Angel Cabrera
链接:https://dzone.com/articles/creating-a-complete-computer-vision-application-in