DETR模型转RKNN

news2024/11/26 3:09:15

目录

1.前言

2.准备工作

3.开始转模型

4.测试代码

 5.不想转,直接用也可以,转好的给你,请关注评论一下


1.前言

        RKNN出最新版本了,测试了一下,rk在transformer方面做了很多的工作,至少之前不能转的模型,现在可以在fp16上面运行了,在测试int8的时候还是有误差,以往后面优化吧,这一篇是DETR模型转rknn的fp16模型的过程。

2.准备工作

        PC: ubuntu 18.04、rknntoolkit2-1.5

        开发板:rk3588

        模型链接: onnx模型 提取码: yciw 

        关于onnx模型怎样来的,请参考博文DERT(DEtection TRansformer) ONNX直接推理!!

        这里模型链接中onnx模型做了一点修改,将模型最后的两个gather算子删除了,这样转化才不出错(有心的同学可以对比一下参考博文的onnx模型和本文中的onnx模型最后的输出)

  

3.开始转模型

import numpy as np
import cv2
from rknn.api import RKNN

ONNX_MODEL = 'modified_models.onnx'
RKNN_MODEL = 'detr_fp16.rknn'
DATASET = './dataset.txt'
QUANTIZE_ON = True
QUANTIZE_OFF = False

if __name__ == '__main__':

    # Create RKNN object
    rknn = RKNN(verbose=True)

    # pre-process config
    print('--> Config model')
    rknn.config(mean_values=[[0, 0, 0]], std_values=[[1, 1, 1]], target_platform='rk3588')
    print('done')

    # Load ONNX model
    print('--> Loading model')
    ret = rknn.load_onnx(model=ONNX_MODEL)
    if ret != 0:
        print('Load model failed!')
        exit(ret)
    print('done')

    # Build model
    print('--> Building model')
    ret = rknn.build(do_quantization=QUANTIZE_OFF, dataset=DATASET)
    if ret != 0:
        print('Build model failed!')
        exit(ret)
    print('done')
    # Export RKNN model
    print('--> Export rknn model')
    ret = rknn.export_rknn(RKNN_MODEL)
    if ret != 0:
        print('Export rknn model failed!')
        exit(ret)
    print('done')

        准换后就有了detr_fp16的模型了

4.测试代码

import numpy as np
from PIL import Image
from PIL import ImageDraw, ImageFont
import colorsys
from rknnlite.api import RKNNLite


def get_classes(classes_path):
    with open(classes_path, encoding='utf-8') as f:
        class_names = f.readlines()
    class_names = [c.strip() for c in class_names]
    return class_names, len(class_names)


def get_new_img_size(height, width, min_length=600):
    if width <= height:
        f = float(min_length) / width
        resized_height = int(f * height)
        resized_width = int(min_length)
    else:
        f = float(min_length) / height
        resized_width = int(f * width)
        resized_height = int(min_length)

    return resized_height, resized_width


def resize_image(image, min_length):
    iw, ih = image.size
    h, w = get_new_img_size(ih, iw, min_length=min_length)
    new_image = image.resize((w, h), Image.BICUBIC)
    return new_image


def cvtColor(image):
    if len(np.shape(image)) == 3 and np.shape(image)[2] == 3:
        return image
    else:
        image = image.convert('RGB')
        return image


class DecodeBox:
    """ This module converts the model's output into the format expected by the coco api"""

    def box_cxcywh_to_xyxy(self, x):
        x_c, y_c, w, h = x[..., 0], x[..., 1], x[..., 2], x[..., 3]
        b = [(x_c - 0.5 * w), (y_c - 0.5 * h),
             (x_c + 0.5 * w), (y_c + 0.5 * h)]
        return np.stack(b, axis=-1)

    def forward(self, outputs, target_sizes, confidence):
        out_logits, out_bbox = outputs["pred_logits"], outputs["pred_boxes"]

        assert len(out_logits) == len(target_sizes)
        assert target_sizes.shape[1] == 2

        prob = np.exp(out_logits) / np.exp(out_logits).sum(-1, keepdims=True)
        scores = np.max(prob[..., :-1], axis=-1)
        labels = np.argmax(prob[..., :-1], axis=-1)  # 加1来转换为类别标签(背景类别为0)


        # convert to [x0, y0, x1, y1] format
        boxes = self.box_cxcywh_to_xyxy(out_bbox)

        # and from relative [0, 1] to absolute [0, height] coordinates
        img_h, img_w = np.split(target_sizes, target_sizes.shape[1], axis=1)[0], np.split(target_sizes, target_sizes.shape[1], axis=1)[1]
        img_h = img_h.astype(float)
        img_w = img_w.astype(float)
        scale_fct = np.hstack([img_w, img_h, img_w, img_h])
        boxes = boxes * scale_fct[:, None, :]

        outputs = np.concatenate([
            np.expand_dims(boxes[:, :, 1], -1),
            np.expand_dims(boxes[:, :, 0], -1),
            np.expand_dims(boxes[:, :, 3], -1),
            np.expand_dims(boxes[:, :, 2], -1),
            np.expand_dims(scores, -1),
            np.expand_dims(labels.astype(float), -1),
        ], -1)

        results = []
        for output in outputs:
            results.append(output[output[:, 4] > confidence])
        # results = [{'scores': s, 'labels': l, 'boxes': b} for s, l, b in zip(scores, labels, boxes)]
        return results


def preprocess_input(image):
    image /= 255.0
    image -= np.array([0.485, 0.456, 0.406])
    image /= np.array([0.229, 0.224, 0.225])
    return image


if __name__ == "__main__":

    count = True
    confidence = 0.5
    min_length = 512
    image = Image.open('1.jpg')
    image = image.resize((512, 512))
    image_shape = np.array([np.shape(image)[0:2]])
    image = cvtColor(image)
    image_data = resize_image(image, min_length)
    # image_data = np.expand_dims(np.transpose(preprocess_input(np.array(image_data, dtype='float32')), (2, 0, 1)), 0)
    image_data = np.expand_dims(preprocess_input(np.array(image_data, dtype='float32')), 0)
    print(image_data.shape)
    model_name = "./detr_fp16.rknn"
    rknn_lite = RKNNLite()

    # load RKNN model
    print('--> Load RKNN model')
    ret = rknn_lite.load_rknn(model_name)
    if ret != 0:
        print('Load RKNN model failed')
        exit(ret)
    print('done')
    ret = rknn_lite.init_runtime(core_mask=RKNNLite.NPU_CORE_0)
    # Inference
    print('--> Running model')
    net_outputs = rknn_lite.inference(inputs=[image_data])
    net_outs = {"pred_logits": net_outputs[0][-1], "pred_boxes": net_outputs[1][-1]}


  
    bbox_util = DecodeBox()
    results = bbox_util.forward(net_outs, image_shape, confidence)

    if results[0] is None:
        print('NO OBJECT')
    else:
        _results = results[0]
        top_label = np.array(_results[:, 5], dtype='int32')
        top_conf = _results[:, 4]
        top_boxes = _results[:, :4]
        font = ImageFont.truetype(font='model_data/simhei.ttf', size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
        thickness = int(max((image.size[0] + image.size[1]) // min_length, 1))
        classes_path = 'model_data/coco_classes.txt'
        class_names, num_classes = get_classes(classes_path)
        hsv_tuples = [(x / num_classes, 1., 1.) for x in range(num_classes)]
        colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
        colors = list(map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), colors))

        for i, c in list(enumerate(top_label)):
            predicted_class = class_names[int(c)]
            box = top_boxes[i]
            score = top_conf[i]
            top, left, bottom, right = box
            top = max(0, np.floor(top).astype('int32'))
            left = max(0, np.floor(left).astype('int32'))
            bottom = min(image.size[1], np.floor(bottom).astype('int32'))
            right = min(image.size[0], np.floor(right).astype('int32'))

            label = '{} {:.2f}'.format(predicted_class, score)
            draw = ImageDraw.Draw(image)
            label_size = draw.textsize(label, font)
            label = label.encode('utf-8')
            print(label, top, left, bottom, right)

            if top - label_size[1] >= 0:
                text_origin = np.array([left, top - label_size[1]])
            else:
                text_origin = np.array([left, top + 1])

            for i in range(thickness):
                draw.rectangle([left + i, top + i, right - i, bottom - i], outline=colors[c])
            draw.rectangle([tuple(text_origin), tuple(text_origin + label_size)], fill=colors[c])
            draw.text(text_origin, str(label, 'UTF-8'), fill=(0, 0, 0), font=font)
            del draw
        image.save('output.png')

        测试的结果如下,还是不错的。

 5.不想转,直接用也可以,转好的给你,请关注评论一下

            DETR_RKNN 提取码: k8tk 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/618469.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ReadProcessMemory可不是一个进程间通信的好方法

有时候我看到有人会使用 ReadProcessMemory 这个 API 来实现进程间通信&#xff0c;老实说吧&#xff0c;我觉得这不是一个明智的选择&#xff0c;原因有如下几条。 首先&#xff0c;你不能使用 ReadProcessMemory 来跨越安全上下文 (Security Contexts)&#xff0c;至少你需要…

SpringCloud入门实战(八)- Gateway服务网关集成

&#x1f4dd; 学技术、更要掌握学习的方法&#xff0c;一起学习&#xff0c;让进步发生 &#x1f469;&#x1f3fb; 作者&#xff1a;一只IT攻城狮 &#xff0c;关注我&#xff0c;不迷路 。 &#x1f490;学习建议&#xff1a;1、养成习惯&#xff0c;学习java的任何一个技术…

macOS Sonoma 14.0 (23A5257q) Beta1 带 OC 引导双分区黑苹果镜像

6月6日&#xff0c;在WWDC2023开发者大会上&#xff0c;苹果带来了全新Mac系统&#xff0c;命名为macOS Sonoma。该系统最大的亮点是带来了小组件&#xff0c;macOS Sonoma可以添加手机上的所有小组件&#xff0c;包括车辆小组件。 镜像下载&#xff1a; 微信公众号&#xff1…

聚观早报 | 苹果发XR头显Vision Pro;英特尔将出售部分Mobileye股票

今日要闻&#xff1a;苹果发XR头显Vision Pro&#xff1b;英特尔将出售部分Mobileye股票&#xff1b;华为已申请注册两枚NETGPT&#xff1b;瑞幸咖啡全国门店数量突破1万家&#xff1b;iPhone15系列本月将在郑州富士康量产 苹果发XR头显Vision Pro 6 月 6 日&#xff0c;苹果 …

从零手写操作系统之RVOS环境搭建-01

从零手写操作系统之RVOS环境搭建-01 背景介绍操作系统的定义操作系统的分类典型的 RTOS 介绍课程系统RVOS简介 Hello WorldQEMU介绍QEMU-virt 地址映射 系统引导引导程序要做哪些事情如何判断当前hart是不是第一个hart?如何初始化栈? 如何在屏幕输出Hello World通过串口输出U…

基于java SpringBoot框架和Vue的智能停车场管理系统

近年来&#xff0c;中国不仅综合国力大幅提升&#xff0c;国民经济也快速增长&#xff0c;推动了中国汽车工业的发展。技术的飞速发展逐渐降低了汽车的制造成本&#xff0c;越来越受欢迎。今天&#xff0c;大多数家庭都有能力购买汽车&#xff0c;因此&#xff0c;中国城市的汽…

R语言手动绘制连续线条的校准曲线(Calibration curve)(4)

校准曲线图表示的是预测值和实际值的差距&#xff0c;作为预测模型的重要部分&#xff0c;目前很多函数能绘制校准曲线。 一般分为两种&#xff0c;一种是通过Hosmer-Lemeshow检验&#xff0c;把P值分为10等分&#xff0c;求出每等分的预测值和实际值的差距。 我们既往已经通…

基于组件化开发思想的微信小程序开发框架

跨端框架的出现为小程序应用的开发带来了巨大的便利性和灵活性。它们提供了统一的开发方式、代码复用的能力&#xff0c;并且与小程序容器技术紧密结合&#xff0c;实现了一次编码、多端运行的目标。开发者可以根据项目需求和团队技术栈选择合适的跨端框架&#xff0c;从而在不…

【大数据工具】Spark 伪分布式、分布式集群搭建

Spark 集群搭建 Spark 安装包下载地址&#xff1a;https://archive.apache.org/dist/spark/ 1. Spark 伪分布式安装 安装前提&#xff1a;安装 Spark 前需要先安装好 JDK 1. 上传并解压 Spark 安装包 使用 fileZilla 或其他文件传输工具上传 Spark 安装包&#xff1a;spar…

简单易懂的 nvm 和 Node.js 版本控制指南

NVM是Node.js的版本管理工具&#xff0c;可以方便地在不同版本的Node.js之间切换。它可以通过命令行或者脚本来管理Node.js的版本&#xff0c;支持在同一台机器上安装多个版本的Node.js&#xff0c;并能够方便地切换它们。 NVM的主要功能包括&#xff1a; 安装和卸载Node.js的不…

2022年国赛高教杯数学建模A题波浪能最大输出功率设计解题全过程文档及程序

2022年国赛高教杯数学建模 A题 波浪能最大输出功率设计 原题再现 随着经济和社会的发展&#xff0c;人类面临能源需求和环境污染的双重挑战&#xff0c;发展可再生能源产业已成为世界各国的共识。波浪能作为一种重要的海洋可再生能源&#xff0c;分布广泛&#xff0c;储量丰富…

DevExpress WinForms v23.1新功能抢先看——支持系统强调色更改

DevExpress WinForm 下一个主要版本&#xff08;v23.1&#xff09;将在6月份左右发布&#xff0c;本文将为大家介绍在早期访问预览版&#xff08;EAP&#xff09;中包含的新功能。 PS&#xff1a;DevExpress WinForm拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具…

5月琐碎但值得的事情

转眼间时间就来到了6月份&#xff0c;又该写5月的思考总结了&#xff0c;依然记录一些5月份发生的小事或者收获&#xff0c; 这些内容本意给我记录生活的&#xff0c;如果对你有一些帮助就更好了。 往期&#xff1a; 1月的碎碎念&#xff0c;但是很有必要 二月的一些琐事&#…

chatgpt赋能python:Python如何阻止弹窗

Python如何阻止弹窗 Python是一种高级编程语言&#xff0c;它具有广泛的应用和丰富的库。它还可以被用于开发自动化程序&#xff0c;包括阻止弹窗。在本文中&#xff0c;我们将介绍如何使用Python阻止弹出窗口&#xff0c;并探讨防止弹窗的原因。 为什么要防止弹窗&#xff1…

Librosa库——语音识别,语音音色识别训练及应用

很多同学以为语音识别是非常难的&#xff0c;其实并不然&#xff0c;起初我也是这么认为&#xff0c;但后来发现语音识别是最简单的&#xff0c;因为同学们可能不知道Python有一个音频处理库Librosa&#xff0c;这个库非常的强大&#xff0c;可以进行音频处理、频谱表示、幅度转…

精彩回顾 | 来看 QTF 量化科技嘉年华上的 DolphinDB

6月2日至6月3日&#xff0c;2023“量变质变”量化科技嘉年华在上海世博中心圆满举办。 DolphinDB 作为联合主办方&#xff0c;在6月3日上午的“因子挖掘与机器学习”分论坛中&#xff0c;为广大量化粉丝们奉上了一场干货满满的主题分享与圆桌讨论&#xff0c;现场座无虚席&…

直击CACLP:新冠红利退潮,谁在裸泳,谁在冲刺?

5月可谓是很多医疗人马不停蹄的一个月&#xff0c;上海的第87届CMEF刚结束&#xff0c;28至30日&#xff0c;体外诊断&#xff08;IVD&#xff09;旗帜性行业盛会——第20届CACLP也在南昌绿地国际博览中心顺利落幕了。 纷享销客已经连续五年参与这两大行业盛会了&#xff0c;…

助力工业物联网,工业大数据之其他维度:组织机构【十五】

文章目录 01&#xff1a;其他维度&#xff1a;组织机构02&#xff1a;其他维度&#xff1a;仓库、物流附录一&#xff1a;常见问题1.错误&#xff1a;没有开启Cross Join2.错误&#xff1a;Unable to move source 01&#xff1a;其他维度&#xff1a;组织机构 目标&#xff1a;…

ChatGPT使用进阶,你一定要知道的应用技巧

鉴于ChatGPT的巨大能力&#xff0c;深入学习ChatGPT使用技巧势在必行。作为伴随着ChatGPT等大语言模型&#xff08;LLM&#xff09;出现的还有一个新的工程领域&#xff1a;提示工程&#xff08;Prompt Engineering&#xff09;。 提示工程&#xff08;Prompt Engineering&…

前端053_单点登录SSO_刷新令牌获取新令牌

刷新令牌获取新令牌 1、创建刷新令牌组件2、添加刷新组件路由配置3、EasyMock 添加刷新令牌接口4、定义 Api 调用刷新令牌接口5、Vuex 发送请求与重置状态6、重构刷新令牌组件7、测试当应用系统请求后台资源接口时,要在请求头带上 accessToken 去请求接口,如果 accessToken 有…