YOLOv11 NCNN安卓部署

YOLOv11 NCNN安卓部署

前言

yolov11 NCNN安卓部署

在这里插入图片描述

目前的帧率可以稳定在20帧左右,下面是这个项目的github地址:https://github.com/gaoxumustwin/ncnn-android-yolov11

上面的检测精度很低时因为这个模型只训练了5个epoch,使用3090训练一个epoch需要15分钟,后续会把训练50个epoch和100个epoch的权重更新到仓库中;

在之前复现了一个yolov8pose ncnn安卓部署的项目,在逛github的时候发现了一个关于yolov11的ncnn仓库,看了一下代码,发现作者是根据三木君大佬的代码进行改写,所以跟yolov8pose ncnn的非常的类似,所以就趁着刚改写的热乎劲,把yolov11 ncnn 安卓部署的代码改写出来;

环境配置

写这个blog的时候,安装时间为2024年11月29日

pip install ultralytics

安装后的ultralytics版本为:8.3.39,安装后的路径为:/root/miniconda3/lib/python3.8/site-packages/ultralytics

数据配置

yolov11的默认检测模型是使用COCO2017数据集进行训练,如果训练COCO数据集建议在autodl上进行训练,因为coco2017数据集在autodl上是公开数据集

如何查看autodl的共享数据

root@autodl-container-3686439328-168c7bd7:~# ls  /root/autodl-pub/
ADEChallengeData2016  COCO2017     DIV2K     ImageNet100                 VOCdevkit   mvtec_anomaly_detection.tar.xz
Aishell               CUB200-2011  DOTA      KITTI_Depth_Completion.tar  Vimeo-90k   nuScenes
BERT-Pretrain-Model   CULane       GOT10k    KITTI_Object                cifar-100
CASIAWebFace          CelebA       ImageNet  SemanticKITTI               cityscapes

数据制作

如果在实例中找到了自己需要的数据集,想使用共享数据,不能直接解压会出现只读错误,需要解压到自己的数据盘中(/root/autodl-tmp)

按照下面的流程操作即可

cd /root/autodl-tmp/
mkdir images
cd images
unzip /root/autodl-pub/COCO2017/train2017.zip
unzip /root/autodl-pub/COCO2017/val2017.zip

此时images下面只有 train2017 val2017

下载COCO2017的标签

cd /root/autodl-tmp
mkdir labels
cd labels
wget https://github.com/ultralytics/assets/releases/download/v0.0.0/coco2017labels.zip
unzip coco2017labels.zip
rm coco2017labels.zip
cd coco
rm -r annotations/
rm -r images/
rm -r LICENSE 
rm -r README.txt 
rm -r test-dev2017.txt 
rm -r train2017.txt 
rm -r val2017.txt 
mv labels/* ../
rm -r coco/  

此时labels下面只有 train2017 val2017

数据配置文件

复制COCO2017的配置文件到训练目录下

# workspace  root
mkdir train
cp /root/miniconda3/lib/python3.8/site-packages/ultralytics/cfg/datasets/coco.yaml ./train

修改coco.yaml中的path、train和val

# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: /root/autodl-tmp # dataset root dir
train: images/train2017 # train images (relative to 'path') 118287 images
val: images/val2017 # val images (relative to 'path') 5000 images

更换激活函数

YOLOv11默认使用的激活函数是SiLU,换成计算更高效的ReLU

更换激活函数后,原有的Pytorch模型需要重新训练再导出ONNX

修改/root/miniconda3/lib/python3.8/site-packages/ultralytics/nn/modules/conv.py中的第39行左右的default_act = nn.SiLU() 修改为 default_act = nn.ReLU()

训练

下载预训练权重

wget https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11n.pt

训练

训练脚本train.py

from ultralytics import YOLO

model = YOLO('yolo11.yaml').load('yolo11n.pt')  # 加载预训练模型  还是有用的 有助于训练

results = model.train(data='./coco.yaml', epochs=100, imgsz=640, batch=64, project='runs')

模型导出

模型结构修改

使用下面的方式修改模型结构不影响训练

修改/root/miniconda3/lib/python3.8/site-packages/ultralytics/nn/modules/head.py文件,修改Detect类的导出函数在其forward函数中加如下代码

if self.export or torch.onnx.is_in_onnx_export():
    results = self.forward_export(x)
    return tuple(results)

同时在Detect类新加上如下函数

def forward_export(self, x):
    results = []
    for i in range(self.nl):
        dfl = self.cv2[i](x[i]).permute(0, 2, 3, 1)
        cls = self.cv3[i](x[i]).sigmoid().permute(0, 2, 3, 1)
        results.append(torch.cat((dfl, cls), -1))
    return results

修改后的整体代码效果如下:

class Detect(nn.Module):
    """YOLO Detect head for detection models."""

    dynamic = False  # force grid reconstruction
    export = False  # export mode
    format = None  # export format
    end2end = False  # end2end
    max_det = 300  # max_det
    shape = None
    anchors = torch.empty(0)  # init
    strides = torch.empty(0)  # init
    legacy = False  # backward compatibility for v3/v5/v8/v9 models

    def __init__(self, nc=80, ch=()):
        """Initializes the YOLO detection layer with specified number of classes and channels."""
        super().__init__()
        self.nc = nc  # number of classes
        self.nl = len(ch)  # number of detection layers
        self.reg_max = 16  # DFL channels (ch[0] // 16 to scale 4/8/12/16/20 for n/s/m/l/x)
        self.no = nc + self.reg_max * 4  # number of outputs per anchor
        self.stride = torch.zeros(self.nl)  # strides computed during build
        c2, c3 = max((16, ch[0] // 4, self.reg_max * 4)), max(ch[0], min(self.nc, 100))  # channels
        self.cv2 = nn.ModuleList(
            nn.Sequential(Conv(x, c2, 3), Conv(c2, c2, 3), nn.Conv2d(c2, 4 * self.reg_max, 1)) for x in ch
        )
        self.cv3 = (
            nn.ModuleList(nn.Sequential(Conv(x, c3, 3), Conv(c3, c3, 3), nn.Conv2d(c3, self.nc, 1)) for x in ch)
            if self.legacy
            else nn.ModuleList(
                nn.Sequential(
                    nn.Sequential(DWConv(x, x, 3), Conv(x, c3, 1)),
                    nn.Sequential(DWConv(c3, c3, 3), Conv(c3, c3, 1)),
                    nn.Conv2d(c3, self.nc, 1),
                )
                for x in ch
            )
        )
        self.dfl = DFL(self.reg_max) if self.reg_max > 1 else nn.Identity()

        if self.end2end:
            self.one2one_cv2 = copy.deepcopy(self.cv2)
            self.one2one_cv3 = copy.deepcopy(self.cv3)

    def forward(self, x):
        """Concatenates and returns predicted bounding boxes and class probabilities."""
        if self.export or torch.onnx.is_in_onnx_export():
            results = self.forward_export(x)
            return tuple(results)

        if self.end2end:
            return self.forward_end2end(x)

        for i in range(self.nl):
            x[i] = torch.cat((self.cv2[i](x[i]), self.cv3[i](x[i])), 1)
        if self.training:  # Training path
            return x
        y = self._inference(x)
        return y if self.export else (y, x)
    
    def forward_export(self, x):
        results = []
        for i in range(self.nl):
            dfl = self.cv2[i](x[i]).permute(0, 2, 3, 1)
            cls = self.cv3[i](x[i]).sigmoid().permute(0, 2, 3, 1)
            results.append(torch.cat((dfl, cls), -1))
        return results

导出的名字修改

如果需要修改输出的名称则要去修改/root/miniconda3/lib/python3.8/site-packages/ultralytics/engine/exporter.py 的 export_onnx函数

导出

导出脚本export.py

from ultralytics import YOLO

# load  model
model = YOLO('best.pt')

# export onnx
model.export(format='onnx', opset=11, simplify=True, dynamic=False, imgsz=640)

NCNN转化和优化

$ ./onnx2ncnn best.onnx yolov11-relu.param yolov11-relu.bin

$ ./ncnnoptimize yolov11-relu.param  yolov11-relu.bin  yolov11-relu-opt.param yolov11-relu-opt.bin 1
fuse_convolution_activation /model.0/conv/Conv /model.0/act/Relu
fuse_convolution_activation /model.1/conv/Conv /model.1/act/Relu
fuse_convolution_activation /model.2/cv1/conv/Conv /model.2/cv1/act/Relu
fuse_convolution_activation /model.2/m.0/cv1/conv/Conv /model.2/m.0/cv1/act/Relu
fuse_convolution_activation /model.2/m.0/cv2/conv/Conv /model.2/m.0/cv2/act/Relu
fuse_convolution_activation /model.2/cv2/conv/Conv /model.2/cv2/act/Relu
fuse_convolution_activation /model.3/conv/Conv /model.3/act/Relu
fuse_convolution_activation /model.4/cv1/conv/Conv /model.4/cv1/act/Relu
fuse_convolution_activation /model.4/m.0/cv1/conv/Conv /model.4/m.0/cv1/act/Relu
fuse_convolution_activation /model.4/m.0/cv2/conv/Conv /model.4/m.0/cv2/act/Relu
fuse_convolution_activation /model.4/cv2/conv/Conv /model.4/cv2/act/Relu
fuse_convolution_activation /model.5/conv/Conv /model.5/act/Relu
fuse_convolution_activation /model.6/cv1/conv/Conv /model.6/cv1/act/Relu
fuse_convolution_activation /model.6/m.0/cv1/conv/Conv /model.6/m.0/cv1/act/Relu
fuse_convolution_activation /model.6/m.0/cv2/conv/Conv /model.6/m.0/cv2/act/Relu
fuse_convolution_activation /model.6/m.0/m/m.0/cv1/conv/Conv /model.6/m.0/m/m.0/cv1/act/Relu
fuse_convolution_activation /model.6/m.0/m/m.0/cv2/conv/Conv /model.6/m.0/m/m.0/cv2/act/Relu
fuse_convolution_activation /model.6/m.0/m/m.1/cv1/conv/Conv /model.6/m.0/m/m.1/cv1/act/Relu
fuse_convolution_activation /model.6/m.0/m/m.1/cv2/conv/Conv /model.6/m.0/m/m.1/cv2/act/Relu
fuse_convolution_activation /model.6/m.0/cv3/conv/Conv /model.6/m.0/cv3/act/Relu
fuse_convolution_activation /model.6/cv2/conv/Conv /model.6/cv2/act/Relu
fuse_convolution_activation /model.7/conv/Conv /model.7/act/Relu
fuse_convolution_activation /model.8/cv1/conv/Conv /model.8/cv1/act/Relu
fuse_convolution_activation /model.8/m.0/cv1/conv/Conv /model.8/m.0/cv1/act/Relu
fuse_convolution_activation /model.8/m.0/cv2/conv/Conv /model.8/m.0/cv2/act/Relu
fuse_convolution_activation /model.8/m.0/m/m.0/cv1/conv/Conv /model.8/m.0/m/m.0/cv1/act/Relu
fuse_convolution_activation /model.8/m.0/m/m.0/cv2/conv/Conv /model.8/m.0/m/m.0/cv2/act/Relu
fuse_convolution_activation /model.8/m.0/m/m.1/cv1/conv/Conv /model.8/m.0/m/m.1/cv1/act/Relu
fuse_convolution_activation /model.8/m.0/m/m.1/cv2/conv/Conv /model.8/m.0/m/m.1/cv2/act/Relu
fuse_convolution_activation /model.8/m.0/cv3/conv/Conv /model.8/m.0/cv3/act/Relu
fuse_convolution_activation /model.8/cv2/conv/Conv /model.8/cv2/act/Relu
fuse_convolution_activation /model.9/cv1/conv/Conv /model.9/cv1/act/Relu
fuse_convolution_activation /model.9/cv2/conv/Conv /model.9/cv2/act/Relu
fuse_convolution_activation /model.10/cv1/conv/Conv /model.10/cv1/act/Relu
fuse_convolution_activation /model.10/m/m.0/ffn/ffn.0/conv/Conv /model.10/m/m.0/ffn/ffn.0/act/Relu
fuse_convolution_activation /model.10/cv2/conv/Conv /model.10/cv2/act/Relu
fuse_convolution_activation /model.13/cv1/conv/Conv /model.13/cv1/act/Relu
fuse_convolution_activation /model.13/m.0/cv1/conv/Conv /model.13/m.0/cv1/act/Relu
fuse_convolution_activation /model.13/m.0/cv2/conv/Conv /model.13/m.0/cv2/act/Relu
fuse_convolution_activation /model.13/cv2/conv/Conv /model.13/cv2/act/Relu
fuse_convolution_activation /model.16/cv1/conv/Conv /model.16/cv1/act/Relu
fuse_convolution_activation /model.16/m.0/cv1/conv/Conv /model.16/m.0/cv1/act/Relu
fuse_convolution_activation /model.16/m.0/cv2/conv/Conv /model.16/m.0/cv2/act/Relu
fuse_convolution_activation /model.16/cv2/conv/Conv /model.16/cv2/act/Relu
fuse_convolution_activation /model.17/conv/Conv /model.17/act/Relu
fuse_convolution_activation /model.23/cv2.0/cv2.0.0/conv/Conv /model.23/cv2.0/cv2.0.0/act/Relu
fuse_convolution_activation /model.23/cv2.0/cv2.0.1/conv/Conv /model.23/cv2.0/cv2.0.1/act/Relu
fuse_convolution_activation /model.23/cv3.0/cv3.0.0/cv3.0.0.1/conv/Conv /model.23/cv3.0/cv3.0.0/cv3.0.0.1/act/Relu
fuse_convolution_activation /model.19/cv1/conv/Conv /model.19/cv1/act/Relu
fuse_convolution_activation /model.19/m.0/cv1/conv/Conv /model.19/m.0/cv1/act/Relu
fuse_convolution_activation /model.23/cv3.0/cv3.0.1/cv3.0.1.1/conv/Conv /model.23/cv3.0/cv3.0.1/cv3.0.1.1/act/Relu
fuse_convolution_activation /model.19/m.0/cv2/conv/Conv /model.19/m.0/cv2/act/Relu
fuse_convolution_activation /model.23/cv3.0/cv3.0.2/Conv /model.23/Sigmoid
fuse_convolution_activation /model.19/cv2/conv/Conv /model.19/cv2/act/Relu
fuse_convolution_activation /model.20/conv/Conv /model.20/act/Relu
fuse_convolution_activation /model.23/cv2.1/cv2.1.0/conv/Conv /model.23/cv2.1/cv2.1.0/act/Relu
fuse_convolution_activation /model.23/cv2.1/cv2.1.1/conv/Conv /model.23/cv2.1/cv2.1.1/act/Relu
fuse_convolution_activation /model.23/cv3.1/cv3.1.0/cv3.1.0.1/conv/Conv /model.23/cv3.1/cv3.1.0/cv3.1.0.1/act/Relu
fuse_convolution_activation /model.22/cv1/conv/Conv /model.22/cv1/act/Relu
fuse_convolution_activation /model.22/m.0/cv1/conv/Conv /model.22/m.0/cv1/act/Relu
fuse_convolution_activation /model.22/m.0/cv2/conv/Conv /model.22/m.0/cv2/act/Relu
fuse_convolution_activation /model.23/cv3.1/cv3.1.1/cv3.1.1.1/conv/Conv /model.23/cv3.1/cv3.1.1/cv3.1.1.1/act/Relu
fuse_convolution_activation /model.22/m.0/m/m.0/cv1/conv/Conv /model.22/m.0/m/m.0/cv1/act/Relu
fuse_convolution_activation /model.23/cv3.1/cv3.1.2/Conv /model.23/Sigmoid_1
fuse_convolution_activation /model.22/m.0/m/m.0/cv2/conv/Conv /model.22/m.0/m/m.0/cv2/act/Relu
fuse_convolution_activation /model.22/m.0/m/m.1/cv1/conv/Conv /model.22/m.0/m/m.1/cv1/act/Relu
fuse_convolution_activation /model.22/m.0/m/m.1/cv2/conv/Conv /model.22/m.0/m/m.1/cv2/act/Relu
fuse_convolution_activation /model.22/m.0/cv3/conv/Conv /model.22/m.0/cv3/act/Relu
fuse_convolution_activation /model.22/cv2/conv/Conv /model.22/cv2/act/Relu
fuse_convolution_activation /model.23/cv2.2/cv2.2.0/conv/Conv /model.23/cv2.2/cv2.2.0/act/Relu
fuse_convolution_activation /model.23/cv2.2/cv2.2.1/conv/Conv /model.23/cv2.2/cv2.2.1/act/Relu
fuse_convolution_activation /model.23/cv3.2/cv3.2.0/cv3.2.0.1/conv/Conv /model.23/cv3.2/cv3.2.0/cv3.2.0.1/act/Relu
fuse_convolution_activation /model.23/cv3.2/cv3.2.1/cv3.2.1.1/conv/Conv /model.23/cv3.2/cv3.2.1/cv3.2.1.1/act/Relu
fuse_convolution_activation /model.23/cv3.2/cv3.2.2/Conv /model.23/Sigmoid_2
fuse_convolutiondepthwise_activation /model.23/cv3.0/cv3.0.0/cv3.0.0.0/conv/Conv /model.23/cv3.0/cv3.0.0/cv3.0.0.0/act/Relu
fuse_convolutiondepthwise_activation /model.23/cv3.0/cv3.0.1/cv3.0.1.0/conv/Conv /model.23/cv3.0/cv3.0.1/cv3.0.1.0/act/Relu
fuse_convolutiondepthwise_activation /model.23/cv3.1/cv3.1.0/cv3.1.0.0/conv/Conv /model.23/cv3.1/cv3.1.0/cv3.1.0.0/act/Relu
fuse_convolutiondepthwise_activation /model.23/cv3.1/cv3.1.1/cv3.1.1.0/conv/Conv /model.23/cv3.1/cv3.1.1/cv3.1.1.0/act/Relu
fuse_convolutiondepthwise_activation /model.23/cv3.2/cv3.2.0/cv3.2.0.0/conv/Conv /model.23/cv3.2/cv3.2.0/cv3.2.0.0/act/Relu
fuse_convolutiondepthwise_activation /model.23/cv3.2/cv3.2.1/cv3.2.1.0/conv/Conv /model.23/cv3.2/cv3.2.1/cv3.2.1.0/act/Relu
Input layer images without shape info, shape_inference skipped
Input layer images without shape info, estimate_memory_footprint skipped

安卓代码的修改

参考这两个代码进行修改

https://github.com/gaoxumustwin/ncnn-android-yolov8-pose

https://github.com/zhouweigogogo/yolo11-ncnn

对于yolo11-ncnn有以下几个修改的地方:

  1. 将softmax函数修改为了使用快速指数fast_exp的sigmoid
  2. 将 cv::dnn::NMSBoxes 修改了使用纯C++代码的实现

对于ncnn-android-yolov8-pose修改为ncnn-android-yolov11主要为将各种与yolov8pose相关的内容替换为yolov11

具体的代码过程,有兴趣的可以去查看

本人技术水平不高,代码肯定还有提升优化的地方!!!

参考资料

https://github.com/gaoxumustwin/ncnn-android-yolov8-pose

https://github.com/zhouweigogogo/yolo11-ncnn

https://github.com/triple-Mu/ncnn-examples/blob/main/cpp/yolov8/src/triplemu-yolov8.cpp

https://zhuanlan.zhihu.com/p/769076635

https://blog.csdn.net/u012863603/article/details/142977809?ops_request_misc=&request_id=&biz_id=102&utm_term=yolov11%E7%9A%84%E8%BE%93%E5%87%BA%E6%98%AF%E4%BB%80%E4%B9%88&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-142977809.142v100pc_search_result_base2&spm=1018.2226.3001.4187

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++内存对齐

在 C 中,内存对齐 是一种编译器和硬件协作的机制,用于将数据存储在内存中时按照一定的规则进行排列,以提高数据访问的效率。其目的是确保数据在内存中的地址满足硬件对齐要求,并优化 CPU 访问速度。 C 中内存对齐的基本概念 对齐单…

365天深度学习训练营-第P6周:VGG-16算法-Pytorch实现人脸识别

🍨 本文为🔗365天深度学习训练营中的学习记录博客🍖 原作者:K同学啊 文为「365天深度学习训练营」内部文章 参考本文所写记录性文章,请在文章开头带上「👉声明」 🍺要求: 保存训练过…

SAP SD学习笔记15 - 返品处理流程2 - 参照请求传票(发票)来生成返品传票

上一章讲了返品处理(退货处理)的流程。 SAP SD学习笔记14 - 返品处理(退货处理)的流程以及系统实操,比如 返品传票;请求Block标记;收到退货之后的处理,请求传票的登录_sap 销售返品…

Flutter 1.1:下载Flutter环境

1、在AS中下载Flutter插件 在setting的Plugins中下载Flutter,如图所示,可以直接进行搜索查找 2、下载flutter的sdk源代码 flutter中文文档学习 通过Git下载SDK源代码 git clone -b stable https://github.com/flutter/flutter.git3、配置系统变量 3…

电子应用设计方案-31:智能AI音响系统方案设计

智能 AI 音响系统方案设计 一、引言 智能 AI 音响作为一种新兴的智能家居设备,通过融合语音识别、自然语言处理、音频播放等技术,为用户提供便捷的语音交互服务和高品质的音乐体验。本方案旨在设计一款功能强大、性能稳定、用户体验良好的智能 AI 音响系…

损失函数分类

1. NLLLoss(负对数似然损失) 定义: 直接对预测的概率 p(yi) 的负对数求平均。通常配合 Softmax 使用,输入为对数概率。 优点: 对离散分类问题效果良好。更灵活,用户可以自行计算 Softmax。 缺点&#x…

聊聊Flink:这次把Flink的触发器(Trigger)、移除器(Evictor)讲透

一、触发器(Trigger) Trigger 决定了一个窗口(由 window assigner 定义)何时可以被 window function 处理。 每个 WindowAssigner 都有一个默认的 Trigger。 如果默认 trigger 无法满足你的需要,你可以在 trigger(…) 调用中指定自定义的 tr…

oracle中删除指定前缀的表

近期接手做的项目,发觉数据库中有许多多余的表。究其原因,应该是同事贪图方便,将过去做过的项目复制粘贴,然后修修改改。包括数据库也是克隆过来的,然后又没有删除本项目多余的表,结果经过几个轮回&#xf…

Mybatis:CRUD数据操作之修改数据update

Mybatis基础环境准备请看:Mybatis基础环境准备 本篇讲解Mybati数据CRUD数据操作之修改数据 用户在该页面书写需要修改的数据,点击 提交 按钮,就会将数据库中对应的数据进行修改。注意一点,如果哪儿个输入框没有输入内容&#xff…

遥感数据集:FTW全球农田边界和对应影像数据,约160万田块边界及7万多个样本

Fields of The World (FTW) 是一个面向农业田地边界实例分割的基准数据集,旨在推动机器学习模型的发展,满足全球农业监测对高精度、可扩展的田地边界数据的需求。该数据集由kerner-lab提供,于2024年8月28日发布,主要特征包括&…

从0开始linux(38)——线程(1)线程概念

欢迎来到博主专栏:从0开始linux 博主ID:代码小豪 文章目录 进程与线程线程概念线程的优点线程的独立数据 进程与线程 如果要理解线程,那么进程将会时绕不开的点。首先我们回顾一下我们之前在进程章节当中是如何描述进程的? 进程&…

使用 PDF API 合并 PDF 文件

内容来源: 如何在 Mac 上合并 PDF 文件 1. 注册与认证 您可以注册一个免费的 ComPDFKit API 帐户,该帐户允许您在 30 天内免费无限制地处理 1,000 多个文档。 ComPDFKit API 使用 JSON Web Tokens 方法进行安全身份验证。从控制面板获取您的公钥和密钥&…

【聊天室后端服务器开发】语音转换子服务

概述 实现逻辑 服务器搭建流程分析 基于gflags模块进行参数解析 RPC信息:当前服务器的地址端口,主要用于搭建RPC服务器的监听地址信息服务注册信息 注册中心的地址端口:向服务器中心进行服务注册外部访问地址端口:告知注册中心的…

w064基于springboot的高校学科竞赛平台

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹赠送计算机毕业设计600个选题excel文件&#xff0…

UCOS-II 自学笔记

摘抄于大学期间记录在QQ空间的一篇自学笔记,当前清理空间,本来想直接删除掉的,但是感觉有些舍不得,因此先搬移过来。 一、UC/OS_II体系结构 二、UC/OS_II中的任务 1、任务的基本概念 在UCOS-II中,通常把一个大型任…

《Python基础》之Python中可以转换成json数据类型的数据

目录 一、JSON简介 JSON有两种基本结构 1、对象(Object) 2、数组(Array) 二、将数据装换成json数据类型方法 三、在Python中,以下数据类型可以直接转换为JSON数据类型 1、字典(Dictionary&#xff09…

Android -- 简易音乐播放器

Android – 简易音乐播放器 播放器功能:* 1. 播放模式:单曲、列表循环、列表随机;* 2. 后台播放(单例模式);* 3. 多位置同步状态回调;处理模块:* 1. 提取文件信息:音频文…

纯Go语言开发人脸检测、瞳孔/眼睛定位与面部特征检测插件-助力GoFly快速开发框架

前言​ 开发纯go插件的原因是因为目前 Go 生态系统中几乎所有现有的人脸检测解决方案都是纯粹绑定到一些 C/C 库,如 ​​OpenCV​​ 或 ​​​dlib​​​,但通过 ​​​cgo​​​ 调用 C 程序会引入巨大的延迟,并在性能方面产生显著的权衡。…

uniapp中父组件数组更新后与页面渲染数组不一致实战记录

简单描述一下业务场景方便理解: 商品设置功能,支持添加多组商品(点击添加按钮进行增加).可以对任意商品进行删除(点击减少按钮对选中的商品设置进行删除). 问题: 正常添加操作后,对已添加的任意商品删除后,控制台打印数组正常.但是与页面显示不一致.已上图为例,选中尾…

【Figma】中文版安装

一、软件安装包下载 打开官网链接https://www.figma.com/downloads/下载相应安装包 或使用我已下载好的链接: FigmaSetup.exe 链接: https://pan.baidu.com/s/113eQ8JRETdeOwUp2B3uieA?pwd4vep 二、安装流程 1.点击安装包 2.选择在浏览器登录 3.输入账号密码&a…