C# Onnx 阿里达摩院开源DAMO-YOLO目标检测

效果

模型信息

Inputs
-------------------------
name:images
tensor:Float[1, 3, 192, 320]
---------------------------------------------------------------

Outputs
-------------------------
name:output
tensor:Float[1, 1260, 80]
name:953
tensor:Float[1, 1260, 4]
---------------------------------------------------------------

项目

VS2022

.net framework 4.8

OpenCvSharp 4.8

Microsoft.ML.OnnxRuntime 1.16.2

代码

using Microsoft.ML.OnnxRuntime.Tensors;
using Microsoft.ML.OnnxRuntime;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Linq;
using System.Drawing;
using System.IO;
using OpenCvSharp.Dnn;
using System.Text;

namespace Onnx_Demo
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";

        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;

        float confThreshold = 0.5f;
        float nmsThreshold = 0.85f;


        int inpWidth;
        int inpHeight;

        Mat image;

        string model_path = "";

        SessionOptions options;
        InferenceSession onnx_session;
        Tensor<float> input_tensor;
        List<NamedOnnxValue> input_container;

        IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer;
        DisposableNamedOnnxValue[] results_onnxvalue;

        List<string> class_names;
        int nout;
        int num_proposal;
        int num_class;

        StringBuilder sb = new StringBuilder();

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;

            pictureBox1.Image = null;
            pictureBox2.Image = null;
            textBox1.Text = "";

            image_path = ofd.FileName;
            pictureBox1.Image = new System.Drawing.Bitmap(image_path);
            image = new Mat(image_path);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 创建输入容器
            input_container = new List<NamedOnnxValue>();

            // 创建输出会话
            options = new SessionOptions();
            options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;
            options.AppendExecutionProvider_CPU(0);// 设置为CPU上运行

            // 创建推理模型类,读取本地模型文件
            model_path = "model/damoyolo_tinynasL20_T_192x320.onnx";

            inpHeight = 192;
            inpWidth = 320;

            onnx_session = new InferenceSession(model_path, options);

            // 创建输入容器
            input_container = new List<NamedOnnxValue>();

            image_path = "test_img/dog.jpg";
            pictureBox1.Image = new Bitmap(image_path);

            class_names = new List<string>();
            StreamReader sr = new StreamReader("coco.names");
            string line;
            while ((line = sr.ReadLine()) != null)
            {
                class_names.Add(line);
            }
            num_class = class_names.Count();

        }

        private unsafe void button2_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }
            textBox1.Text = "检测中,请稍等……";
            pictureBox2.Image = null;
            sb.Clear();
            System.Windows.Forms.Application.DoEvents();

            image = new Mat(image_path);
            //-----------------前处理--------------------------
            float ratio = Math.Min(inpHeight * 1.0f / image.Rows, inpWidth * 1.0f / image.Cols);
            int neww = (int)(image.Cols * ratio);
            int newh = (int)(image.Rows * ratio);
            Mat dstimg = new Mat();
            Cv2.CvtColor(image, dstimg, ColorConversionCodes.BGR2RGB);
            Cv2.Resize(dstimg, dstimg, new OpenCvSharp.Size(neww, newh));
            Cv2.CopyMakeBorder(dstimg, dstimg, 0, inpHeight - newh, 0, inpWidth - neww, BorderTypes.Constant, new Scalar(1));
            int row = dstimg.Rows;
            int col = dstimg.Cols;
            float[] input_tensor_data = new float[1 * 3 * row * col];
            for (int c = 0; c < 3; c++)
            {
                for (int i = 0; i < row; i++)
                {
                    for (int j = 0; j < col; j++)
                    {
                        byte pix = ((byte*)(dstimg.Ptr(i).ToPointer()))[j * 3 + c];
                        input_tensor_data[c * row * col + i * col + j] = pix;
                    }
                }
            }
            input_tensor = new DenseTensor<float>(input_tensor_data, new[] { 1, 3, inpHeight, inpWidth });
            input_container.Add(NamedOnnxValue.CreateFromTensor("images", input_tensor)); 

            //-----------------推理--------------------------
            dt1 = DateTime.Now;
            result_infer = onnx_session.Run(input_container);//运行 Inference 并获取结果
            dt2 = DateTime.Now;

            //-----------------后处理--------------------------
            results_onnxvalue = result_infer.ToArray();
            num_proposal = results_onnxvalue[0].AsTensor<float>().Dimensions[1];
            nout = results_onnxvalue[0].AsTensor<float>().Dimensions[2];
            int n = 0, k = 0; ///cx,cy,w,h,box_score, class_score
            float[] pscores = results_onnxvalue[0].AsTensor<float>().ToArray();
            float[] pbboxes = results_onnxvalue[1].AsTensor<float>().ToArray();
            List<float> confidences = new List<float>();
            List<Rect> position_boxes = new List<Rect>();
            List<int> class_ids = new List<int>();
            for (n = 0; n < num_proposal; n++)   ///特征图尺度
            {
                int max_ind = 0;
                float class_socre = 0;
                for (k = 0; k < num_class; k++)
                {
                    if (pscores[k + n * nout] > class_socre)
                    {
                        class_socre = pscores[k + n * nout];
                        max_ind = k;
                    }
                }

                if (class_socre > confThreshold)
                {
                    float xmin = pbboxes[0 + n * 4] / ratio;
                    float ymin = pbboxes[1 + n * 4] / ratio;
                    float xmax = pbboxes[2 + n * 4] / ratio;
                    float ymax = pbboxes[3 + n * 4] / ratio;

                    Rect box = new Rect();
                    box.X = (int)xmin;
                    box.Y = (int)ymin;
                    box.Width = (int)(xmax - xmin);
                    box.Height = (int)(ymax - ymin);

                    position_boxes.Add(box);

                    confidences.Add(class_socre);

                    class_ids.Add(max_ind);
                }
            }

            // NMS非极大值抑制
            int[] indexes = new int[position_boxes.Count];
            CvDnn.NMSBoxes(position_boxes, confidences, confThreshold, nmsThreshold, out indexes);

            Result result = new Result();

            for (int i = 0; i < indexes.Length; i++)
            {
                int index = indexes[i];
                result.add(confidences[index], position_boxes[index], class_names[class_ids[index]]);
            }

            if (pictureBox2.Image != null)
            {
                pictureBox2.Image.Dispose();
            }

            sb.AppendLine("推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms");
            sb.AppendLine("------------------------------");

            // 将识别结果绘制到图片上
            Mat result_image = image.Clone();
            for (int i = 0; i < result.length; i++)
            {
                Cv2.Rectangle(result_image, result.rects[i], new Scalar(0, 0, 255), 2, LineTypes.Link8);

                Cv2.Rectangle(result_image, new OpenCvSharp.Point(result.rects[i].TopLeft.X - 1, result.rects[i].TopLeft.Y - 20),
                    new OpenCvSharp.Point(result.rects[i].BottomRight.X, result.rects[i].TopLeft.Y), new Scalar(0, 0, 255), -1);

                Cv2.PutText(result_image, result.classes[i] + "-" + result.scores[i].ToString("0.00"),
                    new OpenCvSharp.Point(result.rects[i].X, result.rects[i].Y - 4),
                    HersheyFonts.HersheySimplex, 0.6, new Scalar(0, 0, 0), 1);

                sb.AppendLine(string.Format("{0}:{1},({2},{3},{4},{5})"
                    , result.classes[i]
                    , result.scores[i].ToString("0.00")
                    , result.rects[i].TopLeft.X
                    , result.rects[i].TopLeft.Y
                    , result.rects[i].BottomRight.X
                    , result.rects[i].BottomRight.Y
                    ));
            }

            textBox1.Text = sb.ToString();
            pictureBox2.Image = new System.Drawing.Bitmap(result_image.ToMemoryStream());

            result_image.Dispose();
            dstimg.Dispose();
            image.Dispose();

        }

        private void pictureBox2_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox2.Image);
        }

        private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox1.Image);
        }
    }
}

using Microsoft.ML.OnnxRuntime.Tensors;
using Microsoft.ML.OnnxRuntime;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Linq;
using System.Drawing;
using System.IO;
using OpenCvSharp.Dnn;
using System.Text;namespace Onnx_Demo
{public partial class frmMain : Form{public frmMain(){InitializeComponent();}string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";string image_path = "";DateTime dt1 = DateTime.Now;DateTime dt2 = DateTime.Now;float confThreshold = 0.5f;float nmsThreshold = 0.85f;int inpWidth;int inpHeight;Mat image;string model_path = "";SessionOptions options;InferenceSession onnx_session;Tensor<float> input_tensor;List<NamedOnnxValue> input_container;IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer;DisposableNamedOnnxValue[] results_onnxvalue;List<string> class_names;int nout;int num_proposal;int num_class;StringBuilder sb = new StringBuilder();private void button1_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = fileFilter;if (ofd.ShowDialog() != DialogResult.OK) return;pictureBox1.Image = null;pictureBox2.Image = null;textBox1.Text = "";image_path = ofd.FileName;pictureBox1.Image = new System.Drawing.Bitmap(image_path);image = new Mat(image_path);}private void Form1_Load(object sender, EventArgs e){// 创建输入容器input_container = new List<NamedOnnxValue>();// 创建输出会话options = new SessionOptions();options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;options.AppendExecutionProvider_CPU(0);// 设置为CPU上运行// 创建推理模型类,读取本地模型文件model_path = "model/damoyolo_tinynasL20_T_192x320.onnx";inpHeight = 192;inpWidth = 320;onnx_session = new InferenceSession(model_path, options);// 创建输入容器input_container = new List<NamedOnnxValue>();image_path = "test_img/dog.jpg";pictureBox1.Image = new Bitmap(image_path);class_names = new List<string>();StreamReader sr = new StreamReader("coco.names");string line;while ((line = sr.ReadLine()) != null){class_names.Add(line);}num_class = class_names.Count();}private unsafe void button2_Click(object sender, EventArgs e){if (image_path == ""){return;}textBox1.Text = "检测中,请稍等……";pictureBox2.Image = null;sb.Clear();System.Windows.Forms.Application.DoEvents();image = new Mat(image_path);//-----------------前处理--------------------------float ratio = Math.Min(inpHeight * 1.0f / image.Rows, inpWidth * 1.0f / image.Cols);int neww = (int)(image.Cols * ratio);int newh = (int)(image.Rows * ratio);Mat dstimg = new Mat();Cv2.CvtColor(image, dstimg, ColorConversionCodes.BGR2RGB);Cv2.Resize(dstimg, dstimg, new OpenCvSharp.Size(neww, newh));Cv2.CopyMakeBorder(dstimg, dstimg, 0, inpHeight - newh, 0, inpWidth - neww, BorderTypes.Constant, new Scalar(1));int row = dstimg.Rows;int col = dstimg.Cols;float[] input_tensor_data = new float[1 * 3 * row * col];for (int c = 0; c < 3; c++){for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){byte pix = ((byte*)(dstimg.Ptr(i).ToPointer()))[j * 3 + c];input_tensor_data[c * row * col + i * col + j] = pix;}}}input_tensor = new DenseTensor<float>(input_tensor_data, new[] { 1, 3, inpHeight, inpWidth });input_container.Add(NamedOnnxValue.CreateFromTensor("images", input_tensor)); //将 input_tensor 放入一个输入参数的容器,并指定名称//-----------------推理--------------------------dt1 = DateTime.Now;result_infer = onnx_session.Run(input_container);//运行 Inference 并获取结果dt2 = DateTime.Now;//-----------------后处理--------------------------results_onnxvalue = result_infer.ToArray();num_proposal = results_onnxvalue[0].AsTensor<float>().Dimensions[1];nout = results_onnxvalue[0].AsTensor<float>().Dimensions[2];int n = 0, k = 0; ///cx,cy,w,h,box_score, class_scorefloat[] pscores = results_onnxvalue[0].AsTensor<float>().ToArray();float[] pbboxes = results_onnxvalue[1].AsTensor<float>().ToArray();List<float> confidences = new List<float>();List<Rect> position_boxes = new List<Rect>();List<int> class_ids = new List<int>();for (n = 0; n < num_proposal; n++)   ///特征图尺度{int max_ind = 0;float class_socre = 0;for (k = 0; k < num_class; k++){if (pscores[k + n * nout] > class_socre){class_socre = pscores[k + n * nout];max_ind = k;}}if (class_socre > confThreshold){float xmin = pbboxes[0 + n * 4] / ratio;float ymin = pbboxes[1 + n * 4] / ratio;float xmax = pbboxes[2 + n * 4] / ratio;float ymax = pbboxes[3 + n * 4] / ratio;Rect box = new Rect();box.X = (int)xmin;box.Y = (int)ymin;box.Width = (int)(xmax - xmin);box.Height = (int)(ymax - ymin);position_boxes.Add(box);confidences.Add(class_socre);class_ids.Add(max_ind);}}// NMS非极大值抑制int[] indexes = new int[position_boxes.Count];CvDnn.NMSBoxes(position_boxes, confidences, confThreshold, nmsThreshold, out indexes);Result result = new Result();for (int i = 0; i < indexes.Length; i++){int index = indexes[i];result.add(confidences[index], position_boxes[index], class_names[class_ids[index]]);}if (pictureBox2.Image != null){pictureBox2.Image.Dispose();}sb.AppendLine("推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms");sb.AppendLine("------------------------------");// 将识别结果绘制到图片上Mat result_image = image.Clone();for (int i = 0; i < result.length; i++){Cv2.Rectangle(result_image, result.rects[i], new Scalar(0, 0, 255), 2, LineTypes.Link8);Cv2.Rectangle(result_image, new OpenCvSharp.Point(result.rects[i].TopLeft.X - 1, result.rects[i].TopLeft.Y - 20),new OpenCvSharp.Point(result.rects[i].BottomRight.X, result.rects[i].TopLeft.Y), new Scalar(0, 0, 255), -1);Cv2.PutText(result_image, result.classes[i] + "-" + result.scores[i].ToString("0.00"),new OpenCvSharp.Point(result.rects[i].X, result.rects[i].Y - 4),HersheyFonts.HersheySimplex, 0.6, new Scalar(0, 0, 0), 1);sb.AppendLine(string.Format("{0}:{1},({2},{3},{4},{5})", result.classes[i], result.scores[i].ToString("0.00"), result.rects[i].TopLeft.X, result.rects[i].TopLeft.Y, result.rects[i].BottomRight.X, result.rects[i].BottomRight.Y));}textBox1.Text = sb.ToString();pictureBox2.Image = new System.Drawing.Bitmap(result_image.ToMemoryStream());result_image.Dispose();dstimg.Dispose();image.Dispose();}private void pictureBox2_DoubleClick(object sender, EventArgs e){Common.ShowNormalImg(pictureBox2.Image);}private void pictureBox1_DoubleClick(object sender, EventArgs e){Common.ShowNormalImg(pictureBox1.Image);}}
}

下载

源码下载

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

qt-C++笔记之主线程中使用异步逻辑来处理ROS事件循环和Qt事件循环解决相互阻塞的问题

qt-C笔记之主线程中使用异步逻辑来处理ROS事件循环和异步循环解决相互阻塞的问题 code review! 文章目录 qt-C笔记之主线程中使用异步逻辑来处理ROS事件循环和异步循环解决相互阻塞的问题1.Qt的app.exec()详解2.ros::spin()详解3.ros::AsyncSpinner详解4.主线程中结合使用的示…

云时空社会化商业 ERP 系统 gpy 文件上传漏洞复现

0x01 产品简介 时空云社会化商业ERP&#xff08;简称时空云ERP&#xff09; &#xff0c;该产品采用JAVA语言和Oracle数据库&#xff0c; 融合用友软件的先进管理理念&#xff0c;汇集各医药企业特色管理需求&#xff0c;通过规范各个流通环节从而提高企业竞争力、降低人员成本…

SDK emulator directory is missing

要进行uniapp真机测试&#xff0c;不得不安装配置一下安卓开发环境 &#xff0c;搞一个模拟器。。。然后又是各种坑。。对比来对比去还是IOS的环境使用着舒服&#xff0c;XCODE下载好&#xff0c;一切重点就是在编码了。。 安卓这个脑残货呀&#xff0c;哎&#xff0c;各种安装…

<蓝桥杯软件赛>零基础备赛20周--第8周第1讲--十大排序

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周&#xff08;读者可以按…

Day58权限提升-网站权限后台漏洞第三方获取

webshell 一般我们的渗透流程就是信息收集&#xff0c;发现漏洞&#xff0c;漏洞利用&#xff0c;一些漏洞成功之后获得一些相应的权限&#xff0c;还有一些是漏洞利用成功之后并没有取得的权限&#xff0c;而这个权限是要通过漏洞利用之后在利用其它地方取货的权限。 权限的获…

手写VUE后台管理系统5 - 整合状态管理组件pinia

整合状态管理组件 安装整合创建实例挂载使用 pinia 是一个拥有组合式 API 的 Vue 状态管理库。 pinia 官方文档&#xff1a;https://pinia.vuejs.org/zh/introduction.html 安装 yarn add pinia整合 所有与状态相关的文件都放置于项目 src/store 目录下&#xff0c;方便管理 在…

python-爬虫(可直接使用)

爬虫&#xff08;Web Scraping&#xff09;是指通过编程自动化地获取互联网上的信息的过程。爬虫的目的通常是从网页中抓取数据&#xff0c;进行数据分析、处理或展示。以下是爬虫的基本流程和一些重要的概念&#xff1a; 爬虫基本流程&#xff1a; 确定目标&#xff1a; 确定要…

504. 七进制数

这篇文章会收录到 : 算法通关第十三关-青铜挑战数学基础问题-CSDN博客 七进制数 描述 : 给定一个整数 num&#xff0c;将其转化为 7 进制&#xff0c;并以字符串形式输出。 题目 : LeetCode 504. 七进制数 : 504. 七进制数 分析 : 我们先通过二进制想一下7进制数的变化特…

【python+Excel】读取和存储测试数据完成接口自动化测试

http_request2.py用于发起http请求 #读取多条测试用例 #1、导入requests模块 import requests #从 class_12_19.do_excel1导入read_data函数 from do_excel2 import read_data from do_excel2 import write_data from do_excel2 import count_case #定义http请求函数COOKIENon…

云端导览,数字互动 | 拓世法宝AI数字人一体机助力全新旅游时代

《中国旅行消费趋势洞察白皮书&#xff08;2023版&#xff09;》显示&#xff0c;消费者旅行习惯已从“到此一游”变为“深度在地”&#xff0c;更强调在旅游中充实自我、学习新知识。 &#xff08;《中国旅行消费趋势洞察白皮书&#xff08;2023版》截图&#xff09; 从这些资…

Agent举例与应用

什么是Agent OpenAI 应用研究主管 Lilian Weng 在一篇长文中提出了 Agent LLM&#xff08;大型语言模型&#xff09;记忆规划技能工具使用这一概念&#xff0c;并详细解释了Agent的每个模块的功能。她对Agent未来的应用前景充满信心&#xff0c;但也表明到挑战无处不在。 现…

csapp深入理解计算机系统 bomb lab(1)phase_4

使用 disas phase_4 查看phase_4的汇编代码 按照惯例&#xff0c;查看一下0x4025cf内存单元存放的字符串的值是什么 所以phase_4的输入应该是两个整数。 下面使用先猜想后验证的方法尝试找出两个整数的值&#xff0c;猜想两个整数为1,2&#xff0c;在ans.txt写入1,2&#xff0…

Linux安装jdk8【十分丝滑】

1.上传安装包到Linux&#x1f495;&#x1f495;&#x1f495; 2.使用命令解压缩&#x1f495;&#x1f495;&#x1f495; tar -zxvf 压缩文件名 3.重命名&#x1f495;&#x1f495;&#x1f495; mv 原文件名 新的文件名 4.配置环境变量&#x1f929;&#x1f929;&…

史上最全前端知识点+高频面试题合集,十二大专题,命中率高达95%

前言&#xff1a; 下面分享一些关于阿里&#xff0c;美团&#xff0c;深信服等公司的面经&#xff0c;供大家参考一下。大家也可以去收集一些其他的面试题&#xff0c;可以通过面试题来看看自己有哪里不足。也可以了解自己想去的公司会问什么问题&#xff0c;进行有针对的复习。…

C# 调用 c++ dll

C# 调用 c dll 首先 c 库 dll 要定义 代码中定义 CPP_EXPORTS #ifdef LASERSDK_EXPORTS #define CPP_EXPORTS __declspec(dllexport) #else #define CPP_EXPORTS __declspec(dllimport) #endif编译器定义 LASERSDK_EXPORTS 普通函数 c extern "C" CPP_EXPORTS …

数据挖掘 感知机

要使用感知机&#xff0c;我们首先要引入头文件&#xff0c;以下是感知机用的到头文件&#xff1a; import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import Perceptron from sklearn.model_selection import train_test_…

Ubuntu Linux玩童年小霸王插卡游戏

1.下载安装模拟器 在Windows平台模拟器非常多&#xff0c;而且效果也很优秀&#xff0c;Linux平台的用户常常很羡慕&#xff0c;却因为系统的缘故&#xff0c;无法使用这样的模拟器&#xff0c;但是随着时代的发展&#xff0c;Linux平台也出现了许多优秀的模拟器&#xff0c;现…

深度学习框架:Pytorch与Keras的区别与使用方法

☁️主页 Nowl &#x1f525;专栏《机器学习实战》 《机器学习》 &#x1f4d1;君子坐而论道&#xff0c;少年起而行之 文章目录 Pytorch与Keras介绍 Pytorch 模型定义 模型编译 模型训练 输入格式 完整代码 Keras 模型定义 模型编译 模型训练 输入格式 完整代…

4G5G防爆执法记录仪、防爆智能安全帽赋能智慧燃气,可视化巡检巡线,安全生产管控

随着燃气使用的普及&#xff0c;燃气安全问题日益突出。传统应急安全问题处理方式暴露出以下问题&#xff1a; 应急预案不完善&#xff1a;目前一些燃气企业的应急预案存在实用性不高、流程不清晰等问题&#xff0c;导致在紧急情况下难以迅速启动和有效执行。 部门协同不流畅…

Less的函数的介绍

文章目录 前言描述style.less输出后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;Sass和Less &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&#xff0c;…