mask rcnn onnx测试

Mask R-CNN是一个实例分割算法,可以用来做目标检测、目标实例分割、目标关键点检测。
下面测试它的onnx版本。

onnx的model和相关资料在此处下载。

测试图片:

图片的预处理部分,参考中用了Image来读图片,这里改成了opencv版本。

import numpy as np
import cv2
import onnxruntime
from utils import _COLORS  #自己定义一些mask颜色

#这里把Image版本改成了opencv版本
def preprocess(image):
    # Resize
    ratio = 800.0 / min(image.shape[0], image.shape[1])
    image = cv2.resize(image, (int(ratio * image.shape[1]), int(ratio * image.shape[0])))

    # Convert to BGR
    image = np.array(image)[:, :, [2, 1, 0]].astype('float32')

    # HWC -> CHW
    image = np.transpose(image, [2, 0, 1])

    # Normalize
    mean_vec = np.array([102.9801, 115.9465, 122.7717])
    for i in range(image.shape[0]):
        image[i, :, :] = image[i, :, :] - mean_vec[i]

    # Pad to be divisible of 32
    import math
    padded_h = int(math.ceil(image.shape[1] / 32) * 32)
    padded_w = int(math.ceil(image.shape[2] / 32) * 32)

    padded_image = np.zeros((3, padded_h, padded_w), dtype=np.float32)
    padded_image[:, :image.shape[1], :image.shape[2]] = image
    image = padded_image

    return image

后处理部分。
原版是画轮廓,这里改成了画mask区域。

def display_objdetect_image(image, boxes, labels, scores, masks, score_threshold=0.7):
    # Resize boxes
    ratio = 800.0 / min(image.shape[0], image.shape[1])
    boxes /= ratio

    image = np.array(image)

    for mask, box, label, score in zip(masks, boxes, labels, scores):
        # Showing boxes with score > 0.7
        if score <= score_threshold:
            continue

        # Finding contour based on mask
        #mask:(1,28,28)
        mask = mask[0, :, :, None]  #(28,28,1)
        int_box = [int(i) for i in box]
        mask = cv2.resize(mask, (int_box[2]-int_box[0]+1,int_box[3]-int_box[1]+1)) #box区域大小
        mask = mask > 0.5
        im_mask = np.zeros((image.shape[0], image.shape[1]), dtype=np.uint8) #image大小的全0mask
        x_0 = max(int_box[0], 0)
        x_1 = min(int_box[2] + 1, image.shape[1])
        y_0 = max(int_box[1], 0)
        y_1 = min(int_box[3] + 1, image.shape[0])
        mask_y_0 = max(y_0 - box[1], 0)
        mask_y_1 = max(0, mask_y_0 + y_1 - y_0)
        mask_x_0 = max(x_0 - box[0], 0)
        mask_x_1 = max(0, mask_x_0 + x_1 - x_0)
     
        im_mask[y_0:y_1, x_0:x_1] = mask[  #box区域填上mask,(480,640,1)
            mask_y_0 : mask_y_1, mask_x_0 : mask_x_1
        ]

        im_mask = im_mask[:, :, None] #(480,640,1)
        mask3 = image.copy()  #填上颜色的mask

        color = (_COLORS[label]*255).astype(np.uint8).tolist()
        mask3[im_mask[:,:,0]>0] = color
        image = cv2.addWeighted(image, 0.5, mask3, 0.5, 0)
		
        text = "{}:{:.1f}%".format(classes[label], score * 100)
        txt_color = (0, 0, 0) if np.mean(_COLORS[label]) > 0.5 else (255, 255, 255)
        font = cv2.FONT_HERSHEY_SIMPLEX
        txt_size = cv2.getTextSize(text, font, 0.5, 2)[0]
        #画box框
        cv2.rectangle(image, (x_0, y_0), (x_1, y_1), color, 1)
        #标签区域框
        cv2.rectangle(
            image,
            (x_0, y_0 - txt_size[1] - 1),
            (x_0 + txt_size[0] + txt_size[1], y_0 - 1),
            color,
            -1,
        )
        #填上标签
        cv2.putText(image, text, (x_0, y_0 - 1), font, 0.5, txt_color, thickness=1)
    cv2.imshow("image", image)
    cv2.waitKey(0)

ONNX推理部分(main函数)

if __name__ == '__main__':
    img = cv2.imread('./demo.jpg')
    #前处理
    img_data = preprocess(img)

    #onnx process
    session = onnxruntime.InferenceSession("./MaskRCNN-12.onnx",
                                           providers=['CUDAExecutionProvider',
                                                      'CPUExecutionProvider'])
    model_inputs = session.get_inputs()
    input_names = [model_inputs[i].name for i in range(len(model_inputs))]

    input_shape = model_inputs[0].shape
    input_height = input_shape[1]
    input_width = input_shape[2]
    model_outputs = session.get_outputs()
    output_names = [model_outputs[i].name for i in range(len(model_outputs))]
    # time1 = time.time()
    outputs = session.run(output_names, {input_names[0]: img_data})
    # time2 = time.time()
    boxes = outputs[0]
    labels = outputs[1]
    scores = outputs[2]
    masks = outputs[3]
  	#后处理
    display_objdetect_image(img, boxes, labels, scores, masks)

请添加图片描述

<think>好的,我需要帮助用户在CPU环境下运行Mask R-CNN模型。首先,我得确认用户的需求是什么。他们可能已经有了一些代码,但可能在运行过程中遇到了问题,或者他们想从头开始在CPU上配置环境。用户提到的复现模型,可能是指训练或者仅仅是推理?不过根据引用[4]中的代码示例,看起来他们可能是在尝试加载预训练模型并进行推理。 接下来,我需要回顾一下如何在PyTorch中确保模型在CPU上运行。通常,PyTorch默认会在GPU上运行如果可用,但用户没有GPU,所以需要显式指定设备为CPU。这可能涉及到修改代码中的设备设置,比如将模型加载到CPU上,并确保数据也在CPU上处理。 引用[4]中的代码示例里,用户导入了torch,但没有看到设置设备的代码。因此,用户可能需要添加类似`device = torch.device('cpu')`的语句,并且在加载模型时使用`model.to(device)`。此外,在加载预训练模型时,可能需要设置`map_location='cpu'`,以避免尝试加载GPU上的参数。 另外,用户可能需要安装正确版本的PyTorch。例如,如果用户安装的是GPU版本的PyTorch,即使没有CUDA支持,可能会出现问题。建议用户安装CPU版本的PyTorch,可以通过pip命令如`pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu`来安装。 还有,内存和性能问题需要考虑。在CPU上运行Mask R-CNN可能会比较慢,尤其是处理大图像或批量数据时。用户可能需要调整输入图像的大小或减少批量处理的数量,以避免内存不足的问题。引用[3]提到,Mask R-CNN在Faster R-CNN基础上增加了约20%的开销,所以CPU上的推理时间可能会显著增加。 另外,数据预处理步骤也需要确保在CPU上进行。例如,引用[4]中的代码使用了`ToTensor()`转换,这会将图像转换为张量,但默认情况下可能在CPU上。不过,如果有任何数据加载部分使用了GPU加速,需要检查并修改为CPU。 用户可能还需要注意模型加载时的权重问题。例如,使用`torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=True)`时,PyTorch会自动下载预训练权重,但需要确保这些权重被正确加载到CPU上。如果之前尝试在GPU上运行过,可能需要清除缓存或重新下载。 最后,用户可能会遇到错误信息,比如CUDA不可用。这时候需要捕获这些异常,并确保所有操作都在CPU上执行。例如,在代码开始时设置`torch.cuda.is_available = lambda: False`可能不推荐,但可以通过环境变量`CUDA_VISIBLE_DEVICES`设置为空来禁用GPU的使用。 总结一下,用户需要的关键步骤是:安装CPU版本的PyTorch,修改代码以强制使用CPU设备,处理数据时保持在CPU,调整模型加载方式,以及可能的性能优化措施。同时,引用[4]中的代码示例可以作为基础,但需要根据CPU环境进行调整。</think>### 如何在CPU环境下实现或运行Mask R-CNN模型? #### 步骤说明 1. **安装CPU版本的PyTorch** 确保安装PyTorch的CPU专用版本,避免自动调用GPU资源: ```bash pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu ``` 2. **显式指定设备为CPU** 在代码中强制模型和数据使用CPU: ```python device = torch.device("cpu") model = maskrcnn_resnet50_fpn(pretrained=True).to(device) ``` 3. **加载预训练权重时映射到CPU** 如果加载本地保存的模型权重,需指定`map_location`: ```python model.load_state_dict(torch.load("maskrcnn.pth", map_location=device)) ``` 4. **禁用CUDA相关操作** 在代码开头添加以下语句避免隐式调用GPU: ```python import os os.environ["CUDA_VISIBLE_DEVICES"] = "-1" # 禁用GPU ``` 5. **调整输入数据尺寸和批量大小** CPU内存有限,需缩小输入图像尺寸或减少批量处理数量: ```python transforms = Compose([Resize((256, 256)), ToTensor()]) # 调整图像尺寸 ``` 6. **验证代码兼容性** 运行以下最小示例测试环境是否正常: ```python import torch from torchvision.models.detection import maskrcnn_resnet50_fpn device = torch.device("cpu") model = maskrcnn_resnet50_fpn(pretrained=True).to(device) model.eval() dummy_input = torch.rand(1, 3, 256, 256).to(device) with torch.no_grad(): output = model(dummy_input) print("Mask R-CNN在CPU上运行成功!") ``` #### 关键注意事项 - **性能问题**:CPU推理速度可能比GPU慢10-50倍[^3],建议对实时性要求不高的场景使用。 - **内存限制**:输入分辨率过高可能导致内存不足,建议图像尺寸不超过$512 \times 512$。 - **功能完整性**:Mask R-CNN的ROI Align层在CPU上可能效率较低,但PyTorch 1.6+已支持CPU优化实现[^4]。 #### 部署优化建议 - 使用`onnxruntime`进行模型转换,提升CPU推理速度: ```python import onnxruntime torch.onnx.export(model, dummy_input, "maskrcnn.onnx") session = onnxruntime.InferenceSession("maskrcnn.onnx", providers=['CPUExecutionProvider']) ``` ---
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值