当前位置: 首页 > news >正文

yolov5的pt模型转化为rk3588的rknn,并在rk3588上调用api进行前向推理

当使用yolov5进行目标检测且进行边缘计算的场景时,要考虑性价比或者国产化的话,rk3588板子是个不错的选择。

本篇介绍yolov5的pytorch模型转化为rknn的流程,并展示在rk板子上如何调用相关api来使用转好的rknn模型进行前向推理。

pt转rknn流程

pt转onnx

首先将训练好的pt模型转为onnx中间模型,在转之前需要先修改主目录底下的models下的yolo.py的部分代码,将如图的forward推理部分进行注释。
在这里插入图片描述
替换为:

    def forward(self, x):z = []for i in range(self.nl):x[i] = self.m[i](x[i])return x

如果识别出现乱框的现象,则替换为:

    def forward(self, x):z = []for i in range(self.nl):x[i] = torch.sigmoid(self.m[i](x[i]))return x

记得在训练时再给他改回去,否则会报错,在转模型时才需要改这部分代码。
接下来运行export.py来转onnx:

python export.py --weights runs/train/exp/weights/best.pt --img 320 --batch 1 --include onnx

onnx转rknn

首先创建一个虚拟环境,我创建的python版本为3.8。可以直接使用pip install -r requirements.txt来创建环境;
如果出现报错,则使用conda env create -f environment.yml来创建。如果pip安装可以的话,可以直接-i换源比较方便。
这里rknn-toolkit2安装会失败是正常的,下面会手动进行安装。

*以上为直接复制我的环境,也可以根据下面的步骤来自己安装相应的包。

接下来下载RKNN-Toolkit2,可以通过官网下载,也可以通过我上传的资源下载。
下载完先进入刚才创建的环境安装rknn-toolkit2包,如图,进入packages底下,安装相关依赖:

pip install -r requirements_cp38-1.6.0.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

在这里插入图片描述
然后安装相关rknn-toolkit2包:

pip install rknn_toolkit2-1.6.0+81f21f4d-cp38-cp38-linux_x86_64.whl

*接下来进行onnx转rknn
在如图所示路径下打开test.py
在这里插入图片描述
修改相关参数
在这里插入图片描述
在这里插入图片描述
最后一个参数要改为rk3588,默认为rk3566。改完后直接运行test.py文件即可转为rknn。

rk板子上进行前向推理

因为rk3588是aarch64架构的,所以不能用rknn-toolkit2包,而是要用rknn-toolkit-lite2包,在rk上安装对应的whl:
在这里插入图片描述
代码如下:

from copy import copy
import time
import numpy as np
import cv2
from rknnlite.api import RKNNLiteRKNN_MODEL = 'best.rknn'
# IMG_PATH = './input/240513_00000741.jpg'
OBJ_THRESH = 0.25
NMS_THRESH = 0.45
IMG_SIZE = (640, 640)
OUTPUT_VIDEO_PATH = 'output_1.mp4'
BOX = (450, 150, 1100, 550)
CLASSES = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light','fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow','elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee','skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard','tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple','sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch','potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone','microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear','hair drier', 'toothbrush']anchors = [[[10, 13], [16, 30], [33, 23]],[[30, 61], [62, 45], [59, 119]],[[116, 90], [156, 198], [373, 326]]]class Letter_Box_Info():def __init__(self, shape, new_shape, w_ratio, h_ratio, dw, dh, pad_color) -> None:self.origin_shape = shapeself.new_shape = new_shapeself.w_ratio = w_ratioself.h_ratio = h_ratioself.dw = dwself.dh = dhself.pad_color = pad_colordef box_process(position, anchors):grid_h, grid_w = position.shape[2:4]col, row = np.meshgrid(np.arange(0, grid_w), np.arange(0, grid_h))  # (80, 80) (80, 80)col = col.reshape(1, 1, grid_h, grid_w)    # (1, 1, 80, 80)row = row.reshape(1, 1, grid_h, grid_w)grid = np.concatenate((col, row), axis=1)  # (1, 2, 80, 80)stride = np.array([IMG_SIZE[1]//grid_h, IMG_SIZE[0]//grid_w]).reshape(1,2,1,1)  # 8 8col = col.repeat(len(anchors), axis=0)row = row.repeat(len(anchors), axis=0)anchors = np.array(anchors)anchors = anchors.reshape(*anchors.shape, 1, 1)  # (3, 2, 1, 1)box_xy = position[:,:2,:,:]*2 - 0.5box_wh = pow(position[:,2:4,:,:]*2, 2) * anchorsbox_xy += gridbox_xy *= stridebox = np.concatenate((box_xy, box_wh), axis=1)   # (3, 4, 80, 80)# Convert [c_x, c_y, w, h] to [x1, y1, x2, y2]xyxy = np.copy(box)xyxy[:, 0, :, :] = box[:, 0, :, :] - box[:, 2, :, :]/ 2  # top left xxyxy[:, 1, :, :] = box[:, 1, :, :] - box[:, 3, :, :]/ 2  # top left yxyxy[:, 2, :, :] = box[:, 0, :, :] + box[:, 2, :, :]/ 2  # bottom right xxyxy[:, 3, :, :] = box[:, 1, :, :] + box[:, 3, :, :]/ 2  # bottom right yreturn xyxy
#
def filter_boxes(boxes, box_confidences, box_class_probs):"""Filter boxes with object threshold."""box_confidences = box_confidences.reshape(-1)class_max_score = np.max(box_class_probs, axis=-1)classes = np.argmax(box_class_probs, axis=-1)_class_pos = np.where(class_max_score* box_confidences >= OBJ_THRESH)scores = (class_max_score* box_confidences)[_class_pos]boxes = boxes[_class_pos]classes = classes[_class_pos]return boxes, classes, scores# def filter_boxes(boxes, box_confidences, box_class_probs):
#     """Filter boxes with object threshold.
#     """
#     boxes = boxes.reshape(-1, 4)
#     box_confidences = box_confidences.reshape(-1)
#     box_class_probs = box_class_probs.reshape(-1, box_class_probs.shape[-1])
#
#     _box_pos = np.where(box_confidences >= OBJ_THRESH)
#     boxes = boxes[_box_pos]
#     box_confidences = box_confidences[_box_pos]
#     box_class_probs = box_class_probs[_box_pos]
#
#     class_max_score = np.max(box_class_probs, axis=-1)
#     classes = np.argmax(box_class_probs, axis=-1)
#     _class_pos = np.where(class_max_score >= OBJ_THRESH)
#
#     boxes = boxes[_class_pos]
#     classes = classes[_class_pos]
#     scores = (class_max_score * box_confidences)[_class_pos]
#
#     return boxes, classes, scoresdef nms_boxes(boxes, scores):"""Suppress non-maximal boxes.# Returnskeep: ndarray, index of effective boxes."""x = boxes[:, 0]y = boxes[:, 1]w = boxes[:, 2] - boxes[:, 0]h = boxes[:, 3] - boxes[:, 1]areas = w * horder = scores.argsort()[::-1]keep = []while order.size > 0:i = order[0]keep.append(i)xx1 = np.maximum(x[i], x[order[1:]])yy1 = np.maximum(y[i], y[order[1:]])xx2 = np.minimum(x[i] + w[i], x[order[1:]] + w[order[1:]])yy2 = np.minimum(y[i] + h[i], y[order[1:]] + h[order[1:]])w1 = np.maximum(0.0, xx2 - xx1 + 0.00001)h1 = np.maximum(0.0, yy2 - yy1 + 0.00001)inter = w1 * h1ovr = inter / (areas[i] + areas[order[1:]] - inter)inds = np.where(ovr <= NMS_THRESH)[0]order = order[inds + 1]keep = np.array(keep)return keepdef post_process(input_data, anchors):boxes, scores, classes_conf = [], [], []# 1*255*h*w -> 3*85*h*winput_data = [_in.reshape([len(anchors[0]),-1]+list(_in.shape[-2:])) for _in in input_data]for i in range(len(input_data)):                                    # (3, 85, 80, 80)boxes.append(box_process(input_data[i][:,:4,:,:], anchors[i]))  # (3, 4, 80, 80)scores.append(input_data[i][:,4:5,:,:])                         # (3, 1, 80, 80)classes_conf.append(input_data[i][:,5:,:,:])                    # (3, 80, 80, 80)def sp_flatten(_in):ch = _in.shape[1]_in = _in.transpose(0,2,3,1)return _in.reshape(-1, ch)boxes = [sp_flatten(_v) for _v in boxes]                  # (3, 19200, 4)classes_conf = [sp_flatten(_v) for _v in classes_conf]    # (3, 19200, 80)scores = [sp_flatten(_v) for _v in scores]                # (3, 19200, 1)boxes = np.concatenate(boxes)                  # (25200, 4)classes_conf = np.concatenate(classes_conf)    # (25200, 80)scores = np.concatenate(scores)                # (25200, 1)# filter according to thresholdboxes, classes, scores = filter_boxes(boxes, scores, classes_conf)# (12, 4)  12  12# nmsnboxes, nclasses, nscores = [], [], []for c in set(classes):inds = np.where(classes == c)b = boxes[inds]c = classes[inds]s = scores[inds]keep = nms_boxes(b, s)if len(keep) != 0:nboxes.append(b[keep])nclasses.append(c[keep])nscores.append(s[keep])if not nclasses and not nscores:return None, None, Noneboxes = np.concatenate(nboxes)classes = np.concatenate(nclasses)scores = np.concatenate(nscores)return boxes, classes, scoresdef draw(image, boxes, scores, classes):for box, score, cl in zip(boxes, scores, classes):top, left, right, bottom = [int(_b) for _b in box]print("%s @ (%d %d %d %d) %.3f" % (CLASSES[cl], top, left, right, bottom, score))cv2.rectangle(image, (top, left), (right, bottom), (255, 0, 0), 2)cv2.putText(image, '{0} {1:.2f}'.format(CLASSES[cl], score),(top, left - 6), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)def letterbox(im, new_shape=(640, 640), color=(0, 0, 0), letter_box_info_list=[]):shape = im.shape[:2]  # current shape [height, width]if isinstance(new_shape, int):new_shape = (new_shape, new_shape)r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])ratio = r  # width, height ratiosnew_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding# dw, dh = np.mod(dw, 32), np.mod(dh, 32)dw /= 2  # divide padding into 2 sidesdh /= 2if shape[::-1] != new_unpad:  # resizeim = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))left, right = int(round(dw - 0.1)), int(round(dw + 0.1))im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add borderletter_box_info_list.append(Letter_Box_Info(shape, new_shape, ratio, ratio, dw, dh, color))return im, letter_box_info_listdef get_real_box(box, in_format='xyxy', letter_box_info_list=[]):bbox = copy(box)# unletter_box resultif in_format=='xyxy':bbox[:,0] -= letter_box_info_list[-1].dwbbox[:,0] /= letter_box_info_list[-1].w_ratiobbox[:,0] = np.clip(bbox[:,0], 0, letter_box_info_list[-1].origin_shape[1])bbox[:,1] -= letter_box_info_list[-1].dhbbox[:,1] /= letter_box_info_list[-1].h_ratiobbox[:,1] = np.clip(bbox[:,1], 0, letter_box_info_list[-1].origin_shape[0])bbox[:,2] -= letter_box_info_list[-1].dwbbox[:,2] /= letter_box_info_list[-1].w_ratiobbox[:,2] = np.clip(bbox[:,2], 0, letter_box_info_list[-1].origin_shape[1])bbox[:,3] -= letter_box_info_list[-1].dhbbox[:,3] /= letter_box_info_list[-1].h_ratiobbox[:,3] = np.clip(bbox[:,3], 0, letter_box_info_list[-1].origin_shape[0])return bboxif __name__ == '__main__':rknn = RKNNLite()print('--> Load RKNN model')ret = rknn.load_rknn(RKNN_MODEL)if ret != 0:print('Load RKNN model failed')exit(ret)print('done')ret = rknn.init_runtime()if ret != 0:print('Init runtime environment failed!')exit(ret)print('done')cap = cv2.VideoCapture("./input/out_240715151339.mp4")# 获取视频的一些属性fps = cap.get(cv2.CAP_PROP_FPS)# width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))# height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))# 创建 VideoWriter 对象x, y, w, h = BOXfourcc = cv2.VideoWriter_fourcc(*'mp4v')  # 或者使用 'XVID'out = cv2.VideoWriter(OUTPUT_VIDEO_PATH, fourcc, fps, (w, h))fps = 0.0while True:t1 = time.time()# 读取一帧ret, frame = cap.read()if not ret:break# 加载帧img0 = frame[y:y+h, x:x+w, :]img_size = (640, 640)img, letter_box_info_list = letterbox(im= img0.copy(), new_shape=(IMG_SIZE[1], IMG_SIZE[0]))  # padded resizeimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # HWC to CHW, BGR to RGBif len(img.shape) == 3:img = img[None]  # expand for batch dimoutputs = rknn.inference(inputs=[img])  # Inferenceboxes, classes, scores = post_process(outputs, anchors)boxes_filter, scores_filter, classes_filter = [0, 0, 0, 0], [], []max_box = [0, 0, 0, 0]for box, score, cl in zip(boxes, scores, classes):if cl == 0:if (box[2]-box[0])*(box[3]-box[1]) > (max_box[2]-max_box[0])*(max_box[3]-max_box[1]):max_box = boxboxes_filter = np.expand_dims(max_box, axis=0)scores_filter = np.expand_dims(score, axis=0)classes_filter = np.expand_dims(cl, axis=0)img_p = img0.copy()draw(img_p, get_real_box(boxes_filter, 'xyxy', letter_box_info_list), scores_filter, classes_filter)cv2.imwrite("11.jpg", img_p)out.write(img_p)cap.release()out.release()rknn.release()

这里我是输入视频,输出一帧一帧的图片来查看,可以自行改变输入输出的格式。
后续再补充实现npu进行加速。

相关文章:

yolov5的pt模型转化为rk3588的rknn,并在rk3588上调用api进行前向推理

当使用yolov5进行目标检测且进行边缘计算的场景时&#xff0c;要考虑性价比或者国产化的话&#xff0c;rk3588板子是个不错的选择。 本篇介绍yolov5的pytorch模型转化为rknn的流程&#xff0c;并展示在rk板子上如何调用相关api来使用转好的rknn模型进行前向推理。 pt转rknn流程…...

【机器学习】—PCA(主成分分析)

主成分分析&#xff08;PCA&#xff09;详解 引言 主成分分析&#xff08;PCA&#xff09;是一种统计方法&#xff0c;它可以通过正交变换将一组可能相关的变量转换为一组线性不相关的变量&#xff0c;这些变量称为主成分。PCA经常用于降维&#xff0c;数据压缩&#xff0c;以…...

【Linux】vim

&#x1f33b;个人主页&#xff1a;路飞雪吖~ &#x1f320;专栏&#xff1a;Linux 目录 一、Linux开发工具 &#x1f31f;vim的基本概念 二、Linux编译器-gcc/g使用 &#x1f31f;gcc如何完成&#xff08;ESc - iso&#xff09; 1、预处理&#xff08;进行宏替换&#xff…...

virtualbox给Ubuntu22创建共享文件夹

1.在windows上的操作&#xff0c;创建共享文件夹Share 2.Ubuntu22上的操作&#xff0c;创建共享文件夹LinuxShare 3.在virtualbox虚拟机设置里&#xff0c;设置共享文件夹 共享文件夹路径&#xff1a;选择Windows系统中你需要共享的文件夹 共享文件夹名称&#xff1a;挂载至wi…...

SQLModel与FastAPI结合:构建用户增删改查接口

SQLModel简介 SQLModel是一个现代化的Python库&#xff0c;旨在简化与数据库的交互。它结合了Pydantic和SQLAlchemy的优势&#xff0c;使得定义数据模型、进行数据验证和与数据库交互变得更加直观和高效。SQLModel由FastAPI的创始人Sebastin Ramrez开发&#xff0c;专为与FastA…...

数据库日志

MySQL中有哪些日志 1&#xff0c;redo log重做日志 redo log是物理机日志&#xff0c;因为它记录的是对数据页的物理修改&#xff0c;而不是SQL语句。 作用是确保事务的持久性&#xff0c;redo log日志记录事务执行后的状态&#xff0c;用来恢复未写入 data file的已提交事务…...

力扣第 71 题 简化路径

一、题目描述 给定一个字符串 path&#xff0c;表示一个由目录名和斜杠 "/" 组成的绝对路径&#xff0c;请简化该路径&#xff0c;使其变为规范路径。 在 Unix 风格的文件系统中&#xff1a; 一个点 "." 表示当前目录本身&#xff1b;两个点 "..&q…...

Android 性能优化:内存优化(理论篇)

内存作为App程序运行最重要的资源之一&#xff0c;需要运行过程中做到合理的资源分配与回收&#xff0c;不合理的内存占用轻则使得用户应用程序运行卡顿、ANR、黑屏&#xff0c;重则导致用户应用程序发生 OOM&#xff08;out of memory&#xff09;崩溃。喜马直播随着近些年的业…...

Flink四大基石之窗口(Window)使用详解

目录 一、引言 二、为什么需要 Window 三、Window 的控制属性 窗口的长度&#xff08;大小&#xff09; 窗口的间隔 四、Flink 窗口应用代码结构 是否分组 Keyed Window --键控窗 Non-Keyed Window 核心操作流程 五、Window 的生命周期 分配阶段 触发计算 六、Wi…...

Easy Excel 通过【自定义批注拦截器】实现导出的【批注】功能

目录 Easy Excel 通过 【自定义批注拦截器】实现导出的【批注】功能需求原型&#xff1a;相关数据&#xff1a;要导出的对象字段postman 格式导出对象VO 自定义批注拦截器业务代码&#xff1a; 拦截器代码解释&#xff1a;详细解释&#xff1a;格式优化&#xff1a; Easy Excel…...

PHP 去掉特殊不可见字符 “\u200e“

描述 最近在排查网站业务时&#xff0c;发现有数据匹配失败的情况 肉眼上完全看不出问题所在 当把字符串 【M24308/23-14F‎】复制出来发现 末尾有个不可见的字符 使用删除键或左右移动时才会发现 最后测试通过 var_dump 打印 发现这个"空字符"占了三个长度 &#xf…...

Flume和kafka的整合:使用Flume将日志数据抽取到Kafka中

文章目录 1、Kafka作为Source【数据进入到kafka中&#xff0c;抽取出来】2、kafka作为Sink 【数据从别的地方抽取到kafka里面】 1、Kafka作为Source【数据进入到kafka中&#xff0c;抽取出来】 kafka源 --> memory --> 控制台&#xff1a; a1.sources r1 a1.sinks k1…...

Flutter:启动屏逻辑处理02:启动页

启动屏启动之后&#xff0c;制作一个启动页面 新建splash&#xff1a;view 视图中只有一张图片sliding.png就是我们的启动图 import package:flutter/material.dart; import package:get/get.dart; import index.dart; class SplashPage extends GetView<SplashController…...

【MySQL】自动刷新flush privileges命令

在 MySQL 中&#xff0c;执行 FLUSH PRIVILEGES 命令的主要作用是使权限表中的更改立即生效。下面是关于这个命令的一些关键点&#xff1a; 1. 什么是 FLUSH PRIVILEGES 当你使用 SET PASSWORD 或其他 SQL 语句直接修改了用户的密码或权限&#xff08;例如&#xff0c;使用 U…...

2024免费天气接口(无废话版)

免费接口1&#xff1a;http://t.weather.sojson.com/api/weather/city/101030100 免费接口2&#xff1a;http://t.weather.itboy.net/api/weather/city/101030100 至于后面那个城市编码 请自行查询&#xff1a;如图 注意&#xff01;&#xff01;&#xff01; 点击下载时 可能…...

fpga 时序分析基础

目录 触发器的动态参数 同步时序电路分析 1. 时钟脉冲的特性 2. 同步时序电路分析 Timing Analyzer的应用 异步时序与亚稳态问题 时序分析就是对时序电路进行时序检查&#xff0c;通过分析电路中所有寄存器之间的路径延迟以检查电路的传输延迟是否会导致触发器的建立时间…...

Laravel8.5+微信小程序实现京东商城秒杀方案

一、商品秒杀涉及的知识点 鉴权策略封装掊口访问频次限制小程序设计页面防抖接口调用订单创建事务使用超卖防御 二、订单库存系统方案&#xff08;3种&#xff09; 下单减库存 优点是库存和订单的强一致性&#xff0c;商品不会卖超&#xff0c;但是可能导致恶意下单&#xff…...

Git——本地仓库链接并推送到多个远程仓库

步骤 1. 新建仓库init 或 删除已有仓库远程链接 // 1.新建init git init// 2.已有仓库&#xff0c;查看链接的远程仓库 git remote -v// 3.已有远程连接仓库&#xff0c;需要删除连接 git remote rm origin(或对应远程仓库名) 2.新建远程仓库 在gitee、github等托管平台创建…...

llama-factory 系列教程 (七),Qwen2.5-7B-Instruct 模型微调与vllm部署详细流程实战

文章目录 介绍llama-factory 安装装包下载模型 微调模型数据集训练模型 微调后的模型推理 介绍 时隔已久的 llama-factory 系列教程更新了。本篇文章是第七篇&#xff0c;之前的六篇&#xff0c;大家酌情选看即可。 因为llama-factory进行了更新&#xff0c;我前面几篇文章的实…...

Spring Boot的理解

一、什么是Spring Boot? Spring Boot是一个用于构建基于Spring框架的应用程序的开源框架。它简化了Spring应用程序的开发过程&#xff0c;使开发者能够更容易地创建独立运行的、生产级别的Spring应用程序。Spring Boot提供了许多功能和约定&#xff0c;可以帮助开发者快速搭建…...

QT QFormLayout控件 全面详解

本系列文章全面的介绍了QT中的57种控件的使用方法以及示例,包括 Button(PushButton、toolButton、radioButton、checkBox、commandLinkButton、buttonBox)、Layouts(verticalLayout、horizontalLayout、gridLayout、formLayout)、Spacers(verticalSpacer、horizontalSpacer)、…...

系统性能定时监控PythonLinux

系统性能定时监控 1.系统监控概述 ⽤Python来编写脚本简化⽇常的运维⼯作是Python的⼀个重要⽤途。在Linux下&#xff0c;有许多系统命令可以让我们时刻监控系统运⾏的状态&#xff0c;如 ps &#xff0c; top &#xff0c; free 等等。要获取这些系统信息&#xff0c;Python…...

python学习——列表的相关操作

在 Python 中&#xff0c;列表&#xff08;list&#xff09;是一种非常灵活的数据结构&#xff0c;可以用来存储一系列的元素。以下是列表的一些常见操作&#xff1a; 文章目录 创建列表访问元素修改元素列表切片添加元素删除元素列表推导式其他操作pop基本用法指定索引使用场…...

HTML CSS 魔法秀:打造翻转卡片登录注册页面

这段 HTML 和 CSS 代码创建了一个具有翻转卡片效果的登录和注册页面。下面是对重点标签和 CSS 样式的解释和总结&#xff1a; 一键复制 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"…...

Web day04 SpringBoot

目录 1.Spring概念&#xff1a; 2. spring程序快速入门&#xff1a; 3.HTTP协议&#xff1a; 特点&#xff1a; 基于TCP 协议&#xff1a; 基于请求响应模型&#xff1a; HTTP协议是无状态协议&#xff1a; 请求协议&#xff1a;为浏览器向服务器发出的消息 获取请求数据…...

selinux和防火墙实验

1 、 selinux 的说明 SELinux 是 Security-Enhanced Linux 的缩写&#xff0c;意思是安全强化的 linux 。 SELinux 主要由美国国家安全局&#xff08; NSA &#xff09;开发&#xff0c;当初开发的目的是为了避免资源的误用。 系统资源都是通过程序进行访问的&#xff0c;如…...

ClamAV 在 CentOS 的开发版本 `clamav-devel`

是的&#xff0c;ClamAV 在 CentOS 上有开发版本&#xff08;通常称为 clamav-devel&#xff09;&#xff0c;它包含了开发 ClamAV 应用程序所需的头文件和库文件。以下是如何在 CentOS 上安装 ClamAV 及其开发版本的步骤。 ### 1. **安装 EPEL 仓库** ClamAV 通常在 EPEL&am…...

C++《二叉搜索树》

在初阶数据结构中我学习了树基础的概念以及了解了顺序结构的二叉树——堆和链式结构二叉树该如何实现&#xff0c;那么接下来我们将进一步的学习二叉树&#xff0c;在此会先后学习到二叉搜索树、AVL树、红黑树&#xff1b;通过这些的学习将让我们更易于理解后面set、map、哈希等…...

⭐️ GitHub Star 数量前十的工作流项目

文章开始前&#xff0c;我们先做个小调查&#xff1a;在日常工作中&#xff0c;你会使用自动化工作流工具吗&#xff1f;&#x1f64b; 事实上&#xff0c;工作流工具已经变成了提升效率的关键。其实在此之前我们已经写过一篇博客&#xff0c;跟大家分享五个好用的工作流工具。…...

uni-app中的样式尺寸单位,px,rpx,vh,vw

uni-app 支持less、sass、scss、stylus等预处理器。 尺寸单位 uni-app 支持的通用 css 单位包括 px、rpx px 即屏幕像素rpx 即响应式 px&#xff0c;一种根据屏幕宽度自适应的动态单位。以 750 宽的屏幕为基准&#xff0c;**750rpx 恰好为屏幕宽度。**屏幕变宽&#xff0c;r…...

跳表(Skip List)

跳表&#xff08;Skip List&#xff09; 跳表是一种用于快速查找、插入和删除的概率型数据结构&#xff0c;通常用于替代平衡二叉搜索树&#xff08;如 AVL 树或红黑树&#xff09;。跳表通过在有序链表的基础上增加多层索引&#xff0c;使得查找操作的平均时间复杂度降低&…...

103.【C语言】数据结构之建堆的时间复杂度分析

1.向下调整的时间复杂度 推导 设树高为h 发现如下规律 按最坏的情况考虑(即调整次数最多) 第1层,有个节点,最多向上调整h-1次 第2层,有个节点,最多向上调整h-2次 第3层,有个节点,最多向上调整h-3次 第4层,有个节点,最多向上调整h-4次 ... 第h-1层,有个节点,最多向上调整1次 第…...

数字信号处理实验报告四:IIR数字滤波器设计及软件实现

1.实验目的 (1)熟悉用双线性变换法设计IIR数字滤波器的原理与方法; (2)学会调用MATLAB信号处理工具箱中滤波器设计函数(或滤波器设计分析工具fdatool)设计各种IIR数字滤波器,学会根据滤波需求确定滤波器指标参数。 (3)掌握IIR数字滤波器的MATLAB实现方法。 (3)…...

Flutter:encrypt插件 AES加密处理

1、pubspec.yaml导入插件 cupertino_icons: ^1.0.8 # 密码加密 encrypt: 5.0.3encrypt封装 import package:encrypt/encrypt.dart; /// 加密类 class EncryptUtil {static final EncryptUtil _instance EncryptUtil._internal();factory EncryptUtil() > _instance;Encrypt…...

软银集团孙正义再度加码OpenAI,近屿智能专注AI人才培养

11月28日凌晨&#xff0c;全球最大财经CNBC报道&#xff0c;软银集团创始人兼CEO孙正义再次向人工智能领域的领军企业OpenAI投资了15亿美元。软银对OpenAI的投资已不是首次。就在上个月&#xff0c;软银已在OpenAI的上一轮融资中注入了5亿美元的资金。但他一直寻求获得OpenAI更…...

windows11下的Ubuntu(WSL)中安装界面测试ROS

症状&#xff1a;我在WSL(Ubuntu)中我自己的用户名下面安装好了ROS,输入命令行能用&#xff0c;就是不弹出窗口。 首先到windows应用商店安装Ubuntu,我这里安装的是20.04,然后安装对应的ROS&#xff08;Noetic版本&#xff09;. 然后windows安装VcXsrv. Ubuntu安装xfce4。 …...

Stable Diffusion 3详解

&#x1f33a;系列文章推荐&#x1f33a; 扩散模型系列文章正在持续的更新&#xff0c;更新节奏如下&#xff0c;先更新SD模型讲解&#xff0c;再更新相关的微调方法文章&#xff0c;敬请期待&#xff01;&#xff01;&#xff01;&#xff08;本文及其之前的文章均已更新&…...

【CSS】设置文本超出N行省略

文章目录 基本使用 这种方法主要是针对Webkit浏览器&#xff0c;因此可能在一些非Chrome浏览器中不适用。 基本使用 例如&#xff1a;设置文本超出两行显示省略号。 核心代码&#xff1a; .ellipsis-multiline {display: -webkit-box; -webkit-box-orient: vertical; /* 设置…...

Python绘画:蛋糕

Python绘画&#xff1a;蛋糕 &#x1f438; 前言 &#x1f438;&#x1f40b; 效果图 &#x1f40b;&#x1f409; 代码 &#x1f409; &#x1f335;&#x1f332;&#x1f333;&#x1f334;&#x1f33f;&#x1f340;☘️&#x1f331;&#x1f343;&#x1f38b;&#x1f…...

使用wget在清华镜像站下载Anaconda报错ERROR 403: Forbidden.

问题描述 使用wget在清华镜像站下载Anaconda报错ERROR 403: Forbidden. Resolving mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)… 101.6.15.130, 2402:f000:1:400::2 Connecting to mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)|101.6.15…...

道可云人工智能元宇宙每日资讯|第三届京西地区发展论坛成功召开

道可云元宇宙每日简报&#xff08;2024年11月27日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 工信部等十二部门印发《5G规模化应用“扬帆”行动升级方案》 11月25日&#xff0c;工业和信息化部等十二部门印发《5G规模化应用“扬帆”行动升级方案》。《方案》…...

web安全之信息收集

在信息收集中,最主要是就是收集服务器的配置信息和网站的敏感信息,其中包括域名及子域名信息,目标网站系统,CMS指纹,目标网站真实IP,开放端口等。换句话说,只要是与目标网站相关的信息,我们都应该去尽量搜集。 1.1收集域名信息 知道目标的域名之后,获取域名的注册信…...

Google Earth Engine APP(GEE) ——基于多种机器学习多源遥感不同变量组合下的森林地表生物量模型预测APP

目录 Arguments: Returns: ui.Select Arguments: Returns: ui.Chart Arguments: Returns: ui.Chart Arguments: Returns: Classifier Arguments: Returns: Classifier Arguments: Returns: Classifier 本代码的主要功能是将我们提前准备好的森林生物量样本点上传到…...

Redis开发02:redis.windows-service.conf 默认配置文件解析与注解

文件位置&#xff1a;redis安装目录下的 redis.windows-service.conf &#xff0c;存放了redis服务的相关配置&#xff0c;下面列举出默认配置的含义&#xff1a; 配置项含义bind 127.0.0.1限制 Redis 只监听本地回环地址&#xff0c;意味着只能从本地连接 Redis。protected-m…...

webrtc 3A移植以及实时处理

文章目录 前言一、交叉编译1.Pulse Audio webrtc-audio-processing2.交叉编译 二、基于alsa进行实时3A处理1.demo源码2.注意项3.效果展示 总结 前言 由于工作需要&#xff0c;硬件3A中的AEC效果实在太差&#xff0c;后面使用SpeexDSP的软3A&#xff0c;效果依旧不是很好&#…...

Android so库的编译

在没弄明白so库编译的关系前,直接看网上博主的博文,常常会觉得云里雾里的,为什么一会儿通过Android工程cmake编译,一会儿又通过NDK命令去编译。两者编译的so库有什么区别? android版第三方库编译总体思路: 对于新手小白来说搞明白上面的总体思路图很有必…...

Reachy 2,专为AI与机器人实验室打造的卓越开源双臂移动操作平台!

近期&#xff0c;花粉机器人&#xff08;POLLEN ROBOTICS&#xff09;隆重推出Reachy 2仿生机器人——下一代开源操作平台&#xff0c;为AI与机器人实验室带来理想的双臂移动操作科研平台&#xff01; Reachy 2的仿生性&#xff1a; 》拥有两个基于Maxon无刷电机的仿生7自由度…...

Jest 测试异步函数

异步编程的发展历史 异步函数,就不用我描述了,JS是单线程的,所以没有办法处理异步问题,但是可以通过其他的机制实现 回调函数 例如,我们写一个定时器,在函数fetchData中,有一个延时处理的函数,但是,你有不能等他,如果他是一年呢? 所以,我们给他一个回调函数,来等他执行完返回处…...

linux安全管理-防火墙配置

1. 开启系统防火墙 1、检查内容 检查操作系统是否开启防火墙&#xff1b; 2、配置要求 操作系统开启防火墙&#xff1b; 3、配置方法 systemctl status firewalld ##查看系统防火墙运行状态 systemctl start firewalld ##启动防火墙 systemctl restart firewalld ##重启防火墙…...

Blender 运行python脚本

Blender 运行python脚本 步骤 1&#xff1a;打开 Blender 首先&#xff0c;打开 Blender 软件。你可以从官方网站 [blender.org]( 下载最新的 Blender 版本&#xff0c;并按照安装向导进行安装。 步骤 2&#xff1a;打开“文本编辑器”面板 在 Blender 的默认布局中&#xff…...