123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- """
- 定义SSD推理流程
- """
- import numpy as np
- from mindx.sdk import Tensor # mxVision 中的 Tensor 数据结构
- from mindx.sdk import base # mxVision 推理接口
- from PIL import Image
- from watermark_verify.utils.anchors import get_anchors
- from watermark_verify.utils.utils_bbox import BBoxUtility
- class SSDInference:
- def __init__(self, model_path, input_size=(300, 300), num_classes=20, num_iou=0.45, confidence=0.5, swap=(2, 0, 1)):
- """
- 初始化SSD模型推理流程
- :param model_path: 图像分类模型onnx文件路径
- :param input_size: 模型输入大小
- :param num_classes: 模型目标检测分类数
- :param num_iou: iou阈值
- :param confidence: 置信度阈值
- :param swap: 变换方式,pytorch需要进行轴变换(默认参数),tensorflow无需进行轴变换
- """
- self.model_path = model_path
- self.input_size = input_size
- self.swap = swap
- self.num_classes = num_classes
- self.nms_iou = num_iou
- self.confidence = confidence
- def input_processing(self, image_path):
- """
- 对输入图片进行预处理
- :param image_path: 图片路径
- :return: 图片经过处理完成的ndarray
- """
- image = Image.open(image_path)
- image_shape = np.array(np.shape(image)[0:2])
- # ---------------------------------------------------------#
- # 在这里将图像转换成RGB图像,防止灰度图在预测时报错。
- # 代码仅仅支持RGB图像的预测,所有其它类型的图像都会转化成RGB
- # ---------------------------------------------------------#
- if not (len(np.shape(image)) == 3 and np.shape(image)[2] == 3):
- image = image.convert('RGB')
- image_data = resize_image(image, self.input_size, False)
- MEANS = (104, 117, 123)
- image_data = np.array(image_data, dtype='float32')
- image_data = image_data - MEANS
- image_data = np.expand_dims(np.transpose(image_data, self.swap).copy(), 0)
- image_data = image_data.astype('float32')
- return image_data, image_shape
- def predict(self, image_path):
- """
- 对单张图片进行推理
- :param image_path: 图片路径
- :return: 推理结果
- """
- image_data, image_shape = self.input_processing(image_path)
- # 使用mindx框架进行om权重文件推理
- base.mx_init()
- model = base.model(modelPath=self.model_path) # 初始化 base.model 类
- if model is None:
- raise Exception("模型导入失败!请检查model_path和device_id.")
- # 确保img_tensor是正确的输入格式
- input_tensors = Tensor(image_data) # 将numpy转为转为Tensor类
- outputs = model.infer([input_tensors]) # 执行推理
- output = []
- for item in outputs:
- item.to_host() # 将Tensor数据转移到内存
- item = np.array(item)
- if item.size == 0:
- return False
- output.append(item)
- output = self.output_processing(output, image_shape)
- return output
- def output_processing(self, outputs, image_shape):
- """
- 对模型输出进行后处理工作
- :param outputs: 模型原始输出
- :param image_shape: 原始图像大小
- :return: 经过处理完成的模型输出
- """
- # 处理模型预测输出
- bbox_util = BBoxUtility(self.num_classes)
- anchors = get_anchors(self.input_size)
- results = bbox_util.decode_box(outputs, anchors, image_shape, self.input_size, False, nms_iou=self.nms_iou,
- confidence=self.confidence)
- return results
- def resize_image(image, size, letterbox_image):
- iw, ih = image.size
- w, h = size
- if letterbox_image:
- scale = min(w / iw, h / ih)
- nw = int(iw * scale)
- nh = int(ih * scale)
- image = image.resize((nw, nh), Image.BICUBIC)
- new_image = Image.new('RGB', size, (128, 128, 128))
- new_image.paste(image, ((w - nw) // 2, (h - nh) // 2))
- else:
- new_image = image.resize((w, h), Image.BICUBIC)
- return new_image
|