RT-DETR 目标检测视频推理

先前介绍了RT-DETR推理单张图像的案例,今天则介绍以下如何利用RT-DETR来进行视频推理。

事实上,进行视频推理的过程与单张图片的过程及其类似,就是将原本的视频切分为多帧图像后再进行推理即可。这里面涉及到Image等相关操作,今天便借此机会梳理一遍。

我们的实现思路很简单,其步骤如下:

  1. 将视频拆分为多帧
  2. 将多帧图像依次输入RT-DETR模型中进行检测
  3. 将多帧图像的检测结果合并为视频

利用cv2生成视频读取器,读取视频

python 复制代码
    classes = ['car','truck',"bus"]
    videoname = '1.mp4'
    capture = cv2.VideoCapture(videoname)
    images = []

通过循环将视频拆分为多帧图像

python 复制代码
if capture.isOpened():
        while True:
            ret,img=capture.read() # img 就是一帧图片,此时的img是ndarray格式,即numpy的数组类型
            if not ret:break # 当获取完最后一帧就结束
            img=cv2.resize(img,(640,640))#由于模型输入的图像尺寸固定为640*640,因此需要转换
            img = Image.fromarray(img)#将数组类型转换为Image类型
            img = img.convert('RGB')#通道位置置换
            im_data = ToTensor()(img)[None]#模型输入类型为tensor,故将其转换为tensor类型
            size = torch.tensor([[640, 640]])#设定输入图像的尺寸

加载onnx模型文件,并判断GPU是否可用,同时进行前向推理,并计算FPS

python 复制代码
			if torch.cuda.is_available():
                print("GPU")
                sess = ort.InferenceSession("model.onnx", None, providers=["CUDAExecutionProvider"])
            else:
                print("CPU")
                sess= ort.InferenceSession("model.onnx", None)
            import time
            start = time.time()
            output = sess.run(
                output_names=['labels', 'boxes', 'scores'],
                #output_names=None,
                input_feed={'images': im_data.data.numpy(), "orig_target_sizes": size.data.numpy()},
            )
            end = time.time()
            fps = 1.0 / (end - start)
            print(fps)

根据结果获取目标类别,标注框与得分,并将其绘制在每张图像上

python 复制代码
			labels, boxes, scores = output
            draw = ImageDraw.Draw(img)#生成ImageDraw对象,用于画图
            thrh = 0.6
            for i in range(im_data.shape[0]):
                scr = scores[i]
                lab = labels[i][scr > thrh]
                box = boxes[i][scr > thrh]
                for l, b in zip(lab, box):
                    draw.rectangle(list(b), outline='red',)#ImageDraw对象画框并写入类别,因为原本输出的类别是0,1,2,需要使用定义的数组来获取其真实类别名称
                    draw.text((b[0], b[1] - 10), text=str(classes[l.item()]),font_size=16, fill='blue', )
            images.append(img)#将画好的每张图加入到images数组中

视频合成,指定合成视频的名称,帧率等信息,将images中的图像合成为视频

python 复制代码
 	video_name = 'output.mp4'
    fps = 30  # 每秒钟30帧
    fourcc = cv2.VideoWriter_fourcc(*"mp4v")
    video = cv2.VideoWriter(video_name, fourcc, fps, (640,640))
# 合成视频
    for i in range(len(images)):
            img = images[i]
            img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
            video.write(img)

可以看到,其在视频推理过程中,对CPU的利用率明显增高

当然我们也可以直接将其生成gif

python 复制代码
imageio.mimsave('output.gif',images,fps=25)

完整代码如下:

python 复制代码
import torch
import onnxruntime as ort
from PIL import Image, ImageDraw
from torchvision.transforms import ToTensor
import cv2
import imageio
import numpy as np
import os
if __name__ == "__main__":
    import torch
    print(torch.__version__)

    print(torch.version.cuda)
    print(torch.backends.cudnn.version())

##################
    classes = ['car','truck',"bus"]
    ##################
    videoname = '1.mp4'
    capture = cv2.VideoCapture(videoname)
    images = []
    if capture.isOpened():
        while True:
            ret,img=capture.read() # img 就是一帧图片
            if not ret:break # 当获取完最后一帧就结束
            img=cv2.resize(img,(640,640))
            img = Image.fromarray(img)
            img = img.convert('RGB')
            im_data = ToTensor()(img)[None]
            size = torch.tensor([[640, 640]])
            if torch.cuda.is_available():
                print("GPU")
                sess = ort.InferenceSession("model.onnx", None, providers=["CUDAExecutionProvider"])
            else:
                print("CPU")
                sess= ort.InferenceSession("model.onnx", None)
            import time
            start = time.time()
            output = sess.run(
                output_names=['labels', 'boxes', 'scores'],
                #output_names=None,
                input_feed={'images': im_data.data.numpy(), "orig_target_sizes": size.data.numpy()},
            )
            end = time.time()
            fps = 1.0 / (end - start)
            print(fps)

            labels, boxes, scores = output
            draw = ImageDraw.Draw(img)
            thrh = 0.6

            for i in range(im_data.shape[0]):

                scr = scores[i]
                lab = labels[i][scr > thrh]
                box = boxes[i][scr > thrh]
                for l, b in zip(lab, box):
                    draw.rectangle(list(b), outline='red',)
                    draw.text((b[0], b[1] - 10), text=str(classes[l.item()]),font_size=16, fill='blue', )

            images.append(img)
            # 可以用 cv2.imshow() 查看这一帧,也可以逐帧保存

        else:
                print('视频打开失败!')
                #############
                img.save('2.jpg')
    imageio.mimsave('output.gif',images,fps=25)
    video_name = 'output.mp4'
    fps = 30  # 每秒钟30帧
    fourcc = cv2.VideoWriter_fourcc(*"mp4v")
    video = cv2.VideoWriter(video_name, fourcc, fps, (640,640))
# 合成视频
    for i in range(len(images)):
            img = images[i]
            img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
            video.write(img)
相关推荐
只是甲2 小时前
Text2SQL 系列博客 02:技术原理深度剖析 - 从自然语言到 SQL 的完整链路
人工智能·text2sql·nl2sql·ai agent·自助数据分析·data agent·agentic 数据洞察
EasyDSS2 小时前
视频直播点播平台EasyDSS一体化融媒体平台:直播、点播、会议与集群对讲的一站式管理
音视频·媒体
懷淰メ2 小时前
【AI赋能】基于PyQt+YOLO+DeepSeek水上漂浮物检测系统(详细介绍)
人工智能·yolo·目标检测·计算机视觉·pyqt·漂浮物·水上漂浮物
EQUINOX12 小时前
【论文精读】| CLIP精读
大数据·人工智能
PC2005-cloud3 小时前
博文已索引但不展示:一次 Bing SEO 问题排查记录
服务器·人工智能
weixin_408099673 小时前
2026 图片去文字 API 实战:AI一键去除图片文字(附 Python / Java / PHP / JS 完整代码)
人工智能·api接口·图片去水印·石榴智能·ai图像修复·图片去文字
greenbbLV3 小时前
2026节日慰问品政策解读:合规标准升级与福利行业新趋势
人工智能·节日
奈斯先生Vector3 小时前
告别工具碎片化:基于 Nano Banana 全模态 AI 聚合架构搭建“文本-图像-视频”自动化协同生产线
运维·数据库·人工智能·架构·自动化·aigc·音视频
领麦微红外3 小时前
国产MEMS红外测温传感器:传感器+算法+产品级出厂标定一站式交付模式深度解读
人工智能·硬件工程·产品经理
mingo_敏4 小时前
DeepAgents : 检索(Retrieval)
人工智能·深度学习·langchain