测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)

文章目录

  • 一、任务描述
  • 二、指标分析
    • 2.1 TP/FP/FN/TN
    • 2.2 精准率
    • 2.3 召回率
  • 三、接口处理
  • 四、数据集处理
  • 五、开始计算指标
  • 五、实用工具
    • 5.1 移动文件
    • 5.2 可视化JSON标签
    • 5.3 可视化TXT标签

一、任务描述

通过给定的算法接口,对算法的输出(置信度、检测框、告警、类别等)进行数据处理,结合原标签完成TP、FP、FN、TN、准确率、召回率的指标测试。

二、指标分析

2.1 TP/FP/FN/TN

TP(True Positives,真正例):表示模型正确预测为正类的样本数量,也就是将正例正确分类为正例的数量。

FP(False Positives,假正例):表示模型错误预测为正类的样本数量,也就是将负例错误分类为正例的数量。

FN(False Negatives,假负例):表示模型错误预测为负类的样本数量,也就是将正例错误分类为负例的数量。

TN(True Negatives,真负例):表示模型正确预测为负类的样本数量,也就是将负例正确分类为负例的数量。

2.2 精准率

精准率是指模型在所有被预测为正例的样本中,真正为正例的比例。它的计算公式是:Precision = TP / (TP + FP)。精准率衡量了模型的预测中有多少是真正的正例,是一个关于假正例的指标。

2.3 召回率

召回率是指模型在所有实际正例中,成功预测为正例的比例。它的计算公式是:Recall = TP / (TP + FN)。召回率衡量了模型对于所有正例的识别能力,是一个关于假负例的指标。

三、接口处理

import os, base64, json, time, requestsdef get_all_file(path):result_list = []for root, dirs, files in os.walk(path):for file in files:if os.path.basename(file).__contains__(".jpg"):result_list.append(os.path.join(root, file))return result_listdef pic2base64(img_path):if os.path.exists(img_path):encoded_base64 = base64.b64encode(open(img_path, 'rb').read()).decode()return encoded_base64else:os.error("图片不存在,请检查图片路径:{}".format(img_path))def write_content_to_json(content, json_file_path):with open(json_file_path, 'w+', encoding='utf-8') as f:f.write(json.dumps(content, indent=4, ensure_ascii=False))if __name__ == "__main__":result = {}fish_pic_path = r"D:\datasets\test_mission\fishing_test_data"url_fish = "http://***.***.***.*:端口号/能力接口"pic_list = get_all_file(fish_pic_path)for pic in pic_list:image_base64 = pic2base64(pic)payload = {"seqid": "test1","timestamp": int(time.time()),"image": image_base64# "image": rf';base64,{image_base64}\"alt=\"\">'}res = requests.post(url_fish, json=payload)json_res = res.json()print(json_res)if 'code' in json_res and json_res['code'] == 6000:result[os.path.basename(pic)] = json_res['data']write_content_to_json(result, 'result/fish_result.json')

将所有的结果保存为JSON文档,如下:
在这里插入图片描述

四、数据集处理

数据集统一处理成:
在这里插入图片描述

数据集如果是JSON格式,通过下面的代码转换为TXT格式

import os
import numpy as np
import json
from glob import glob
import cv2
from sklearn.model_selection import train_test_split
from shutil import copyfile
import argparseobj_classes = []# Labelme坐标到YOLO V5坐标的转换
def convert(size, box):dw = 1. / (size[0])dh = 1. / (size[1])x = (box[0] + box[1]) / 2.0 - 1y = (box[2] + box[3]) / 2.0 - 1w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn (x, y, w, h)def create(yolo_labels_dir):if not os.path.exists(yolo_labels_dir):os.makedirs(yolo_labels_dir)# 样本转换
def convertToYolo5(fileList, output_dir, labelImg_path, unify_path):# 创建指定样本的父目录if not os.path.exists(output_dir):os.makedirs(output_dir)# 创建指定样本的images和labels子目录yolo_images_dir = '{}/images/'.format(output_dir)yolo_labels_dir = '{}/labels/'.format(output_dir)create(yolo_images_dir)create(yolo_labels_dir)create(unify_path)# 一个样本图片一个样本图片地转换for num,json_file_ in enumerate(fileList):# print('fileList',fileList)# 1. 生成YOLO样本图片# 构建json图片文件的全路径名imagePath = labelImg_path + '/' + json_file_ + ".jpg"print('name',imagePath, json_file_)# print('labelme_path', labelme_path)# 构建Yolo图片文件的全路径名yolo_image_file_path = yolo_images_dir + "{}.jpg".format(json_file_)print('yolo_image_file_path', yolo_image_file_path)# copy样本图片copyfile(imagePath, yolo_image_file_path)# 2. 生成YOLO样本标签# 构建json标签文件的全路径名labelme_path_ = labelImg_path.split('image')[0]json_filename = labelme_path_ + 'json'+'\\' + json_file_ + ".json"# 构建Yolo标签文件的全路径名yolo_label_file_path = yolo_labels_dir + "{}.txt".format(json_file_)txt_label_file_path = unify_path + "/{}.txt".format(json_file_)# 创建新的Yolo标签文件yolo_label_file = open(yolo_label_file_path, 'w')txt_label_file = open(txt_label_file_path, 'w')# 获取当前图片的Json标签文件json_obj = json.load(open(json_filename, "r", encoding="utf-8"))# 获取当前图片的长度、宽度信息height = json_obj['imageHeight']width = json_obj['imageWidth']# 依次读取json文件中所有目标的shapes信息for shape in json_obj["shapes"]:# 获取shape中的物体分类信息label = shape["label"]if label not in ['car_red','car_orange','car_green','car_blue','car_black','car_white','car_purple','car_grey','car_silvery','car grey','car orange','car black','car','car blue','car purple','car white','car silvery','car green','car_yellow','car red']:if label == 'Fengtain' or label == 'FengTain' or label == 'FengtTian' or label == 'Fengtian':label = 'FengTian'if (label not in obj_classes):obj_classes.append(label)# 获取shape中的物体坐标信息if (shape["shape_type"] == 'rectangle'):points = np.array(shape["points"])xmin = min(points[:, 0]) if min(points[:, 0]) > 0 else 0xmax = max(points[:, 0]) if max(points[:, 0]) > 0 else 0ymin = min(points[:, 1]) if min(points[:, 1]) > 0 else 0ymax = max(points[:, 1]) if max(points[:, 1]) > 0 else 0# 对坐标信息进行合法性检查if xmax <= xmin:passelif ymax <= ymin:passelse:# Labelme坐标转换成YOLO V5坐标bbox_labelme_float = (float(xmin), float(xmax), float(ymin), float(ymax))bbox_yolo_normalized = convert((width, height), bbox_labelme_float)# 把分类标签转换成分类idclass_id = obj_classes.index(label)# 生成YOLO V5的标签文件yolo_label_file.write(str(class_id) + " " + " ".join([str(a) for a in bbox_yolo_normalized]) + '\n')# 保存为统一的位置txt_label_file.write(str(class_id) + " " + " ".join([str(a) for a in bbox_yolo_normalized]) + '\n')yolo_label_file.close()txt_label_file.close()def check_output_directory(output=""):# 创建保存输出图片的目录save_path = output + '/'is_exists = os.path.exists(save_path)if is_exists:print('Warning: path of %s already exist, please remove it firstly by manual' % save_path)# shutil.rmtree(save_path)  # 避免误删除已有的文件return ""# print('create output path %s' % save_path)os.makedirs(save_path)return save_pathdef create_yolo_dataset_cfg(output_dir='', label_class=[]):# 创建文件data_cfg_file = open(output_dir + '/data.yaml', 'w')# 创建文件内容data_cfg_file.write('train:  ../train/images\n')data_cfg_file.write("val:    ../valid/images\n")data_cfg_file.write("test:   ../test/images\n")data_cfg_file.write("\n")data_cfg_file.write("# Classes\n")data_cfg_file.write("nc: %s\n" % len(label_class))data_cfg_file.write('names: ')i = 0for label in label_class:if (i == 0):data_cfg_file.write("[")else:data_cfg_file.write(", ")if (i % 10 == 0):data_cfg_file.write("\n        ")i += 1data_cfg_file.write("'" + label + "'")data_cfg_file.write(']  # class names')data_cfg_file.close()# 关闭文件def labelImg2yolo(input='', output='', unify_path=""):outputdir_root = output + '/'labelImg_path = inputprint(labelImg_path)labelImg_path_imagepath = labelImg_path + '\\' + 'image'print(labelImg_path_imagepath)json_path = labelImg_path+'\\'+'json'print(json_path)print("*"*100)# 1.获取input目录中所有的json标签文件全路径名files = glob(json_path + "/*.json")print(files)# 2.获取所有标签文件的短文件名称files = [i.replace("\\", "/").split("/")[-1].split(".json")[0] for i in files]print(files)# 3. 按比例随机切分数据集,获取训练集样本train_files, valid_test_files = train_test_split(files, test_size=0.2, random_state=55)# 4. 按比例随机切分数据集,获取验证集和测试集样本valid_files, test_files = train_test_split(valid_test_files, test_size=0.1, random_state=55)# 5. 构建YOLO数据集目录train_path = outputdir_root + '/train'valid_path = outputdir_root + '/valid'test_path = outputdir_root + '/test'# 6. 生成YOLO 训练、验证、测试数据集:图片+标签convertToYolo5(train_files, train_path, labelImg_path_imagepath, unify_path)convertToYolo5(valid_files, valid_path, labelImg_path_imagepath, unify_path)convertToYolo5(test_files, test_path, labelImg_path_imagepath, unify_path)print("*"*100)# 7. 创建YOLO数据集配置文件create_yolo_dataset_cfg(output, obj_classes)labelme_path = inputprint("Classes:", obj_classes)print('Finished, output path =', outputdir_root)return 0def parse_opt():# define argparse objectparser = argparse.ArgumentParser()# input 包含两个文件夹, image和json,分别存放了对应的文件parser.add_argument('--input', type=str, default=r'F:\python\mission\fish_power_test\data\test',help='The input LabelImg directory')# output 存放保存的yolov5的训练数据,分为train、val、test三个文件,里面分别存放了对应的images和labels,在train目录下还存放了yolov5加载数据集的yaml文件(见data.yaml)parser.add_argument('--output', type=str,default=r'F:\python\mission\fish_power_test\data\test/yolo_txt', help='The output YOLO V5 directory')# 统一存放parser.add_argument('--unify_path', type=str,default=r'F:\python\mission\fish_power_test\data\test/txt', help='The output txt directory')# parse arges from command lineopt = parser.parse_args()print("input  =", opt.input)print("output =", opt.output)print("unify_path =", opt.unify_path)# return optreturn optdef main(opt):labelImg2yolo(**vars(opt))if __name__ == '__main__':opt = parse_opt()main(opt)

然后通过下面的代码将源标签的txt文档进行总结

# 将txt标签对应的原始的label和boxs写入到txt文档中
import cv2
import os# 读取txt文件信息
def read_list(txt_path):pos = []with open(txt_path, 'r') as file_to_read:while True:lines = file_to_read.readline()  # 整行读取数据if not lines:break# 将整行数据分割处理,如果分割符是空格,括号里就不用传入参数,如果是逗号, 则传入‘,'字符。p_tmp = [float(i) for i in lines.split(' ')]pos.append(p_tmp)  # 添加新读取的数据passreturn posdef draw_box_in_single_image(image_path, txt_path, image_name):# 读取图像image = cv2.imread(image_path)pos = read_list(txt_path)reses = []reses.append(image_name)for i in range(len(pos)):label = classes[int(str(int(pos[i][0])))]print('label is '+label)# 将中心坐标、宽度和高度转换为 xywh 格式x_center = int(pos[i][1] * image.shape[1])y_center = int(pos[i][2] * image.shape[0])width = int(pos[i][3] * image.shape[1])height = int(pos[i][4] * image.shape[0])x_min = x_center - width // 2y_min = y_center - height // 2# 绘制矩形框cv2.rectangle(image, (x_min, y_min), (x_min + width, y_min + height), colores[int(str(int(pos[i][0])))], 2)cv2.putText(image, label, (x_min, y_min - 2), 0, 1, colores[int(str(int(pos[i][0])))], thickness=2, lineType=cv2.LINE_AA)res = [label, x_min, y_min, width, height]reses.append(res)# cv2.imshow("images", image)# cv2.waitKey(0)return resesif __name__ == '__main__':f =  open('result/ori_data.txt', 'w+')img_folder = "data/test/image"img_list = [f for f in os.listdir(img_folder) if f.endswith('.jpg')]img_list.sort()label_folder =  "data/test/txt"label_list = [f for f in os.listdir(label_folder) if f.endswith('.txt')]label_list.sort()classes = {0: "fishing", 1: "no_fishing"}colores = [(0, 0, 255), (255, 0, 255)]for i in range(len(img_list)):image_path = os.path.join(img_folder, img_list[i])txt_path = os.path.join(label_folder, label_list[i])reses = draw_box_in_single_image(image_path, txt_path, img_list[i])print(reses)f.write(str(reses))f.write("\n")f.close()

五、开始计算指标

处理之后就可以得到检测后的fish_result.json和ori_data.txt。然后根据这两个文件来计算即可。

部分重要代码放在这里面:链接
在这里插入图片描述

五、实用工具

5.1 移动文件

import os
import shutil# 源文件夹和目标文件夹的路径
source_folder = 'fishing_test_data'
destination_folder = 'test/image'# 确保目标文件夹存在,如果不存在就创建它
if not os.path.exists(destination_folder):os.makedirs(destination_folder)# 遍历源文件夹中的文件
for filename in os.listdir(source_folder):# 检查文件扩展名是否为图片格式,可以根据需要添加其他格式if filename.endswith(('.jpg', '.png', '.jpeg')):# 构建源文件的完整路径和目标文件的完整路径source_file_path = os.path.join(source_folder, filename)destination_file_path = os.path.join(destination_folder, filename)# 移动文件shutil.move(source_file_path, destination_file_path)print(f'Moved: {filename} to {destination_folder}')

5.2 可视化JSON标签

# -*- coding: utf-8 -*-
import cv2
import os
import json
import shutil
import numpy as np
from pathlib import Path
from glob import globid2cls = {0: 'fishing', 1: "no_fishing"}
cls2id = {'fishing': 0,  "no_fishing": 1}
id2color = {"fishing": (0, 255, 0), "no_fishing": (0, 255, 255)}# 支持中文路径
def cv_imread(filePath):cv_img = cv2.imdecode(np.fromfile(filePath, dtype=np.uint8), flags=cv2.IMREAD_COLOR)return cv_imgdef get_labelme_info(label_file):anno = json.load(open(label_file, "r", encoding="utf-8"))shapes = anno['shapes']image_path = os.path.basename(anno['imagePath'])labels = []for s in shapes:pts = s['points']x1, y1 = pts[0]x2, y2 = pts[1]color = id2color[s["label"]]labels.append([color, x1, y1, x2, y2])return labels, image_pathdef vis_labelme(labelme_label_dir, save_dir='res/'):labelme_label_dir = str(Path(labelme_label_dir)) + '/'save_dir = str(Path(save_dir)) + '/'if not os.path.exists(save_dir):os.makedirs(save_dir)json_files = glob(labelme_label_dir + '*.json')for ijf, jf in enumerate(json_files):print(ijf + 1, '/', len(json_files), jf)filename = os.path.basename(jf).rsplit('.', 1)[0]labels, image_path = get_labelme_info(jf)image = cv_imread(labelme_label_dir + image_path)for label in labels:color = label[0]x1, y1, x2, y2 = label[1:]x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)cv2.rectangle(image, (x1, y1), (x2, y2), color, 3)# 显示图片# cv2.imshow(filename, image)# cv2.waitKey(0)# 支持中文路径,保存图片cv2.imencode(os.path.splitext(image_path)[-1], image)[1].tofile(save_dir + image_path)print('Completed!')if __name__ == '__main__':root_dir = r'D:\Python\money\data\test'save_dir = r'D:\Python\money\data\test/t'vis_labelme(root_dir, save_dir)

5.3 可视化TXT标签

import cv2
import os# 读取txt文件信息
def read_list(txt_path):pos = []with open(txt_path, 'r') as file_to_read:while True:lines = file_to_read.readline()  # 整行读取数据if not lines:break# 将整行数据分割处理,如果分割符是空格,括号里就不用传入参数,如果是逗号, 则传入‘,'字符。p_tmp = [float(i) for i in lines.split(' ')]pos.append(p_tmp)  # 添加新读取的数据# Efield.append(E_tmp)passreturn pos# txt转换为box
def convert(size, box):xmin = (box[1] - box[3] / 2.) * size[1]xmax = (box[1] + box[3] / 2.) * size[1]ymin = (box[2] - box[4] / 2.) * size[0]ymax = (box[2] + box[4] / 2.) * size[0]box = (int(xmin), int(ymin), int(xmax), int(ymax))return boxdef draw_box_in_single_image(image_path, txt_path):# 读取图像image = cv2.imread(image_path)pos = read_list(txt_path)for i in range(len(pos)):label = classes[int(str(int(pos[i][0])))]print('label is '+label)box = convert(image.shape, pos[i])image = cv2.rectangle(image,(box[0], box[1]),(box[2],box[3]),colores[int(str(int(pos[i][0])))],2)cv2.putText(image, label,(box[0],box[1]-2), 0, 1, colores[int(str(int(pos[i][0])))], thickness=2, lineType=cv2.LINE_AA)cv2.imshow("images", image)cv2.waitKey(0)if __name__ == '__main__':img_folder = r"F:\python\mission\fish_power_test\data\test\yolo_txt\train\images"img_list = os.listdir(img_folder)img_list.sort()label_folder = r"F:\python\mission\fish_power_test\data\test\yolo_txt\train/labels"label_list = os.listdir(label_folder)label_list.sort()classes = {0: "fishing", 1: "no_fishing"}colores = [(0,0,255),(255,0,255)]for i in range(len(img_list)):image_path = img_folder + "\\" + img_list[i]txt_path = label_folder + "\\" + label_list[i]draw_box_in_single_image(image_path, txt_path)

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

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

相关文章

英飞凌 Tricore 架构中断系统详解

本文以TC3系列MCU为例&#xff0c;先来了解中断源是如何产生的&#xff0c;再看一下CPU是如何处理中断源的。 AURIX TC3XX的中断路由模块 Interrupt Router (IR) 在TC3中&#xff0c;中断既可以被CPU处理&#xff0c;也可以被DMA处理&#xff0c;所以手册中不再把中断称为中断…

Apache Commons Pool2 池化技术

对象池是一种设计模式&#xff0c;用于管理和重用对象&#xff0c;以提高性能和资源利用率。对象池的概念在许多应用程序中都有广泛应用&#xff0c;特别是在需要频繁创建和销毁对象的情况下&#xff0c;例如数据库连接、线程、HTTP连接等 对象池通过预先创建一组对象并将它们存…

【数据结构篇】堆

文章目录 堆前言基本介绍认识堆堆的特点堆的分类堆的操作堆的常见应用 堆的实现JDK 自带的堆手动实现堆 堆 前言 本文主要是对堆的一个简单介绍&#xff0c;如果你是刚学数据结构的话&#xff0c;十分推荐看这篇文章&#xff0c;通过本文你将对堆这个数据结构有一个大致的了解…

阿里云ACP知识点(三)

1、弹性伸缩不仅提供了在业务需求高峰或低谷时自动调节ECS实例数量的能力&#xff0c;而且提供了ECS实例上自动部署应用的能力。弹性伸缩的伸缩配置支持多种特性&#xff0c;例如______,帮助您高效、灵活地自定义ECS实例配置&#xff0c;满足业务需求。 标签、密钥对、 实例RAM…

大学各个专业介绍

计算机类 五米高考-计算机类 注&#xff1a;此处平均薪酬为毕业五年平均薪酬&#xff0c;薪酬数据仅供参考 来源&#xff1a; 掌上高考 电气类 五米高考-电气类 机械类 五米高考-机械类 电子信息类 五米高考-电子信息类 土木类 五米高考-土木类

从零手搓一个【消息队列】实现数据的硬盘管理和内存管理(线程安全)

文章目录 一、硬盘管理1, 创建 DiskDataCenter 类2, init() 初始化3, 封装交换机4, 封装队列5, 关于绑定6, 关于消息 二、内存管理1, 数据结构的设计2, 创建 MemoryDataCenter 类3, 关于交换机4, 关于队列5, 关于绑定6, 关于消息7, 恢复数据 三、小结 创建 Spring Boot 项目, S…

26 docker前后端部署

[参考博客]((257条消息) DockerNginx部署前后端分离项目(SpringBootVue)的详细教程_在docker中安装nginx实现前后端分离_这里是杨杨吖的博客-CSDN博客) (DockerNginx部署前后端分离项目(SpringBootVue)) 安装docker # 1、yum 包更新到最新 yum update # 2、安装需要的软件包…

SEO的优化教程(百度SEO的介绍和优化)

百度SEO关键字介绍&#xff1a; 百度SEO关键字是指用户在搜索引擎上输入的词语&#xff0c;是搜索引擎了解网站内容和相关性的重要因素。百度SEO关键字可以分为短尾词、中尾词和长尾词&#xff0c;其中长尾词更具有针对性和精准性&#xff0c;更易于获得高质量的流量。蘑菇号-…

构建一个TypeScript环境的node项目

本文 我们用一种不太一样的方式来创建项目 这里 我们事先创建了一个文件夹作为项目目录 然后打开项目终端 输入 npm init然后 在新弹出的对话框中 大体就是 名字随便写一个 然后 后面的回车&#xff0c;到最后一个输入 yes 然后回车 这样 我们就有一个基础的 node项目结构了…

AGV小车、机械臂协同作业实战06-任务分配算法(图解蚁群算法)代码示例java

什么是蚁群算法&#xff1f; 蚁群系统(Ant System(AS)或Ant Colony System(ACS))是由意大利学者Dorigo、Maniezzo等人于20世纪90年代首先提出来的。他们在研究蚂蚁觅食的过程中&#xff0c;发现蚁群整体会体现一些智能的行为&#xff0c;例如蚁群可以在不同的环境下&#xff0c…

排序篇(四)----归并排序

排序篇(四)----归并排序 1.归并(递归) 基本思想&#xff1a; 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide andConquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到…

Hive SQL初级练习(30题)

前言 Hive 的重要性不必多说&#xff0c;离线批处理的王者&#xff0c;Hive 用来做数据分析&#xff0c;SQL 基础必须十分牢固。 环境准备 建表语句 这里建4张表&#xff0c;下面的练习题都用这些数据。 -- 创建学生表 create table if not exists student_info(stu_id st…

yolov5分割+检测c++ qt 中部署,以opencv方式(详细代码(全)+复制可用)

1&#xff1a;版本说明&#xff1a; qt 5.12.10 opencv 4.5.3 &#xff08;yolov5模型部署要求opencv>4.5.0&#xff09; 2&#xff1a;检测的代码 yolo.h #pragma once #include<iostream> #include<cmath> #include<vector> #include <opencv2/…

毅速课堂:3D打印随形水路在小零件注塑中优势明显

小零件注塑中的冷却不均匀问题常常导致烧焦现象的发生。这主要是因为传统机加工方法无法制造出足够细小的水路&#xff0c;以适应小零件的复杂形状。而3D打印技术的引入&#xff0c;尤其是随形水路的设计&#xff0c;为解决这一问题提供了新的解决方案。 3D打印随形水路技术的优…

TS编译选项——编译TS文件同时对JS文件进行编译

一、允许对JS文件进行编译 我们在默认情况下编译TS项目时是不能编译js文件的&#xff0c;如下图中的hello.js文件并未编译到dist目录下&#xff08;这里配置了编译文件放到dist目录下&#xff09; 如果我们想要实现编译TS文件同时对JS文件进行编译&#xff0c;就需要在tsconfi…

使用U3D、pico开发VR(二)——添加手柄摇杆控制移动

一、将unity 与visual studio 相关联 1.Edit->Preference->External tool 选择相应的版本 二、手柄遥控人物转向和人物移动 1.添加Locomotion System组件 选择XR Origin&#xff1b; 2.添加Continuous Move Provider&#xff08;Action-based&#xff09;组件 1>…

编程每日一练(多语言实现)基础篇:求总数问题

文章目录 一、实例描述二、技术要点三、代码实现3.1 C 语言实现3.2 Python 语言实现3.3 Java 语言实现3.4 JavaScript 语言实现 一、实例描述 集邮爱好者把所有的邮票存放在三个集邮册中&#xff0c;在A册内存放全部的十分之二&#xff0c;在B册内存放不知道是全部的七分之几&…

MyBatis的一级缓存和二级缓存:原理和作用

MyBatis的一级缓存和二级缓存&#xff1a;原理和作用 引言 在数据库访问中&#xff0c;缓存是一种重要的性能优化手段&#xff0c;它可以减少数据库查询的次数&#xff0c;加快数据访问速度。MyBatis作为一款流行的Java持久层框架&#xff0c;提供了一级缓存和二级缓存来帮助…

基于Java的大学生就业招聘系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

【数据结构】排序算法(一)—>插入排序、希尔排序、选择排序、堆排序

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.直接插入排序 2.希尔排序 3.直接选择排…