JetsonOrinNano刷机与YOLOv8部署演示

原创 OpenCV学堂 2023-03-31 18:12

点击上方蓝字关注我们

微信公众号:OpenCV开发者联盟

关注获取更多计算机视觉与深度学习知识

Jetson Orin Nano 介绍

NVIDIA Jetson Orin Nano 系列模组以最小的 Jetson 外形提供高达 40 TOPS 的 AI 算力,功耗在 7W 至 15W 之间,算力相当于是 NVIDIA Jetson Nano 的 80 倍。Jetson Orin Nano 提供 8GB 和 4GB两个版本,其中 开发套件是8GB 版本。

可以广泛应用于智能机器人开发、智能无人机开发、智能相机开发。从Jetson Orin Nano™ 到最高性能的 Jetson AGX Orin™,有六个基于相同架构的不同模块,是端侧与边缘智能的理想开发载板。

显示器接口是DP的,必须买个DP转HDMI转接头才可以接到HDMI支持的显示器,最重要的这款支持WIFI了。以前的Jetson Nano是USB供电就可以了,这个是配有专门的电源线,19V电源输入,没办法算力强悍肯定得多耗电,相对来说还是低功耗。

作者用的是NV提供的测试样机,国内正式销售会在4月份开始!

JetPack5.1镜像制作

安装JetPack5.1之前先准备好一个microSD卡,最少是64G,推荐买128G的,因为Jetpack5.1安装程序烧录完成已经是20G,再安装一些其它第三方库比如pytorch、torchvision、pyqt5或者QT什么的,就没有多少应用程序开发与部署可用空间了。准备好microSD卡之后,就先下载镜像文件,下载地址如下:
https://developer.nvidia.com/downloads/embedded/l4t/r35_release_v3.1/sd_card_b49/jp511-orin-nano-sd-card-image.zip/
必须NVIDIA的账号登录之后才可以下载。JetPack5.1已经预安装好了
- CUDA11.4.19- cuDNN8.6.0- TensorRT8.5.2- OpenCV4.5.4
还有其他的一些支持工具软件。下载好Jetpack5.1镜像包之后,先下载SD卡格式化软件,格式化SD卡。截图如下:


然后从下面的地址下载镜像制作软件
https://www.balena.io/etcher#download-etcher
安装好之后选择镜像文件与SD卡,然后开始制作,显示如下:


烧录完成以后插到Jetson Orin Nano开发板的风扇下方的卡槽中,图示如下:


安装pytorch与torchvision

安装好了Jetpack5.1之后,我才发现英伟达官方还没有正式发布适配的pytorch版本跟torchvision版本,但是我在官方的论坛里面发现了这个:

意思是用pytorch1.14版本,以此类推torchvision选择0.15.1版本。然后从这里直接下载1.14适配jetpack的版本文件,这里建议先看看:
https://docs.nvidia.com/deeplearning/frameworks/install-pytorch-jetson-platform/index.html


下载好之后,别着急安装pytroch,先通过下面的命令行安装好依赖:
sudo apt-get -y install autoconf bc build-essential g++-8 gcc-8 clang-8 lld-8 gettext-base gfortran-8 iputils-ping libbz2-dev libc++-dev libcgal-dev libffi-dev libfreetype6-dev libhdf5-dev libjpeg-dev liblzma-dev libncurses5-dev libncursesw5-dev libpng-dev libreadline-dev libssl-dev libsqlite3-dev libxml2-dev libxslt-dev locales moreutils openssl python-openssl rsync scons python3-pip libopenblas-dev;

国内安装经常会有网络无法连接发生各种错误,没事多执行几次命令行肯定可以安装成功的(我的个人经验)。

安装好pytorch相关依赖之后,安装pytorch就很简单:
pip3 install torch-1.14.0a0+44dac51c.nv23.02-cp38-cp38-linux_aarch64.whl
安装好pytorch之后,使用下面的命令行从源码安装torchvision 0.15.1版本,先安装依赖,然后下载安装包,最后从源码编译安装,大概十分钟左右就好,相关命令行如下:
sudo apt install libjpeg-dev zlib1g-dev libpython3-dev libavcodec-dev libavformat-dev libswscale-devpip3 install --upgrade pillowwget https://github.com/pytorch/vision/archive/refs/tags/v0.15.1.zipunzip v0.15.1.zipcd vision-0.15.1export BUILD_VERSION=0.15.1python3 setup.py install --user
同样不行就执行几次,肯定会成功安装的,我安装与运行的截图如下:


都安装好了用pip3 list查一下,然后我发现pip list显示没有TensorRT,但是我查一下已经有了,只是缺少python包支持,我记得jetpack4.x刷机之后就自动有了,这个怎么没有了,我晕!不过没关系,执行下面的命令行安装python TensorRT支持,执行完之后肯定有了!


最终验证测试如下:

说明一切准备工作就绪了。


说明一下,安装过程中要求输入提示的都输入 y

ONNX2ENGINE

我发现我在TensorRT8.4上面转换的engine文件无法在TensorRT8.5上面成功加载,所以我直接把YOLOv8n的ONNX格式模型文件直接拷贝到Jetson Orin Nano上,然后通过命令行重新生成engine文件:
cd /usr/src/tensorrt/bin./trtexec --onnx=<path_to_onnx_file> --saveEngine=<path_to_save_engine_file>
相关截图如下:


这个时间大概在五分钟左右,需要等一下才可以转换好。

YOLOv8对象检测演示

在此之前,我已经写好了YOLOv8 + TensorRT的测试程序,所以我直接把程序拷贝过来,然后用新生成的yolov8n.engine开启YOLOv8对象检测推理,测试视频运行如下:



这里程序中FPS计算包含了前后处理,因为两个视频的分辨率不同,导致前后处理的耗时不同,对象我之前在Jetson Nano上的推理速度,我只能说太厉害了,因为我之前Python版本tensorRT的推理这个程序在Jetson Nano一跑过一会就要卡死的感觉,特别慢!相关的测试源码如下:
  1import tensorrt as trt
2from torchvision import transforms
3import torch as t
4from collections import OrderedDict, namedtuple
5import cv2 as cv
6import time
7import numpy as np
8
9img_transform = transforms.Compose([transforms.ToTensor(),
10                                    transforms.Resize((640640))
11                                    ])
12
13def load_classes():
14    with open("classes.txt""r"as f:
15        class_list = [cname.strip() for cname in f.readlines()]
16    return class_list
17
18
19def format_yolov8(frame):
20    row, col, _ = frame.shape
21    _max = max(col, row)
22    result = np.zeros((_max, _max, 3), np.uint8)
23    result[0:row, 0:col] = frame
24    result = cv.cvtColor(result, cv.COLOR_BGR2RGB)
25    return result
26
27def wrap_detection(input_image, output_data):
28    class_ids = []
29    confidences = []
30    boxes = []
31    out_data = output_data.T
32    rows = out_data.shape[0]
33
34    image_width, image_height, _ = input_image.shape
35
36    x_factor = image_width / 640.0
37    y_factor = image_height / 640.0
38
39    for r in range(rows):
40        row = out_data[r]
41        classes_scores = row[4:]
42        class_id = np.argmax(classes_scores)
43        if (classes_scores[class_id] > .25):
44            class_ids.append(class_id)
45            confidences.append(classes_scores[class_id])
46            x, y, w, h = row[0].item(), row[1].item(), row[2].item(), row[3].item()
47            left = int((x - 0.5 * w) * x_factor)
48            top = int((y - 0.5 * h) * y_factor)
49            width = int(w * x_factor)
50            height = int(h * y_factor)
51            box = np.array([left, top, width, height])
52            boxes.append(box)
53
54    indexes = cv.dnn.NMSBoxes(boxes, confidences, 0.250.25)
55
56    result_class_ids = []
57    result_confidences = []
58    result_boxes = []
59
60    for i in indexes:
61        result_confidences.append(confidences[i])
62        result_class_ids.append(class_ids[i])
63        result_boxes.append(boxes[i])
64
65    return result_class_ids, result_confidences, result_boxes
66def gpu_trt_demo():
67    class_list = load_classes()
68    device = t.device('cuda:0')
69    Binding = namedtuple('Binding', ('name''dtype''shape''data''ptr'))
70    logger = trt.Logger(trt.Logger.INFO)
71    with open("yolov8n.engine"'rb'as f, trt.Runtime(logger) as runtime:
72        model = runtime.deserialize_cuda_engine(f.read())
73    bindings = OrderedDict()
74    for index in range(model.num_bindings):
75        name = model.get_binding_name(index)
76        dtype = trt.nptype(model.get_binding_dtype(index))
77        shape = model.get_binding_shape(index)
78        data = t.from_numpy(np.empty(shape, dtype=np.dtype(dtype))).to(device)
79        bindings[name] = Binding(name, dtype, shape, data, int(data.data_ptr()))
80    binding_addrs = OrderedDict((n, d.ptr) for n, d in bindings.items())
81    context = model.create_execution_context()
82
83    capture = cv.VideoCapture("test.mp4")
84    colors = [(2552550), (02550), (0255255), (25500)]
85    while True:
86        _, frame = capture.read()
87        if frame is None:
88            print("End of stream")
89            break
90        fh, fw, fc = frame.shape
91        start = time.time()
92        image = format_yolov8(frame)
93        x_input = img_transform(image).view(13640640).to(device)
94        binding_addrs['images'] = int(x_input.data_ptr())
95        context.execute_v2(list(binding_addrs.values()))
96        out_prob = bindings['output0'].data.cpu().numpy()
97        end = time.time()
98
99        class_ids, confidences, boxes = wrap_detection(image, np.squeeze(out_prob, 0))
100        for (classid, confidence, box) in zip(class_ids, confidences, boxes):
101            if box[2] > fw * 0.67:
102                continue
103            color = colors[int(classid) % len(colors)]
104            cv.rectangle(frame, box, color, 2)
105            cv.rectangle(frame, (box[0], box[1] - 20), (box[0] + box[2], box[1]), color, -1)
106            cv.putText(frame, class_list[classid] + " " + ("%.2f"%confidence), (box[0], box[1] - 10), cv.FONT_HERSHEY_SIMPLEX, .5, (000))
107
108        inf_end = end - start
109        fps = 1 / inf_end
110        fps_label = "FPS: %.2f" % fps
111        cv.putText(frame, fps_label, (1025), cv.FONT_HERSHEY_SIMPLEX, 1, (00255), 2)
112        cv.imshow("YOLOv8 + TensorRT8.5.x Object Detection", frame)
113        cc = cv.waitKey(1)
114        if cc == 27:
115            break
116    cv.waitKey(0)
117    cv.destroyAllWindows()
118
119
120if __name__ == "__main__":
121    gpu_trt_demo()



总结:

Jetson Orin Nano从系统烧录到安装好pytorch、torchvision、部署运行YOLOv8推理演示程序基本没有什么坑,唯一需要注意的是numpy别用1.24的最新版本。Jetson Orin Nano算力相比Jetson Nano感觉是一个天上一个地下,一句话这波要相信Jetson Orin Nano!C++版本的YOLOv8推理还没来得及测试,后续补上,相信推理速度会更加好!
学习YOLOv8最新版从训练到部署
扫码观看视频教程

扫码查看OpenCV+OpenVIO+Pytorch系统化学习路线图


OpenCV学堂 专注计算机视觉开发技术分享,技术框架使用,包括OpenCV,Tensorflow,Pytorch教程与案例,相关算法详解,最新CV方向论文,硬核代码干货与代码案例详解!作者在CV工程化方面深度耕耘15年,感谢您的关注!
评论 (0)
  • CS5290兼容CS5230防破音AB/D切换,5.2W单声道GF类音频功放IC
    CS5290兼容CS5230防破音AB/D切换,5.2W单声道GF类音频功放IC
  • 14、谷景科普0510色环电感超声波震荡后出现不良的常见原因分析
    14、谷景科普0510色环电感超声波震荡后出现不良的常见原因分析
  • 晶体管电路设计 铃木雅臣著作
    内涵晶体管基础知识与晶体管放大电路制作。包括OP放大器制作等。
  • 中低压配电网实用技术指导书.pdf
    中低压配电网实用技术指导书.pdf

  • C++微服务架构及安全云盘项目实训课程
    分享课程——C++微服务架构及安全云盘项目实训,包含课程配套资料下载。


    本课程从实践中理解软件工程,学习需求分析、架构设计、详细设计文档的编写,学习编程规范,了解多人协作开发策略,理解并引用软件的版本管理,熟悉git工具和软件发布管理流程, bug管理提交问题。
  • 《精通机器学习:MATLAB 分步实施指南》
    《精通机器学习:MATLAB 分步实施指南》
  • 同步整流技术
    同步整流最小系统的详细介绍及应用详情
  • 基于波束形成的通信抗干扰算法与fpga实现
    波束形成相关的参考文献,涉及通信、导航等领域
  • 中低压配电实用技术.pdf
    中低压配电实用技术.pdf
  • 15、磁环线圈共模电感封装尺寸你知道怎么选吗
    15、磁环线圈共模电感封装尺寸你知道怎么选吗
  • CS5366应用TypeC转HDMI4k60HZ+USB3.0扩展芯片电路图

    CS5366芯片应用电路图,CS5366设计原理图,应用TypeC转HDMI4k60HZ+USB3.0扩展芯片电路,CS5366集成DSC1.2a decoder, 不仅支持2 lane 8.1G的source,  也支持2 lane 5.4G输出4K60 video方案芯片

  • 从0写自己的Linux x86操作系统
    分享一套操作系统课程——从0写自己的Linux x86操作系统,附源码+课件+开发工具+参考资料+磁盘映像下载。

    适用人群
    对操作系统内部工作机制感兴趣,想要设计操作系统的大学生、软件开发人员

    课程采用从0行代码编写的方式,教你如何写一个类似于Linux 0.11的x86操作系统,从而深入掌握操作系统的工作原理。

    课程大纲
    第一阶段:引导程序设计
        设计boot程序,接管计算机运行权
        设计loader程序,加载并解析操作系统内核
    第二阶段:多进程管理
        增加中断处理模块,可处理硬件中断和异常
        利用多任务机制,实现系统中多进程的运行
        实现信号量与锁,允许进程之间同步和互斥
    第三阶段:虚拟内存管理
        为系统增加页表,实现进程加载到虚拟地址
        利用分页机制,让进程之间相互隔离,运行互不影响
    第四阶段:tty与文件系统
        增加文件系统模块,可从磁盘上加载程序并执行
        支持标准输入输出文件,允许应用使用printf输出
    第五阶段:命令行shell实现
        实现命令行接口,解析命令行参数并执行
        创建自己的应用程序,并在shell中动态加载并执行
  • Git、Jenkins、Ansible实践CI/CD课程(20章完整版)
    分享课程——《Git、Jenkins、Ansible实践CI/CD》,课程一共20章,提供配套的文档+软件+脚本下载!学完本课程,你将会学到:掌握CI/CD自动化部署Git\Jenkins\Sonar\Nexus\Ansible\shell等内容。

    课程内容包含:
    1、掌握持续集成、持续交付、持续部署、自动化部署流程、容器发布流程、部署策略(蓝绿、灰度、滚动)
    2、掌握Git提交代码、回退代码、区域概念、分支模型;掌握远程仓库Gitee、Gitlab、备份、恢复
    3、掌握Jenkins基本应用、Jenkins集成Gitlab、集成Shell脚本、集成Ansible
    4、掌握Jenkins构建静态站点CI与CD,使用Shell、Ansible来实现不同环境的滚动升级策略
    5、掌握Jenkins构建Java应用(War包类型、Jar包类型),实现WebHook全自动CI流程
    6、掌握Nexus制品库,以及Jenkins如何集成制品库,实现自动拉取代码,自动编译代码,自提交制品库
    7、掌握Sonarqube质量检测,以及Jenkins集成Sonarqube进行代码质量扫描
    8、掌握Jenkins集成DingDing,实现Sonarqube质量检测结果状态通知
    9、掌握Jenkins全自动化CI流程,自动化部署测试环境CD流程,手动部署生产环境CD流程
    10、掌握JenkinsPipeline流水线CI与CD、掌握Jenkins分布式构建及RBAC权限管理

    课程大纲:
    第1章 持续集成CI、CD核心概念
    第2章 自动化发布代码策略
    第3章 Git分布式版本控制-本地仓库
    第4章 Git分布式版本控制-远程仓库
    第5章 Gitlab分布式版本控制系统-入门
    第6章 Gitlab分布式版本控制系统-进阶
    第7章 Gitlab分布式版本控制系统-维护
    第8章 Jenkins快速入门
    第9章 Jenkins集成Git、Shell、Ansible
    第10章 Jenkins基于Shell构建CI实战
    第11章 Jenkins基于Ansible构建CI实践
    第12章 Jenkins基于触发器实现自动化CI实践
    第13章 Jenkins基于CommitID实现自动化回退
    第14章 Jenkins实现Java项目的CI实践
    第15章 Jenkins基于Nexus实现CI-CD实践
    第16章 Jenkins基于Jar包实现CI-CD实践
    第17章 Jenkins集成SonarQube实现CI质量检查实践
    第18章 Jenkins集成钉钉实现CI质检结果通知实践
    第19章 Jenkins Pipeline流水线实现CI-CD实践
    第20章 Jenkins分布式构建与RBAC权限实践
    文档+软件+脚本
  • 阻抗匹配是指负载阻抗与激励源内部阻抗互相适配,得到最大功率输出的一种工作状态。阻抗匹配是微波电子学的一部分,也是射频电路中非常重要的一部分,主要用于传输线路中,以达到能够将所有高频微波信号传输到负载点的目的。回溯到原点,提高能源效率。阻抗,顾名思义就是对电路中电流起到阻碍作用的元器件。我们在射频电路中,又引入了特征阻抗和等效阻抗两个概念。特征阻抗是射频传输线的一个固有特性,其物理意义是在射频传输线上入射波电压与入射波电流的比值,或者反射波电压和反射波电流的比值。等效阻抗也是传输线理论的一个概念,
    cxtf004 2023-05-30 14:58 189浏览
  • 今日(5月29日),广东省人民政府网站发布,中共广东省委、广东省人民政府关于新时代广东高质量发展的若干意见(以下简称意见)。意见指出,要坚持制造业当家,强化高质量发展的产业根基。《意见》指出,到2027年,全省高质量发展实现新进步,自主创新能力明显提高。到2035年,高质量发展实现更大成效,科技创新能力大幅跃升,城乡区域发展更加协调更加平衡。意见称,广东建设现代化产业集群。着力发展先进制造业,打造梯次型产业格局,争创国家先进制造业集群。推动20个战略性产业集群发展,重点加快发展集成电路、新能源汽
    传感器专家网 2023-05-29 19:54 138浏览
  • [1] 压降 (1)什么是压降? 压降电压 VDO 是指为实现正常稳压,输入电压 VIN 必须高出所需输出电压 VOUT(nom) 的最小压差。 (2)决定压降的因素是什么?                           
    HGno1 2023-05-29 23:34 177浏览
  • 前言 2022年,全球半导体产业连续高增长,进入调整周期。与此形成对比,在新能源汽车、光伏、储能等需求带动下,第三代半导体产业保持高速发展,全球化供应链体系正在形成,竞争格局逐步确立,产业步入快速成长期。而国内第三代半导体产业经过前期产能部署和产线建设,国产第三代半导体产品相继开发成功并通过验证,技术稳步提升,产能不断释放,国产碳化硅(SiC)器件及模块开始“上机”,生态体系逐渐完善,自主可控能力不断增强,整体竞争实力日益提升。 01 产能释放,第三代半导体产业即将进入”战国
    普赛斯仪表 2023-05-29 17:31 165浏览
  • 近日,经纬恒润AUTOSAR基础软件产品INTEWORK-EAS-CP成功适配智芯半导体的Z20K14x产品家族。同时,经纬恒润完成了对智芯半导体Z20K14X 产品MCAL软件适配和工程集成,为智芯半导体提供了全套AUTOSAR解决方案。  左图:经纬恒润AUTOSAR EAS CP软件工程配置页面  右图:智芯半导体Z20K14x产品板   通过本次合作,智芯半导体的芯片产品将以功能更加完善、性能更加量化、服务更加完整的状态面向车
    hirain 2023-05-30 11:12 243浏览
  • 网约车行业竞争越来越卷,自动驾驶成为网约车平台重要的发力点,滴滴、T3出行、曹操出行等网约车平台相继对外宣布自动驾驶的计划并提出了“小目标”。滴滴发布两款自动驾驶核心硬件——“北曜Beta”激光雷达和三域融合计算平台“Orca虎鲸”,并宣布首款自动驾驶量产车型计划于2025年接入滴滴共享出行网络。T3出行联手轻舟智航在苏州启动Robtaxi的公开运营,并计划到2026年末,L4自动驾驶车辆商业运营达1000辆。曹操出行与吉利汽车达成战略合作,计划围绕出行平台构建集车内空间开发、定制车、智能驾驶、
    刘旷 2023-05-30 10:51 229浏览
  • By Toradex秦海1). 简介嵌入式 Linux  由于运行平台通常资源受限同时对稳定性要求高,因此需要比较精简,那么针对 SSH 服务器/客户端应用,通常也不使用庞大的 OpenSSH,而是采用十分精简的 Dropbear SSH工具。Dropbear 是一个基于 MIT License 的开源软件,其一些基本信息可以参考如下软件发布页面:https://matt.ucc.asn.au/dropbear/dropbear.html 本文所演示的平台来自于Toradex
    hai.qin_651820742 2023-05-31 15:16 113浏览
  • [2] 电容器与电容 (1)什么是电容器? 电容器是用于储存电荷的器件,其中包含一对或多对由绝缘体分隔的导体。容器通常由铝、钽或陶瓷等材料制成。各种材料的电容器在系统中使用时具有各自的优缺点,如表 1 所示。陶瓷电容器通常是理想的选择,因为其电容变化最小,而且成本较低。                 (2)  直流电压降额        
    HGno1 2023-05-29 23:42 183浏览
  • 射频(RF)电路板设计虽然在理论上还有很多不确定性,但RF电路板设计还是有许多可以遵循的法则。不过,在实际设计时,真正实用的技巧是当这些法则因各种限制而无法实施时,如何对它们进行折衷处理,本文将集中探讨与RF电路板分区设计有关的各种问题。1、微过孔的种类电路板上不同性质的电路必须分隔,但是又要在不产生电磁干扰的最佳情况下连接,这就需要用到微过孔(microvia)。通常微过孔直径为0.05mm~0.20mm,这些过孔一般分为三类,即盲孔(blind via)、埋孔(bury via)和通孔(th
    攻城狮华哥 2023-05-30 11:27 206浏览
  • 一、二极管基础 1、   基础知识 2、   各项参数: (1)    结电容       结电容有两种,分别是势垒电容和扩散电容。        势垒电容:PN结两端电压变化,引起积累在中间区域的电荷数量的改变,从而呈现电容效应,这个电容就是势垒电容。 扩散电容:当有外加正向偏压时,在PN结两侧的少子扩散
    HGno1 2023-05-29 22:55 177浏览
  • MEMS芯片和ASIC芯片是一个MEMS传感器中技术和价值含量最高的部分。你知道MEMS芯片是怎么被制造出来的吗?MEMS芯片与集成电路芯片有什么区别?此外,谈到MEMS传感器,我们还常说ASIC芯片,ASIC芯片是什么?对MEMS传感器有什么作用?MEMS传感器的ASIC芯片相比其他ASIC芯片有什么特别?MEMS传感器的主要构造?MEMS芯片与集成电路芯片有什么区别?MEMS是Micro-Electro-MechanicalSystem的缩写,中文名称是微机电系统,是将微电子电路技术与微机械
    传感器专家网 2023-05-29 20:00 137浏览
  •  近日,财政部会计司发布了《关于公布电子凭证会计数据标准(试行版)的通知》,为做好电子凭证会计数据标准深化试点工作,研究制定了9类电子凭证的会计数据标准。在通知的《电子凭证会计数据标准——全面数字化的电子发票(试行版)》指南中,明确了数电票报销入账归档的具体处理方式。    指南明确: 接收方取得数电票报销入账归档的,应按照《财政部 国家档案局关于规范电子会计凭证报销入账归档的通知》(财会〔2020〕6号,以下称《通知》)和《会计档案管
    科技财经汇 2023-05-29 20:47 195浏览
  • 在电脑内存条、显卡上,有一排金黄色导电触片,就是大家俗称的“金手指”。在PCB设计制作行业中的“金手指”(Gold Finger,或称Edge Connector),是由connector连接器作为PCB板对外连接网络的出口。关于“金手指”你知道多少呢?小编已做足了功课,今天就带大家全面了解PCB中“金手指”的设计,以及一些可制造性细节的处理等知识。“金手指”的功能用途1、“金手指”互连点当辅助PCB(如显卡、内存条)连接到主板时,会通过几个母槽中的其中一个插槽,如PCI、ISA或AGP槽,在外
    攻城狮华哥 2023-05-31 11:46 117浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦