yolov7怎么整合推理代码为一个class b站魔傀面具

import cv2
import torch
import numpy as np
from yolov7.utils import non_max_suppression, letterbox, scale_coords, plot_one_box

class yolov7:
    def __init__(self, model_path, iou_thres, conf_thres, device, names):
        device = self.select_device(device)
        print(device)
        if model_path.endswith('pt'):
            model = torch.jit.load(model_path).to(device)
        elif model_path.endswith('onnx'):
            try:
                import onnxruntime as ort
            except:
                raise 'please install onnxruntime.'
            providers = ['CUDAExecutionProvider'] if device.type != 'cpu' else ['CPUExecutionProvider']
            model = ort.InferenceSession(model_path, providers=providers)
        colors = [[random.randint(0, 255) for _ in range(3)] for _ in names]
        self.__dict__.update(locals())
    
    

导入了一些自定义的工具函数和类:non_max_suppression、letterbox、scale_coords和plot_one_box。这些函数和类用于执行非最大抑制、图像letterbox处理(调整图像尺寸后填充)、坐标缩放和绘制边界框等功能。

接着,定义了一个名为yolov7的类。该类的构造函数__init__接收以下参数:model_path(模型文件路径,可以是.pt.onnx格式)、iou_thres(IoU阈值,用于非最大抑制的阈值)、conf_thres(置信度阈值,用于目标检测结果的筛选)、device(设备类型,可以是CPU或GPU)、names(类别名称列表)。

__init__函数首先通过调用select_device方法选择设备,并打印出所选择的设备。然后,根据model_path的后缀来加载模型,如果是.pt格式,则使用torch.jit.load加载模型并将其发送到选择的设备;如果是.onnx格式,则使用onnxruntime.InferenceSession加载模型,同时根据设备类型选择使用的执行提供者。

def __call__(self, data):
        if type(data) is str:
            image = cv2.imdecode(np.fromfile(data, np.uint8), cv2.IMREAD_COLOR)
        else:
            image = data
        im = self.processing(image)
        
        if self.model_path.endswith('pt'):
            result = self.model(im)[0]
        elif self.model_path.endswith('onnx'):
            result = self.model.run([i.name for i in self.model.get_outputs()], {'images':im})[0]
        image = self.post_processing(result, im, image)
        
        return image
        
    def processing(self, img):
        image = letterbox(img, auto=False)[0]
        image = image.transpose((2, 0, 1))[::-1]
        image = np.expand_dims(image, 0)
        image = np.ascontiguousarray(image)
        image = np.array(image, dtype=np.float32)
        image /= 255
        
        if self.model_path.endswith('pt'):
            im = torch.from_numpy(image).float().to(self.device)
        elif self.model_path.endswith('onnx'):
            im = image
        return im
    
    def post_processing(self, result, im=None, img=None):
        if self.model_path.endswith('pt'):
            result = non_max_suppression(result, conf_thres=self.conf_thres, iou_thres=self.iou_thres)[0]
            result[:, :4] = scale_coords(im.shape[2:], result[:, :4], img.shape)
            
            for *xyxy, conf, cls in result:
                label = f'{self.names[int(cls)]} {conf:.2f}'
                plot_one_box(xyxy, img, label=label, color=self.colors[int(cls)], line_thickness=1)
        elif self.model_path.endswith('onnx'):
            result = result[:, 1:]
            ratio, dwdh = letterbox(img, auto=False)[1:]
            result[:, :4] -= np.array(dwdh * 2)
            result[:, :4] /= ratio
            
            for *xyxy, cls, conf in result:
                label = f'{self.names[int(cls)]} {conf:.2f}'
                plot_one_box(xyxy, img, label=label, color=self.colors[int(cls)], line_thickness=1)
        
        return img
    
    def select_device(self, device):
        if device == -1:
            return torch.device('cpu')
        else:
            os.environ['CUDA_VISIBLE_DEVICES'] = str(device)
            assert torch.cuda.is_available(), f'CUDA unavailable, invalid device {device} requested'  # check availability
            device = torch.device('cuda:0')
        return device

if __name__ == '__main__':
    # read cfg
    with open('model.yaml') as f:
        cfg = yaml.load(f, Loader=yaml.SafeLoader)
    # print cfg
    print(cfg)
    # init
    yolo = yolov7(**cfg)
    image_path = '1.jpg'
    # inference
    image = yolo(image_path)
    cv2.imshow('pic', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

定义了一个colors列表,其中包含了每个类别的随机颜色,用于绘制边界框时的类别标签颜色。

__call__方法用于实际执行推断。它接收一个输入数据data,可以是图像文件的路径字符串或者是OpenCV图像数组。

__call__方法内部,首先根据输入数据的类型,使用OpenCV的imdecode函数将图像文件解码为OpenCV图像数组。然后,调用processing方法对图像进行预处理,将其转换为模型所需的格式。

接着,根据model_path的后缀,使用加载的模型对输入数据进行推断。如果是.pt格式,则使用模型进行一次前向传播,得到输出结果;如果是.onnx格式,则使用模型的run方法得到输出结果。

最后,调用post_processing方法对输出结果进行后处理,将检测到的边界框绘制在原始图像上,并返回绘制完成的图像。

processing方法用于对图像进行预处理。它首先使用letterbox函数将图像调整为模型所需的输入尺寸,并做一些其他必要的转换操作,如转置、扩展维度和归一化。最后,根据模型的类型和格式,将图像转换为相应的torch.Tensornumpy.ndarray格式,并返回预处理后的图像。

post_processing方法用于对模型的输出结果进行后处理。首先,根据模型的类型和格式,对输出结果进行一些调整和计算,如非最大抑制的阈值过滤、坐标缩放等。然后,利用plot_one_box函数将结果绘制在原始图像上,并返回绘制完成的图像。

select_device方法用于选择设备。如果device为-1,则选择CPU设备;否则,通过设置环境变量CUDA_VISIBLE_DEVICES来选择GPU设备,并确保选择的设备可用。

最后,代码利用上述定义的yolov7类实例化了一个对象,并进行了简单的测试。它首先加载了一个配置文件(model.yaml),然后根据配置初始化了yolov7对象。接着,指定一个图像路径,通过调用yolo对象对图像进行推断,并将结果显示在窗口中。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值