Gradio and ONNX 图像分类 Demo

参考:https://www.gradio.app/guides/Gradio-and-ONNX-on-Hugging-Face

import numpy as np
import onnxruntime
import copy
import cv2
def letter_bbox(img, tar_size=(512, 512), color=(0, 0, 0)):
    height = tar_size[0]
    shape = img.shape  # shape = [height,width]
    ratio = float(height) / max(shape)  # ratio = old / new 得到缩放比例
    new_shape = (round(shape[1] * ratio), round(shape[0] * ratio))
    dw = (height - new_shape[0]) / 2  # width padding
    dh = (height - new_shape[1]) / 2  # height padding
    top, bottom = round(dh - 0.1), round(dh + 0.1)
    left, right = round(dw - 0.1), round(dw + 0.1)
    img = cv2.resize(img, new_shape, interpolation=cv2.INTER_LINEAR)
    img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
    return img, {'dw':dw, 'dh':dh, 'ratio':ratio, 'orin_shape':shape}
class Classifier(object):
    def __init__(self, model_path: str, cls_dict: dict, provider: list = None,
                 letter_box_flag: bool = True, infer_size: tuple = (224, 224)):
        if provider is None:
            self.provider = ['CUDAExecutionProvider', 'CPUExecutionProvider']
        self.onnx_session = onnxruntime.InferenceSession(model_path, providers=self.provider)
        self.input_name = self.get_input_name()
        self.output_name = self.get_output_name()
        self.letter_box_flag = letter_box_flag
        self.infer_size = infer_size
        self.cls_dict = cls_dict
        self.mean = np.array([0.485, 0.456, 0.406])
        self.std = np.array([0.229, 0.224, 0.225])

    def get_input_name(self):
        input_name = []
        for node in self.onnx_session.get_inputs():
            input_name.append(node.name)
        return input_name

    def get_output_name(self):
        output_name = []
        for node in self.onnx_session.get_outputs():
            output_name.append(node.name)
        return output_name

    def get_input_feed(self, img_tensor):
        input_feed = {}
        for name in self.input_name:
            input_feed[name] = img_tensor.astype(np.float32)
        return input_feed

    def pre_process(self, img):
        pre_img = copy.deepcopy(img)
        pre_img = cv2.cvtColor(pre_img, cv2.COLOR_BGR2RGB)
        if self.letter_box_flag:
            pre_img, resize_dict = letter_bbox(pre_img, tar_size=self.infer_size)
            # pre_img = pre_img / 255
            pre_img = (pre_img / 255 - self.mean) / self.std
            pre_img = pre_img.transpose(2, 0, 1)
            pre_img = np.expand_dims(pre_img, axis=0)
            return pre_img, resize_dict
        else:
            ori_shape = img.shape
            pre_img, __ = resize(pre_img, tar_size=self.infer_size)
            # pre_img = pre_img / 255
            pre_img = (pre_img/255 - self.mean) / self.std
            pre_img = pre_img.transpose(2, 0, 1)
            pre_img = np.expand_dims(pre_img, axis=0)
            return pre_img, {'orin_shape': ori_shape}

    def infer(self, img: np.ndarray):
        i_img = copy.deepcopy(img)
        i_img, param_dict = self.pre_process(i_img)
        input_feed = self.get_input_feed(i_img)
        pred = self.onnx_session.run(None, input_feed)[0]
        return pred
cloth_cls_dict = {0: 'HoodieL', 1: 'ShirtL', 2: 'ShirtS', 3: 'Suit', 4: 'DJacket', 5:'Jacket', 6: 'dressL', 
          7: 'dressS', 8: 'dressN', 9: 'TshirtL', 10: 'TshirtS', 11: 'vest'}
model = Classifier(model_path='cloth-clsv3.onnx', cls_dict=cloth_cls_dict, letter_box_flag=True, infer_size=(224, 224))
C:\Users\Administrator\AppData\Roaming\Python\Python38\site-packages\onnxruntime\capi\onnxruntime_inference_collection.py:54: UserWarning: Specified provider 'CUDAExecutionProvider' is not in available provider names.Available providers: 'CPUExecutionProvider'
  warnings.warn(
import gradio as gr
import torch
import requests
from torchvision import transforms

def read_txt_file(filename):
    with open(filename, 'r') as file:
        lines = file.readlines()
        lines = [line.strip() for line in lines]
        return lines

# model = torch.hub.load('pytorch/vision:v0.6.0', 'resnet18', pretrained=True).eval()
filename = 'labels-cloth.txt'  # 替换为你的txt文件路径
labels = read_txt_file(filename)
print(len(labels))

def predict(inp):
  inp = cv2.imread(inp)
  # inp = transforms.ToTensor()(inp).unsqueeze(0)
  with torch.no_grad():
    prediction = torch.nn.functional.softmax(torch.from_numpy(model.infer(inp)[0]), dim=0)
    confidences = {labels[i]: float(prediction[i]) for i in range(12)}
  return confidences

demo = gr.Interface(fn=predict,
             inputs=gr.inputs.Image(type="filepath"),
             outputs=gr.outputs.Label(num_top_classes=3),
             examples=[["_crop/bd_000101_3.jpg"]],
             )

demo.launch()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_11000\3164783745.py:26: GradioDeprecationWarning: Usage of gradio.inputs is deprecated, and will not be supported in the future, please import your component from gradio.components
  inputs=gr.inputs.Image(type="filepath"),
C:\Users\Administrator\AppData\Local\Temp\ipykernel_11000\3164783745.py:26: GradioDeprecationWarning: `optional` parameter is deprecated, and it has no effect
  inputs=gr.inputs.Image(type="filepath"),
C:\Users\Administrator\AppData\Local\Temp\ipykernel_11000\3164783745.py:27: GradioDeprecationWarning: Usage of gradio.outputs is deprecated, and will not be supported in the future, please import your components from gradio.components
  outputs=gr.outputs.Label(num_top_classes=3),
C:\Users\Administrator\AppData\Local\Temp\ipykernel_11000\3164783745.py:27: GradioUnusedKwargWarning: You have unused kwarg parameters in Label, please remove them: {'type': 'auto'}
  outputs=gr.outputs.Label(num_top_classes=3),


12
Running on local URL:  http://127.0.0.1:7872

To create a public link, set `share=True` in `launch()`.
posted @ 2023-08-03 18:32  Zenith_Hugh  阅读(14)  评论(0)    收藏  举报