【YOLOv8系列】(四)YOLOv8使用自己的数据集进行模型训练,成就感满满

news2024/11/11 23:06:30

目录

一.数据集获取

1.使用开源数据集

2.自定义数据图片

二.数据集标注

1.标注工具介绍

2.labelme安装

3.数据标注

1.选择要标注的数据集文件夹

2.设置自动保存:

3.创建多边形标注

4.格式转换

1.安装labelme2yolo 

2.格式转换

3.效果查看

4.其他格式转换 

5.划分数据集

三.模型训练

1.模型训练

2.参数解读

1.训练参数

2.结果参数

3.模型验证

四.总结 


随着YOLO(You Only Look Once)系列的不断进化,YOLOv8以其显著的精度提升和优化的架构设计,再次吸引了众多研究者和开发者的眼球。在本系列的第四篇文章中,我们将深入探讨如何在自定义数据集上训练YOLOv8模型,让你从零开始掌握目标检测的实战技能。

本系列其他文章

【YOLOv8系列】(一)YOLOv8介绍:实时目标检测的最新突破-CSDN博客

【YOLOv8系列】(二)YOLOv8环境配置,手把手嘴对嘴保姆教学-CSDN博客

【YOLOv8系列】(三)YOLOv8应用实践:从识别到分类再到分割的全方位视觉解决方案-CSDN博客

一.数据集获取

在机器学习和深度学习中,数据集是训练模型的基础。尤其在计算机视觉领域,数据集的重要性更为突出。以下是获取数据集的几个途径:

1.使用开源数据集

有许多公开的目标检测数据集可供使用。以下是一些常见的数据集:

  • COCO (Common Objects in Context):一个大规模的图像数据集,包含80种类别的物体。可以从 COCO官网 下载。
  • Pascal VOC:一个经典的目标检测数据集,包含20种类别的物体。可以从Pascal VOC官网 下载。
  • Open Images:一个包含约900万张图像和600种类别的物体数据集。可以从 Open Images官网下载。

  • ModelScope :魔搭社区

2.自定义数据图片

通过爬虫程序批量下载网络上的图片数据集,或者使用相机或其他来源收集您需要的图片

二.数据集标注

数据标注是通过人工把需要识别和分辨的数据贴上标签。深度神经网络学习这些标注数据的特征,最终实现自主识别的功能。

1.标注工具介绍

使用标注工具对图片中的目标进行标注。常用的标注工具包括:

  • LabelImg:一个开源的图像标注工具,支持VOC和YOLO格式。可以从 LabelImg官网 下载。
  • LabelMe:一个在线的图像标注工具,支持多种标注格式。可以从 LabelMe官网 使用。
  • Roboflow:一个在线平台,提供数据集管理和标注工具。可以从 Roboflow官网 使用。

2.labelme安装

我个人比较推荐使用labelme,因为可以进行多边形标注。

pip安装

pip install labelme

终端输入labelme打开软件

labelme

 界面如下所示

3.数据标注

1.选择要标注的数据集文件夹

2.设置自动保存:

文件—>自动保存

3.创建多边形标注

标注的数据会自动保存

4.格式转换

将标注文件转换为YOLO格式。YOLO格式的标注文件内容如下:

<class_id> <x_center> <y_center> <width> <height>

但我们标注好的json数据格式是这样的,需要将json格式转换成需要的txt

1.安装labelme2yolo 

pip install labelme2yolo

2.格式转换

labelme2yolo --json_dir /path/to/labelme_json_dir/ # 将所有 LabelMe JSON 文件放在 labelme_json_dir 下

--json_dirLabelMe JSON 文件文件夹路径。

--val_size(可选)验证数据集大小,例如 0.2 表示 20% 用于验证。

--test_size(可选)测试数据集大小,例如 0.1 表示 Test 的 10%。

--json_name(可选)转换单个LabelMe JSON文件。

--output_format(可选)标签的输出格式。

--label_list(可选)预先分配的类别标签。

3.效果查看

运行后会出现一个名为YOLODataset的文件夹

 项目结构如下所示:

YOLODataset/
├── images/
│   ├── train/
│   ├── val/
├── labels/
│   ├── train/
│   ├── val/
├── dataset.yaml

yaml文件如下 

转换后的txt文件如下

可以看到,除了格式转换,labelme2yolo模块已经帮我们划分好了数据集以及验证集并生成好了yaml文件。一劳永逸,灰常好用!!!!!

4.其他格式转换 

除了json文件,最常见的就是voc格式的xml文件,例如安全帽检测数据集。以下脚本可以将xml转成txt文件。

import xml.etree.ElementTree as ET
import os
 
 
def convert(size, box):
    x_center = (box[0] + box[1]) / 2.0
    y_center = (box[2] + box[3]) / 2.0
    #分别计算纵坐标和横坐标的中心点
    x = x_center / size[0]
    y = y_center / size[1]
 
    w = (box[1] - box[0]) / size[0]
    h = (box[3] - box[2]) / size[1]
 
    # print(x, y, w, h)
    return (x, y, w, h)
 
 
def convert_annotation(xml_files_path, save_txt_files_path, classes):
    xml_files = os.listdir(xml_files_path)
    print(xml_files)
    for xml_name in xml_files:
        print(xml_name)
        xml_file = os.path.join(xml_files_path, xml_name)
        out_txt_path = os.path.join(save_txt_files_path, xml_name.split('.')[0] + '.txt')
        out_txt_f = open(out_txt_path, 'w')
        tree = ET.parse(xml_file)
        root = tree.getroot()
        size = root.find('size')
        w = int(size.find('width').text)
        h = int(size.find('height').text)
 
        for obj in root.iter('object'):
            difficult = obj.find('difficult').text
            cls = obj.find('name').text
            if cls not in classes or int(difficult) == 1:
                continue
            cls_id = classes.index(cls)
            xmlbox = obj.find('bndbox')
            b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
                 float(xmlbox.find('ymax').text))
            # b=(xmin, xmax, ymin, ymax)
            print(w, h, b)
            bb = convert((w, h), b)
            out_txt_f.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
 
 
if __name__ == "__main__":
    # 1、指定yolo类别
    classes1 = ["class1","class2","class3"]
    # 2、voc格式的xml标签文件路径
    xml_files1 = r'/path/to/your/xml/folder'
    # 3、转化为yolo格式的txt标签文件存储路径
    save_txt_files1 = r'/path/to/your/txt/save/folder'
 
    convert_annotation(xml_files1, save_txt_files1, classes1)
    with open(save_txt_files1 + '/classes.txt', 'w') as file:
        for class_name in classes1:
            file.write(class_name + '\n')
 

5.划分数据集

如果你是通过labelme按照以上步骤标注自己数据集,这一步可以跳过。但如果是下载的公开已标注好的数据集,那么需要通过脚本进行数据集的划分。

import os
import random
import shutil
import time
import yaml
 
 
 
class YOLOTrainDataSetGenerator:
    def __init__(self, origin_dataset_dir, train_dataset_dir, train_ratio=0.7, val_ratio=0.15, test_ratio=0.15,
                 clear_train_dir=False):
        # 设置随机数种子
        random.seed(1233)
 
        self.origin_dataset_dir = origin_dataset_dir
        self.train_dataset_dir = train_dataset_dir
        self.train_ratio = train_ratio
        self.val_ratio = val_ratio
        self.test_ratio = test_ratio
        self.clear_train_dir = clear_train_dir
 
        assert self.train_ratio > 0.5, 'train_ratio must larger than 0.5'
        assert self.val_ratio > 0.01, 'train_ratio must larger than 0.01'
        assert self.test_ratio > 0.01, 'test_ratio must larger than 0.01'
        total_ratio = round(self.train_ratio + self.val_ratio + self.test_ratio)
        assert total_ratio == 1.0, 'train_ratio + val_ratio + test_ratio must equal 1.0'
 
    def generate(self):
        time_start = time.time()
        # 原始数据集的图像目录,标签目录,和类别文件路径
        origin_image_dir = os.path.join(self.origin_dataset_dir, 'images')
        origin_label_dir = os.path.join(self.origin_dataset_dir, 'labels')
        origin_classes_file = os.path.join(self.origin_dataset_dir, 'classes.txt')
        if not os.path.exists(origin_classes_file):
            return
        else:
            origin_classes = {}
            with open(origin_classes_file, mode='r') as f:
                for cls_id, cls_name in enumerate(f.readlines()):
                    cls_name = cls_name.strip()
                    if cls_name != '':
                        origin_classes[cls_id] = cls_name
 
        # 获取所有原始图像文件名(包括后缀名)
        origin_image_filenames = os.listdir(origin_image_dir)
 
        # 随机打乱文件名列表
        random.shuffle(origin_image_filenames)
 
        # 计算训练集、验证集和测试集的数量
        total_count = len(origin_image_filenames)
        train_count = int(total_count * self.train_ratio)
        val_count = int(total_count * self.val_ratio)
        test_count = total_count - train_count - val_count
 
        # 定义训练集文件夹路径
        if self.clear_train_dir and os.path.exists(self.train_dataset_dir):
            shutil.rmtree(self.train_dataset_dir, ignore_errors=True)
        train_dir = os.path.join(self.train_dataset_dir, 'train')
        val_dir = os.path.join(self.train_dataset_dir, 'val')
        test_dir = os.path.join(self.train_dataset_dir, 'test')
        train_image_dir = os.path.join(train_dir, 'images')
        train_label_dir = os.path.join(train_dir, 'labels')
        val_image_dir = os.path.join(val_dir, 'images')
        val_label_dir = os.path.join(val_dir, 'labels')
        test_image_dir = os.path.join(test_dir, 'images')
        test_label_dir = os.path.join(test_dir, 'labels')
 
        # 创建训练集输出文件夹
        os.makedirs(train_image_dir, exist_ok=True)
        os.makedirs(train_label_dir, exist_ok=True)
        os.makedirs(val_image_dir, exist_ok=True)
        os.makedirs(val_label_dir, exist_ok=True)
        os.makedirs(test_image_dir, exist_ok=True)
        os.makedirs(test_label_dir, exist_ok=True)
 
        # 将图像和标签文件按设定的ratio划分到训练集,验证集,测试集中
        for i, filename in enumerate(origin_image_filenames):
            if i < train_count:
                output_image_dir = train_image_dir
                output_label_dir = train_label_dir
            elif i < train_count + val_count:
                output_image_dir = val_image_dir
                output_label_dir = val_label_dir
            else:
                output_image_dir = test_image_dir
                output_label_dir = test_label_dir
            src_img_name_no_ext = os.path.splitext(filename)[0]
            src_image_path = os.path.join(origin_image_dir, filename)
            src_label_path = os.path.join(origin_label_dir, src_img_name_no_ext + '.txt')
            if os.path.exists(src_label_path):
                # 复制图像文件
                dst_image_path = os.path.join(output_image_dir, filename)
                shutil.copy(src_image_path, dst_image_path)
                # 复制标签文件
                src_label_path = os.path.join(origin_label_dir, src_img_name_no_ext + '.txt')
                dst_label_path = os.path.join(output_label_dir, src_img_name_no_ext + '.txt')
                shutil.copy(src_label_path, dst_label_path)
            else:
                pass
        train_dir = os.path.normpath(train_dir)
        val_dir = os.path.normpath(val_dir)
        test_dir = os.path.normpath(test_dir)
        data_dict = {
            'train': train_dir,
            'val': val_dir,
            'test': test_dir,
            'nc': len(origin_classes),
            'names': origin_classes
        }
 
        yaml_file_path = os.path.normpath(os.path.join(self.train_dataset_dir, 'data.yaml'))
        with open(yaml_file_path, mode='w') as f:
            yaml.safe_dump(data_dict, f, default_flow_style=False, allow_unicode=True)
    
 
if __name__ == '__main__':
    g_origin_dataset_dir = '原始数据集'
    g_train_dataset_dir = '生成的文件地址'
    g_train_ratio = 0.7
    g_val_ratio = 0.15
    g_test_ratio = 0.15
    yolo_generator = YOLOTrainDataSetGenerator(g_origin_dataset_dir, g_train_dataset_dir, g_train_ratio, g_val_ratio,
                                               g_test_ratio, True)
    yolo_generator.generate()

原始YOLO数据集:images包含被标注的图像,labels包含对应图像的标注文件,classes.txt包含标注的类别。

生成用于YOLOv8训练用的数据集,如下图所示:

三.模型训练

当以上步骤都完成后就可以开始漫长的模型训练过程了。

1.模型训练

#coding:utf-8
from ultralytics import YOLO
# 加载预训练模型
model = YOLO("./model/yolov8n.pt")
# Use the model
if __name__ == '__main__':
    # Use the model
    results = model.train(data='dataset.yaml', epochs=300, batch=4)  # 训练模型

 训练ing~~~

如果训练出现意外中断,例如说电脑爆炸,世界末日之类的,可以使用下面命令或python代码恢复训练

# Resume an interrupted training
yolo train resume model=path/to/last.pt
from ultralytics import YOLO

# Load a model
model = YOLO("path/to/last.pt")  # load a partially trained model

# Resume training
results = model.train(resume=True)

2.参数解读

1.训练参数

  • Epoch:训练过程中的迭代次数
  • GPU_mem:GPU内存使用情况,通常是以MB或GB为单位的数字
  • box_loss:模型预测的边界框与真实边界框之间的平均损失值
  • cls_loss:模型预测的对象类别与真实类别之间的平均损失值
  • dfl_loss:分布式焦距损失,用于提高边界框回归的精度
  • Instances:检测任务中每个图像包含的目标实例
  • Size:输入模型的图像的大小,通常是以像素为单位的宽度和高度。
  • Class:检测的目标类别
  • Images:测试集中包含该类别的图像数量
  • Box(P:该类别的预测精确度(precision),即正确预测的物体数量占所有预测的物体数量的比例
  • R:该类别的召回率(recall),即正确预测的物体数量占所有真实物体数量的比例
  • mAP50:在 50% IoU(Intersection over Union)阈值下的平均精度(mean Average Precision)
  • mAP50-95):在 IoU 阈值从 0.50 到 0.95(步长为 0.05)的范围内,逐步计算的平均精度的平均值

2.结果参数

Yolov8在训练完成之后,会在runs/detect/train目录下把训练的过程一些参数与结果示意图保存下来,这里面包含是目标检测性能指标。

  • weights:包含best.pt以及last.pt,分布代表模型损失最低的结果以及最后一次训练完成后的结果
  • args.yaml:训练时的保存的超参数
  • 混淆矩阵(confusion_matrix):

                其中:

                        True Positive (TP):预测为正类且实际为正类的样本数。

                        False Positive (FP):预测为正类但实际为负类的样本数(误报)。

                        False Negative (FN):预测为负类但实际为正类的样本数(漏报)。

                        True Negative (TN):预测为负类且实际为负类的样本数。        

  •  混淆矩阵归一化(confusion_matrix_normalized):将每个单元格的值除以该类别实际样本数,从而得到表示分类准确率的百分比

  • F1曲线(F1_curve): 指在不同阈值下计算的 F1 分数与阈值之间的关系曲线。

  • labels :代表每个检测到的目标的类别和边界框信息。

                从左往右,从上到下按顺序排列:

                1.训练集的数据量,显示每个类别包含的样本数量

                2.框的尺寸和数量,展示了训练集中边界框的大小分布以及相应数量

                3.中心点相对于整幅图的位置,描述了边界框中心点在图像中的位置分布情况

                4.图中目标相对于整幅图的高宽比例,反映了训练集中目标高宽比例的分布状况

  • labels_correlogram:展示了在训练过程中对标签之间相关性的建模情况。每个矩阵单元代表模型训练时使用的标签,而单元格的颜色深浅反映了对应标签之间的相关性。 

  • P_curve: 关于的是PrecisionConfidence之间的关系。

  • PR_curve :关于的是PrecisionRecall之间的关系

  • R_curve :召回率曲线。在目标检测中,召回率是衡量模型检测到所有正样本中有多少被正确检测出来的指标。

  • results.csv :模型训练时每次迭代结果,记录了一些我们训练过程中的参数信息,包括损失和学习率等。

  • results :

        损失函数在目标检测任务中扮演关键角色,它用于衡量模型的预测值与真实值之间的差异,直接影响模型性能。以下是一些与目标检测相关的损失函数和性能评价指标的解释:

        1. 定位损失(box_loss):

                定义: 衡量预测框与标注框之间的误差,通常使用 GIoU(Generalized Intersection over Union)来度量,其值越小表示定位越准确。
                目的: 通过最小化定位损失,使模型能够准确地定位目标。
        2. 置信度损失(obj_loss):

                定义: 计算网络对目标的置信度,通常使用二元交叉熵损失函数,其值越小表示模型判断目标的能力越准确。
                目的: 通过最小化置信度损失,使模型能够准确判断目标是否存在。
        3. 分类损失(cls_loss):

                定义: 计算锚框对应的分类是否正确,通常使用交叉熵损失函数,其值越小表示分类越准确。
                目的: 通过最小化分类损失,使模型能够准确分类目标。
        4. Precision(精度):

                定义: 正确预测为正类别的样本数量占所有预测为正类别的样本数量的比例。
                目的: 衡量模型在所有预测为正例的样本中有多少是正确的。
        5. Recall(召回率):

                定义: 正确预测为正类别的样本数量占所有真实正类别的样本数量的比例。
                目的: 衡量模型能够找出真实正例的能力。
        6. mAP(平均精度):

                定义: 使用 Precision-Recall 曲线计算的面积,mAP@[.5:.95] 表示在不同 IoU 阈值下的平均 mAP。
                目的: 综合考虑了模型在不同精度和召回率条件下的性能,是目标检测任务中常用的评价指标。

        在训练过程中,通常需要关注精度和召回率的波动情况,以及 mAP50 mAP50-95) 评估训练结果。这些指标可以提供关于模型性能和泛化能力的有用信息。 

3.模型验证

当模型训练完成,我们使用以下命令行预测

yolo task=detect mode=predict model=best.pt source=YOLODataset/images/val

结果如下所示:

置信度都在90左右,效果还是蛮不错的!!! 

四.总结 

本文详细介绍了如何利用YOLOv8模型进行目标检测任务的训练过程,包括数据集获取、数据集标注、模型训练、以及最终的部署和应用。通过本文的指导,读者可以快速掌握训练YOLOv8模型的关键步骤,并在实际项目中应用和优化模型。

如果以上内容对您有帮助,可以三连打赏订阅本专栏哦, 谢谢~

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

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

相关文章

腾讯开源 tlbs-map 地图组件库

腾讯宣布开源 tlbs-map&#xff0c;一个基于腾讯位置服务地图 API 开发的 web 端地图组件库&#xff0c;支持在网页绘制地图并在地图上绘制点、线、面、热力图等效果&#xff0c;支持 Vue2、Vue3、React 等业界主流技术栈&#xff0c;旨在帮助开发者低成本开发地图业务 Javascr…

大模型LLM 应用私有化部署项目

LLM 参数包含数十亿甚至万亿级的架构复杂&#xff0c;训练和推理涉及大量计算资源。企业客户训练资料少&#xff0c;在实际应用中可能表现出检索幻觉、精准度差&#xff0c;同时也带来了性能、安全性和效率等方面的挑战。 ChatGPT、LLaMa、Bard 等大语言模型(LLMs)取得了非常巨…

【前端】零基础学会编写CSS

一、什么是CSS CSS (Cascading Style Sheets&#xff0c;层叠样式表&#xff09;是一种是一种用来为结构化文档&#xff08;如 HTML 文档&#xff09;添加样式&#xff08;字体、间距和颜色等&#xff09;的计算机语言&#xff0c;能够对网页中元素位置的排版进行像素级别的精…

论文解读--4D mmWave Radar for Autonomous Driving Perception:A Comprehensive Survey

用于自动驾驶感知的4D毫米波雷达&#xff1a;综合综述 摘要 自动驾驶技术的快速发展推动了感知系统的不断创新&#xff0c;其中4D毫米波&#xff08;mmWave&#xff09;雷达是关键的传感设备之一。利用其全天候操作特性和在具有挑战性的环境中的强大感知能力&#xff0c;4D毫米…

keil5新建stm32工程的基本

1、建立工程文件夹&#xff0c;keil中新建工程&#xff0c;选择型号&#xff1b; 2、工程文件夹里建立自己所需要的文件夹等&#xff0c;复制固件库里面的文件到工程文件夹里&#xff1b; 3、将工程里建立对应的同名的分组&#xff0c;并将文件夹内的文件添加到工程分组中。 点…

buuctf_RE(第三页)

[SWPU2019]ReverseMe 找到关键函数&#xff0c;但是很长&#xff0c;也只能分析出一些零碎的东西&#xff0c;看 wp 是通过动调来缕清程序的逻辑的。 一个是用ida&#xff0c;还有一个OD都试试吧 还看到一个大佬是用的 ponce 解的&#xff0c;这个先放放。 调的太难受了 0.0 还…

未来互联网的新篇章:深度解析Facebook的技术与战略

随着科技的飞速发展和社会的不断变迁&#xff0c;互联网作为全球信息交流的重要平台&#xff0c;正经历着前所未有的变革和演进。作为全球最大的社交媒体平台之一&#xff0c;Facebook不仅是人们沟通、分享和互动的重要场所&#xff0c;更是科技创新和数字化进程的推动者。本文…

什么是独立成分分析(ICA, Independent Component Analysis)

**独立成分分析&#xff08;ICA, Independent Component Analysis&#xff09;**是一种用于信号处理的统计技术&#xff0c;旨在将多变量信号分解为统计独立的非高斯信号成分。ICA广泛应用于各类信号处理领域&#xff0c;如脑电图&#xff08;EEG&#xff09;、语音信号处理、图…

概率论习题

泊松分布习题 假设你在医院值班&#xff0c;每天需要安保人员出动的次数N~P(1),则关于任一天安保人员出动次数&#xff1a; A&#xff1a;出动一次的概率是多少 B&#xff1a;出动次数小于等于一次的概率为 C&#xff1a;出动次数小于一次的概率为 D&#xff1a;若随机事件发生…

Python Cleanlab库:提升机器学习数据质量

更多Python学习内容&#xff1a;ipengtao.com 在机器学习和数据科学中&#xff0c;数据质量对模型的性能和可靠性有着至关重要的影响。清洗和纠正标签错误的数据是确保模型准确性和泛化能力的关键步骤。Python的Cleanlab库提供了一种便捷且强大的方式来检测和纠正数据中的标签错…

数列分块<1>

本期是数列分块入门<1>。该系列的所有题目来自hzwer在LOJ上提供的数列分块入门系列。 Blog:http://hzwer.com/8053.html sto hzwer orz %%% [转载] -----------------------------------------------------------------…

2024.7.12 暑期训练记录(4)

之后的训练方式是上午板刷2000的题&#xff0c;下午学新算法or vp&#xff0c;如果近期没有新算法要学也不vp就换成继续板刷&#xff0c;晚上补题&#xff0c;没有题要补就继续板刷在尝试新的做题方式&#xff0c;看完题先把主要信息写在纸上&#xff0c;如果有思路就顺着思路走…

分享浏览器被hao123网页劫持,去除劫持的方式

昨天看python相关的自动化工作代码时&#xff0c;发现谷歌浏览器被hao123劫持了&#xff0c;把那些程序删了也不管用 方法1&#xff1a;删除hao123注册表&#xff0c;这个方式不太好用&#xff0c;会找不到注册表 方法2&#xff1a;看浏览器快捷方式的属性页面&#xff0c;一…

redis查询慢,你们是如何排查优化的(运维篇2)

1、开启慢查询日志 首先&#xff0c;第一步&#xff0c;你需要去查看一下 Redis 的慢日志&#xff08;slowlog&#xff09;。 Redis 提供了慢日志命令的统计功能&#xff0c;它记录了有哪些命令在执行时耗时比较久。 查看 Redis 慢日志之前&#xff0c;你需要设置慢日志的阈值。…

ESP32和ESP8266的WIFI的136个问题与答案

ESP32和ESP8266的WIFI的136个问题与答案 ESP32和ESP8266 WIFI相关问题与答案&#xff0c;具有一定的参考价值。ESP32-S3模块 1. ESP32 和 ESP8266 是否支持中文 SSID&#xff1f; ESP32 和 ESP8266 均支持中文 SSID&#xff0c;但需要使用相应的库和设置。需要注意的是&#…

PySide(PyQt)判断QLineEdit的输入是否合规

判断QLineEdit的输入是否符合要求&#xff0c;比如是否为整数或者浮点数。 1、使用正则表达式来判断 符合正则表达式则输入合规 import sys import re from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QLabelclass ExampleWidget(QWidget):…

Eclipse 运行程序

我们可以在 Package Explorer 视图 可以在 Package Explorer 视图中快速运行 Java 程序。 Package Explorer 视图: 鼠标右击包含 main 函数的 java 类选择 Run As > Java Application 同样你也可以在 Package Explorer 视图中选择包含 main 方法的类并按下快捷键&#x…

C++之多态使用小结

1、多态定义 1.1 多态概念 C多态性&#xff08;Polymorphism&#xff09;是面向对象编程(OOP)的一个重要特性之一&#xff0c;它允许我们使用统一的接口来处理不同类型的对象。多态性使得程序更加灵活、可扩展并且易于维护。 通俗来说&#xff0c;就是多种形态&#xff0…

期末成绩发布智能助手

期末考试的结束标志着教师们迎来了成绩处理的忙碌时期。传统的成绩单分发方式不仅耗时耗力&#xff0c;而且容易出错。幸运的是&#xff0c;易查分小程序的出现&#xff0c;为这一过程提供了一个简便而高效的解决方案。 易查分小程序是专为教师和家长设计的智能工具&#xff0…

安卓笔记1-Retrofit2请求自定义接口

1、整体功能概述 安卓项目中使用Retrofit2实现和自定义接口的网络交互&#xff0c;通过Postman模拟服务端&#xff0c;创建自定义接口。 作用 前后端开发进度对不齐时&#xff0c;客户端可利用本功能模拟测试数据。备忘。 缺点 retrofit模拟接口需要配置响应数据类&#xff…