OrangePi AIpro 快速上手初体验——接口、样例和目标检测

一、 开发板简介

OrangePi AIpro开发板是香橙派联合华为精心打造的高性能 AI 开发板,其搭载了昇腾 AI 处理器,可提供 8TOPS INT8 的计算能力,内存提供了 8GB 和 16GB两种版本。可以实现图像、视频等多种数据分析与推理计算,可广泛用于教育、机器人、无人机等场景。

下面让我们来具体看看吧:

1.1 开发板全貌

首先看一眼产品的全貌:

img

img

(不得不说,颜值还是很nice的)

1.2 硬件规格

(1)昇腾AI处理器: 搭配华为昇腾310NPU,4核64位Arm处理器+AI处理器
(2)AI算力: 支持半精度(FP16):4 TFLOPS 和 整数精度(INT8):8 TOPS
(3)内存: 8GB 或 16GB
(4)存储: 板载32MB的SPI Flash,提供Micro SD卡插槽和eMMC插座
(5)接口: 接口配置丰富,包括USB3.0、USB Type-C 3.0、Micro USB、HDMI、CSI、DSI、以太网口、40pin扩展口等多种接口
(6)Wifi+蓝牙: 支持2.4G和5G双频WIFI、BT 4.2
(7)操作系统: 支持Ubuntu 22.04 和 openEuler 22.03
(8)外观规格: 107*68mm、82kg
输入npu-smi info 再看一下芯片信息:

img

1.3 接口和引脚图

接口:

img

引脚:

img

二、 开机和使用

2.1 开机准备

由于获得的Orange Pi AIpro 已经烧录了ubuntu的镜像到TF卡,因此选择使用TF卡的启动方式。
而开发板支持从 TF 卡、eMMC 和 SSD(支持 NVMe SSD 和 SATA SSD)启动,通过背面的两个拨码开关(BOOT1和BOOT2)控制

img

两个拨码开关都支持左右两种设置状态,共4种状态,目前开发板使用了其中的3种,不同状态的启动设备如下表所示:

拨码开关BOOT1拨码开关BOOT2对应的启动设备
未使用
SATA SSD和NVMe SSD
eMMC
TF卡

SATA SSD和NVMe SSD通过M2_TYPE引脚的电平自动区分。此外切换拨码开关需要重新插拔电源使启动设备选项生效,复位键不行。

2.2 开机

使用 HDMI0 连接屏幕,如图所示,上电等待一会儿后即自动开机,输入密码:Mind@123进入 ubuntu 系统

img

(注意:使用时天线不能贴到板子上,同时天线的导电布也不能挨着板子,否则可能会烧坏板子)

img

鼠标和键盘插到两个usb 3.0的接口中都可以正常使用!

2.3 SSH连接

直接用MobaXterm软件连接,下面VNC也是,填上ip地址,username可以填HwHiAiUser或者root,密码:Mind@123

img

登陆成功后显示:

img

2.4 VNC远程连接

由于我的屏幕有点拉闸,所以我选择vnc远程连接

输入ip和 端口,默认是5901,密码:Mind@123

img

说明:

打开终端后,请执行bash激活命令行。

在命令行开启远程桌面服务(执行以后重启,可使用VNC登录图形桌面。默认已开启,无需配置。)

sudo systemctl enable vncserver@1.service
reboot
在命令行关闭远程桌面服务(执行以后重启,不可使用VNC登录图形桌面,且系统会释放相应内存。)

sudo systemctl disable vncserver@1.service
reboot
在命令行修改VNC登录密码(修改密码之后,使用VNC登陆远程桌面需要重新输入密码。)

vncpasswd
成功连接后桌面:

img

若始终无法连接:

如果你不小心重新配置了vnc,导致始终无法连接的话,可以参考以下方法。

(1)输入 cd ~/.vnc进入 .vnc 文件夹

(2)输入 gedit xstartup修改 xstartup 文件

#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec startxfce4
(3)输入 chmod u+x ~/.vnc/xstartup 加上权限

(4)最后输入:

vncserver -localhost no
vncserver
即可启动vnc,此时再重新连接

三、 样例和接口测试

3.1 登录Jupyter Lab

(1)首先进入保存AI样例的目录:

cd samples/notebooks/
(2)执行 start_notebook.sh 启动Jupyter Lab

./start_notebook.sh
(3)进入Jupyter Lab的网址,直接用火狐浏览器打开即可

img

进入后,即可看到左侧有9个样例的文件夹

img

下面我就挑选几个样例进行测试一下!

3.2 yolov5目标检测

到 样例运行 部分,可以切换视频、图片和摄像头三种模式运行

infer_mode = 'video'
infer_mode = 'image'
infer_mode = 'camera'

img

img

img

def infer_frame_with_vis(image, model, labels_dict, cfg, bgr2rgb=True):# 数据预处理img, scale_ratio, pad_size = preprocess_image(image, cfg, bgr2rgb)# 模型推理output = model.infer([img])[0]output = torch.tensor(output)# 非极大值抑制boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"])pred_all = boxout[0].numpy()# 预测坐标转换scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size))# 图片预测结果可视化img_vis = draw_bbox(pred_all, image, (0, 255, 0), 2, labels_dict)return img_vis

从这里的推理框架来看,我们可以将我们训练好模型转换成om模型后直接使用,只要对数据的输入做好前处理,推理后,再做好后处理即可。

img

3.3 卡通图像生成

该样例使用 cartoonGAN 模型对输入图片进行卡通化处理。在样例中已经包含转换后的om模型和测试图片。

main 如下:

def main():MODEL_PATH = "cartoonization.om"MODEL_WIDTH = 256MODEL_HEIGHT = 256acl_resource = AclLiteResource()  # 初始化acl资源acl_resource.init()# instantiation Cartoonization objectcartoonization = Cartoonization(MODEL_PATH, MODEL_WIDTH, MODEL_HEIGHT)  # 构造模型对象# initret = cartoonization.init()  # 初始化模型类变量utils.check_ret("Cartoonization.init ", ret)  image_file = 'img.jpg'# read imageimage = AclLiteImage(image_file)  # 构造 AclLiteImage ,方便利用 dvpp 进行前处理print('===================')print(image)# preprocesscrop_and_paste_image = cartoonization.pre_process(image)  # 前处理# inferenceresult = cartoonization.inference([crop_and_paste_image, ])  # 推理# postprocesscartoonization.post_process(result, image_file, image)  # 后处理

从代码逻辑中可以看到,整套代码:

(1)首先初始化了acl资源,也就是对AscendCL进行初始化;
(2)创建了一个Cartoonization类,定义了前处理、推理和后处理函数;
(3)构造AclLiteImage类型数据,并转换图片格式为模型需要的yuv格式;
(4)进行推理;
(5)进行后处理。

img

img

3.4 人像分割与背景替换

该样例使用了PortraitNet模型进行人像分割。

main函数如下所示:

def main():"""推理主函数"""os.makedirs(OUTPUT_DIR, exist_ok=True)os.makedirs(MASK_DIR, exist_ok=True)acl_resource = AclLiteResource()acl_resource.init()seg = Seg(MODEL_PATH, MODEL_WIDTH, MODEL_HEIGHT)ret = seg.init()utils.check_ret("seg.init ", ret)images_list = [os.path.join(IMAGE_DIR, img)for img in os.listdir(IMAGE_DIR)if os.path.splitext(img)[1] in const.IMG_EXT]for image_file in images_list:image_name = os.path.basename(image_file)if image_name != 'background.jpg':print('====' + image_name + '====')# read imageimage = AclLiteImage(image_file)# Preprocess the pictureresized_image = seg.pre_process(image)# Inferenceresult = seg.inference([resized_image, ])# Post-processingmask = seg.post_process(result, image_name)# Fusion of segmented portrait and background imagebackground_replace(os.path.join(IMAGE_DIR, 'background.jpg'), \image_file, os.path.join(MASK_DIR, image_name))

可以看出代码逻辑都相似:
(1)首先初始化了acl资源;
(2)创建Seg类对象,定义前处理、推理和后处理函数;
(3)构造AclLiteImage类型图像数据并进行前处理;
(4)推理后得到分割结果进行后处理获得mask;
(5)进行背景替换

img

3.5 摄像头测试

上面开机时我们接了HDMI0的屏幕和USB的键盘、鼠标,都可以正常使用,下面我们试一下USB摄像头。

在昇腾论坛上,找到一位楼主部署了一个贪吃蛇的小游戏,我打算用这个案例来测试一下:
https://www.hiascend.com/forum/thread-0265146309613977027-1-1.html

首先接入摄像头,将代码下载到系统中,该套代码使用的Google的开源的MediaPipe手势识别库;
其次要安装相关的库:

pip install mediapipe
pip install cvzone

随后就可以直接运行代码:

python main.py

img

可见,效果还是不错的,但是有一点,用vnc连接时默认是虚拟桌面,虚拟桌面好像无法识别到摄像头,所以我还是用的hdmi屏幕。

3.6 串口通信测试

既然是开发板,那么有时候避免不了使用串口的吧,嘿嘿,所以这里对串口也进行了测试。
根据用户手册,可以找到uart设备节点和uart的对应关系:

img

也可以输入 ls /dev/ttyAMA* 来查看,需要注意的是,uart0默认设置为了调试串口功能

img

再看一下引脚图:

img

于是我用一个CH340 USB转TTL模块,选择使用uart7,也就是ttyAMA2TXGPIO7_07RXGPIO7_02

img

这里使用python的一个库:pyserial

输入:pip install pyserial 安装

import serial
import serial.tools.list_portsports_list = list(serial.tools.list_ports.comports())  # 获得所有串口设备实例
for port in ports_list:  # 输出所有串口号print(list(port)[0], list(port)[1])  #/dev/ttyAMA1、/dev/ttyAMA2ser = serial.Serial("/dev/ttyAMA2", 115200)  # 打开串口,设置波特率
if ser.isOpen():  # 判断是否打开print("open success")print(ser.name)  # 输出串口号
else:print("failed")
write_len = ser.write("OrangePi AIpro".encode('utf-8'))
ser.close()  # 关闭串口
if ser.isOpen():  # 判断是否关闭串口print("no closed")
else:print("closed")

运行: sudo python3 serial_test.py,串口ttyAMA2发送 “OrangePi AIpro”,pc端通过串口调试助手也接收到了发送过来的数据

img

img

四、AscendCL快速入门

下面我们具体来看一下AscendCL要如何应用?

AscendCL(Ascend Computing Language)是一套用于在昇腾平台上开发深度神经网络应用的C语言API库,提供运行资源管理、内存管理、模型加载与执行、算子加载与执行、媒体数据处理等API,能够实现利用昇腾硬件计算资源、在昇腾CANN平台上进行深度学习推理计算、图形图像预处理、单算子加速计算等能力。简单来说,就是统一的API框架,实现对所有资源的调用。

而AscendCL结构调用的基本流程可分下面几个步骤:
(1)AscendCL初始化
(2)运行管理资源申请
(3)模型推理/单算子调用/媒体数据处理
(4)运行管理资源释放
(5)AscendCL去初始化

下面我们通过一个简单的狗狗图像分类的应用快速了解AscendCL接口(C语言接口)开发应用的基本过程:

img

首先进入到昇腾开源仓库:Ascend: 昇腾万里,让智能无所不及

进入samples\cplusplus\level2_simple_inference\1_classification\resnet50_firstapp目录下:

(1)直接git整个仓库,或者下载zip,将resnet50_firstapp上传到ubuntu中

(2)下载测试需要的文件:

a)下载模型文件(*.prototxt):

https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/003_Atc_Models/AE/ATC%20Model/resnet50/resnet50.prototxt

放到resnet50_firstapp/model目录下

b)下载权重文件(*.caffemodel):

https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/003_Atc_Models/AE/ATC%20Model/resnet50/resnet50.caffemodel

放到resnet50_firstapp/model目录下

c)下载测试的输入图片:

https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/models/aclsample/dog1_1024_683.jpg

放到resnet50_firstapp/data目录下

img

(3)使用ATC工具进行模型转换

执行:

atc --model=model/resnet50.prototxt --weight=model/resnet50.caffemodel --framework=0 --output=model/resnet50 --soc_version=Ascend310B4

将原始模型转换为昇腾AI处理器能识别的*.om模型文件

● --model: ResNet-50网络的模型文件(.prototxt)的路径。
● --weight: ResNet-50网络的预训练模型文件(
.caffemodel)的路径。
● --framework: 原始框架类型。0:Caffe; 1:MindSpore; 3:Tensorflow; 5:Onnx
● --output: resnet50.om模型文件的路径。请注意,记录保存该om模型文件的路径,后续开发应用时需要使用。
● --soc_version: 昇腾AI处理器的版本。进入“CANN软件安装目录/compiler/data/platform_config”目录,".ini"文件的文件名即为昇腾AI处理器的版本,请根据实际情况选择。实际目录可参考:
./usr/local/Ascend/ascend-toolkit/7.0.0/compiler/data/platform_config
(我这里是通过命令npu-smi info指令这里选择的版本)

img

成功后输出如下所示:

img

转模型有可能会遇到下述问题:

img

img

在昇腾论坛找到了解决方案https://www.hiascend.com/forum/thread-0239142592318174023-1-1.html,总结就是:

转om模型时内存不足,开发板cpu核数较少,atc过程中使用的最大并行进程数默认是服务器的配置,可以使用环境变量减少atc过程中的进程数来减少内存消耗。

·减小算子最大并行编译进程数

export TE_PARALLEL_COMPILER=1

·减少图编译时可用的CPU核数

export MAX_COMPILE_CORE_NUMBER=1

之后就可以成功转换om模型啦!

(4)对输入图片进行处理

由于我们下载的.jpg的输入图片,与模型要求的输入不同,模型要求输入图片是rgb的且大小为224*224,所以这里直接运行resnet50_firstapp/script/transferPic.py脚本进行数据处理

(5)执行编译脚本

给编译脚本执行权限:

chmod +x sample_build.sh

添加环境变量:

export APP_SOURCE_PATH=/home/HwHiAiUser/samples/test_samples/resnet50_firstapp
export DDK_PATH=/usr/local/Ascend/ascend-toolkit/latest
export NPU_HOST_LIB=${DDK_PATH}/runtime/lib64/stub

执行编译脚本:

./sample_build.sh

img

此时在out/main下生成了一个名为main的可执行文件

(6)执行运行脚本

给执行脚本执行权限:

chmod +x sample_run.sh

执行运行脚本:

./sampele_run.sh

img

因为模型使用imagenet数据集训练的,所以标签可以imagenet数据集处查看:https://blog.csdn.net/u013491950/article/details/83927968

img

五、YOLOv8移植测试

虽然官方提供了yolov5的样例,但还是想体验一把部署自己模型的感觉,恰恰又对yolo系列更为熟悉,所以就还是选择以yolov8为例啦

5.1 模型转换

首先我们git下yolov8的源码:https://github.com/ultralytics/ultralytics,下载一下模型,这里我选择下载yolov8s.pt

img

用简单的代码转换成onnx模型:

from ultralytics import YOLOmodel = YOLO('yolov8s.pt', 'detect')
model.export(format='onnx', opset=11, simplify=True)

输出如下:

img

注意这里的输出是三个尺度的。

将onnx模型放到ubuntu系统中后,转换成om模型:

export TE_PARALLEL_COMPILER=1
export MAX_COMPILE_CORE_NUMBER=1
atc --model=yolov8s.onnx --framework=5 --output=yolov8s --soc_version=Ascend310B4 --input_format=NCHW --input_shape="images:1,3,640,640" --output_type="FP32" --log=error

–framework: 选择5,即onnx模型
–output: 为输出的名称,会自动加上.om后缀
–input_format: 输入格式为NCHW
–input_shape: 设置模型输入的格式
–output_type: 输出格式,可以自己选择

img

我这里为了方便后处理直接使用一个转换好的onnx模型,输出为(1, 84, 8400),大家可以自取,免费下载:https://download.csdn.net/download/qq_47941078/89365245

5.2 推理

获得om模型后,就要自己写一下推理代码啦

import cv2
import torch
import numpy as np
import time
import random
from numpy import ndarray
from typing import List, Tuple
from ais_bench.infer.interface import InferSession# 类别名称
CLASS_NAMES = ('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')# 预处理
def preprocess_warpAffine(image, dst_width=640, dst_height=640):scale = min((dst_width / image.shape[1], dst_height / image.shape[0]))ox = (dst_width  - scale * image.shape[1]) / 2oy = (dst_height - scale * image.shape[0]) / 2M = np.array([[scale, 0, ox],[0, scale, oy]], dtype=np.float32)img_pre = cv2.warpAffine(image, M, (dst_width, dst_height), flags=cv2.INTER_LINEAR,borderMode=cv2.BORDER_CONSTANT, borderValue=(114, 114, 114))IM = cv2.invertAffineTransform(M)img_pre = (img_pre[...,::-1] / 255.0).astype(np.float32)img_pre = img_pre.transpose(2, 0, 1)[None]img_pre = torch.from_numpy(img_pre)return img_pre, IM# 计算iou
def iou(box1, box2):def area_box(box):return (box[2] - box[0]) * (box[3] - box[1])left   = max(box1[0], box2[0])top    = max(box1[1], box2[1])right  = min(box1[2], box2[2])bottom = min(box1[3], box2[3])cross  = max((right-left), 0) * max((bottom-top), 0)union  = area_box(box1) + area_box(box2) - crossif cross == 0 or union == 0:return 0return cross / union# nms非极大值抑制
def NMS(boxes, iou_thres):remove_flags = [False] * len(boxes)keep_boxes = []for i, ibox in enumerate(boxes):if remove_flags[i]:continuekeep_boxes.append(ibox)for j in range(i + 1, len(boxes)):if remove_flags[j]:continuejbox = boxes[j]if(ibox[5] != jbox[5]):continueif iou(ibox, jbox) > iou_thres:remove_flags[j] = Truereturn keep_boxes# 后处理
def postprocess(pred, IM=[], conf_thres=0.25, iou_thres=0.45):# 1,8400,84 [cx,cy,w,h,class*80]boxes = []for item in pred[0]:cx, cy, w, h = item[:4]label = item[4:].argmax()confidence = item[4 + label]if confidence < conf_thres:continueleft    = cx - w * 0.5top     = cy - h * 0.5right   = cx + w * 0.5bottom  = cy + h * 0.5boxes.append([left, top, right, bottom, confidence, label])boxes = np.array(boxes)lr = boxes[:,[0, 2]]tb = boxes[:,[1, 3]]boxes[:,[0,2]] = IM[0][0] * lr + IM[0][2]boxes[:,[1,3]] = IM[1][1] * tb + IM[1][2]boxes = sorted(boxes.tolist(), key=lambda x:x[4], reverse=True)return NMS(boxes, iou_thres)def hsv2bgr(h, s, v):h_i = int(h * 6)f = h * 6 - h_ip = v * (1 - s)q = v * (1 - f * s)t = v * (1 - (1 - f) * s)r, g, b = 0, 0, 0if h_i == 0:r, g, b = v, t, pelif h_i == 1:r, g, b = q, v, pelif h_i == 2:r, g, b = p, v, telif h_i == 3:r, g, b = p, q, velif h_i == 4:r, g, b = t, p, velif h_i == 5:r, g, b = v, p, qreturn int(b * 255), int(g * 255), int(r * 255)def random_color(id):h_plane = (((id << 2) ^ 0x937151) % 100) / 100.0s_plane = (((id << 3) ^ 0x315793) % 100) / 100.0return hsv2bgr(h_plane, s_plane, 1)if __name__ == "__main__":model_path = 'yolov8s2.om'img_path = 'bus.jpg'img = cv2.imread(img_path)img22 = cv2.imread(img_path)# img_pre = preprocess_letterbox(img)img_pre, IM = preprocess_warpAffine(img)# model  = AutoBackend(weights="yolov8s.pt")model = InferSession(0, model_path)# names  = model.namesnames = CLASS_NAMESimg = np.ascontiguousarray(img_pre, dtype=np.float32)start = time.perf_counter()result = model.infer([img])print(np.array(result).shape) # (1, 1, 84, 8400)result = np.array(result).transpose(0, 1, 3, 2).squeeze()[np.newaxis]print(np.array(result).shape) # (1, 8400, 84)result = list(result)end = time.perf_counter()print(f'Inference FPS: {1 / (end - start)}')boxes  = postprocess(result, IM)for obj in boxes:left, top, right, bottom = int(obj[0]), int(obj[1]), int(obj[2]), int(obj[3])confidence = obj[4]label = int(obj[5])color = random_color(label)cv2.rectangle(img22, (left, top), (right, bottom), color=color ,thickness=2, lineType=cv2.LINE_AA)caption = f"{names[label]} {confidence:.2f}"print("caption:", caption)w, h = cv2.getTextSize(caption, 0, 1, 2)[0]cv2.rectangle(img22, (left - 3, top - 33), (left + w + 10, top), color, -1)cv2.putText(img22, caption, (left, top - 5), 0, 1, (0, 0, 0), 2, 16)print("img22:", img22.shape)#img22 = img22.transpose(1, 2, 0)#print("img22:", img22.shape)cv2.imwrite("infer.jpg", img22)print("save done")

输出打印:

img

保存的推理图片为:

img

可以看到精度还是很高的,并没有什么损失!

六、 总结

OrangePi AIpro是一款非常优秀的AI开发板,结合了高性能处理器和专用的AI加速硬件,算力强大,完全满足正常的视频流推理的需求,又有着非常丰富的接口,给开发者提供了一个强大且灵活的平台来用于深度学习、目标检测等AI应用的开发和部署。

同时,关于OrangePi AIpro有着非常丰富详细的资料,用户手册完全可以帮助快速使用开发板;各种开源仓库也提供了多种测试样例;此外还有论坛,用户活跃,各种问题都可以相互讨论交流,比如我在模型转换时遇到了内存不足的问题便是在论坛上找到的解决方案;社区还提供了详细的开发指南,从文本教程到视频教程,对开发者都是非常有帮助的,本次体验非常愉快!

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

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

相关文章

【已解决】使用token登录机制,token获取不到,blog_list.html界面加载不出来

Bug产生 今天使用token完成用户登录信息的存储的时候被卡了大半天。 因为登录的功能写的已经很多了&#xff0c;所以今天就没有写一点验一点&#xff0c;而是在写完获取博客列表功功能&#xff0c;验证完它的后端后&#xff0c;了解完令牌的基本使用以及Jwt的基本使用方式——…

4.共享文件夹的设置

注&#xff1a;设置共享文件夹&#xff1a;首先要先关机 一、点击 编辑虚拟机设置 二、点击 选项 选项卡 三、点击 共享文件夹 四、在本地建立一个共享文件夹后选择路径 五、Linux系统文件夹中的共享文件夹路径 六、在Linux系统中查看共享文件夹 Ubuntushare是共享文件夹&…

【简单介绍下idm有那些优势】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

国内加密软件排行榜,每一款加密软件都是精品

在数字化快速发展的今天&#xff0c;数据安全和隐私保护已成为企业和个人关注的焦点。加密软件作为保护数据安全的重要手段&#xff0c;其重要性日益凸显。以下是根据权威机构的评测和用户反馈&#xff0c;整理的国内加密软件排行榜及其特点概述。 1、加密软件安企神免费试用7天…

贷款借钱平台 小额贷款系统开发小额贷款源码 贷款平台开发搭建

这款是贷款平台源码/卡卡贷源码/小贷源码/完美版 后台51800 密码51800 数据库替换application/database.php程序采用PHPMySQL&#xff0c;thinkphp框架代码开源&#xff0c;不加密后台效果&#xff1a;手机版效果 这款是贷款平台源码/卡卡贷源码/小贷源码/完美版 后台51800 密码…

《web应用技术》第九次作业

一、将前面的代码继续完善功能 1.采用XML映射文件的形式来映射sql语句&#xff1b; <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis…

HiWoo Box工业智能网关

随着工业4.0的浪潮席卷全球&#xff0c;智能化、网络化已成为工业发展的必然趋势。在这个时代&#xff0c;工业智能网关成为了连接工业设备与网络的关键节点&#xff0c;扮演着至关重要的角色。HiWoo Box作为一款工业智能网关&#xff0c;以其卓越的性能和广泛的应用场景&#…

系统架构设计师【第3章】: 信息系统基础知识 (核心总结)

文章目录 3.1 信息系统概述3.1.1 信息系统的定义3.1.2 信息系统的发展3.1.3 信息系统的分类3.1.4 信息系统的生命周期3.1.5 信息系统建设原则3.1.6 信息系统开发方法 3.2 业务处理系统&#xff08;TPS&#xff09;3.2.1 业务处理系统的概念3.2.2 业务处理系统的功能 …

c++(六)

c&#xff08;六&#xff09; 多态概念在c中是如何实现多态静态多态&#xff08;绑定&#xff09;动态多态&#xff08;绑定&#xff09; 动态多态的实现原理动态内存分配中遇到的问题 重载、重定义、重写的区别抽象类接口类---抽象类空类对象的内存大小explicitfinal修饰类修饰…

软件游戏缺失d3dcompiler_47.dll如何解决,简单有效的五种解决方法分享

在现代游戏中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“缺少d3dcompiler47.dll文件”。这个问题通常会导致游戏无法正常运行或出现崩溃的情况。为了解决这个问题&#xff0c;我总结出了以下五种解决方法。希望这些方法能够帮助到遇到相同问题的玩家。 …

web刷题记录(1)

[GXYCTF 2019]Ping Ping Ping 进入页面&#xff0c;发现有一个传入参数的框&#xff0c;目的就是为了让我们通过参数传入内容来执行代码。这里先传入本地ip&#xff0c;方便后面的ping命令运行 ls命令来查看&#xff0c;目录中的文件 传入后&#xff0c;发现目录下有flag.php,…

倍福TwinCAT3 PLC编程软件下载安装

1、哪里下载TwinCAT3 链接: Search result | 倍福 中国https://www.beckhoff.com.cn/zh-cn/support/download-finder/search-result/?download_group=97028248下载倍福PLC编程软件需要注册,大家可以提前注册,注册好后就可以开始愉快的下载了 安装前需要注意将各杀毒软件卸…

单链表经典算法题理解

目录 1. 前言&#xff1a; 2. 移除链表元素 3. 反转链表 4. 合并两个有序链表 5. 链表的中间节点 6. 环形链表的约瑟夫问题 7. 分割链表 1. 前言&#xff1a; 当我们学习了单链表之后&#xff0c;我能可以尝试的刷一下题了&#xff0c;以下分享一下几道题的解法 2. 移…

7-zip工具?这么好用的你都能找到!

关于7-Zip&#xff0c;这不是一个神奇的小工具吗&#xff1f;让我悄悄告诉你&#xff0c;它其实是个压缩界的隐形冠军哦。 想象一下&#xff0c;你下载了一堆文件&#xff0c;电脑空间却告急&#xff0c;这时候7-Zip就像你的小助手&#xff0c;帮你把文件们“瘦身”&#xff0…

【网络运维的重要性】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

期权与股票在交易上是有什么区别吗?

国内的股票市场&#xff0c;只能做多&#xff0c;T1交易。期权则分为4个方向&#xff0c;买入看涨期权&#xff0c;买入看跌期权&#xff0c;也就是做多和做空T0双向交易&#xff0c;同时每个方向还区分不同的行权价&#xff0c;每个行权价对应的4个方向的期权&#xff0c;都有…

AI大模型日报#0529:杨红霞创业入局“端侧模型”、Ilya左膀右臂被Claude团队挖走

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE 4.0&#xff09;、“零一万物”&#xff08;Yi-34B&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xff0…

springboot+minio 文件上传

前期准备 需要先安装minio文件服务器&#xff0c;请参考我上一篇文章 pom.xml 版本 本次使用的是springboot2.7.16 版本&#xff0c; minio 版本是8.2.2 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-pare…

信息学奥赛初赛天天练-15-阅读程序-深入解析二进制原码、反码、补码,位运算技巧,以及lowbit的神奇应用

更多资源请关注纽扣编程微信公众号 1 2021 CSP-J 阅读程序1 阅读程序&#xff08;程序输入不超过数组或字符串定义的范围&#xff1b;判断题正确填 √&#xff0c;错误填&#xff1b;除特 殊说明外&#xff0c;判断题 1.5 分&#xff0c;选择题 3 分&#xff09; 源码 #in…

debian11安装留档@VirtualBox

因为debian12无法安装tpot&#xff0c;所以又把11重新安装一遍&#xff0c;以前的安装文档&#xff1a;安装Debian 11 留档-CSDN博客 下载光盘 华为云地址&#xff1a;https://repo.huaweicloud.com/debian-cd/11.0.0/amd64/iso-cd/ 使用了debian11 教育版&#xff0c;比较有…