MMSegmentation笔记

如何训练自制数据集?

首先需要在 mmsegmentation/mmseg/datasets 目录下创建一个自制数据集的配置文件,以我的苹果叶片病害分割数据集为例,创建了mmsegmentation/mmseg/datasets/appleleafseg.py

可以看到,这个配置文件主要定义了自制数据集中的 METAINFO , 包括标签的类别,以及对应的 palette 调色板色彩数值,还定义了原始图像和标签图像的文件后缀,分别是 jpg 和 png,以及设置 reduce_zero_label 属性 (是否忽略背景)

from mmseg.registry import DATASETS
from .basesegdataset import BaseSegDataset@DATASETS.register_module()
class AppleLeafSegDataset(BaseSegDataset):METAINFO = dict(classes=('background', 'Alternaria_Boltch', 'Brown_spot', 'Frogeye_leaf_spot', 'Grey_spot', 'Mosaic', 'Powdery_mildew', 'Rust', 'Scab', 'Health'),palette=[[0, 0, 0], [170, 0, 0], [99, 102, 129], [249, 193, 0], [160, 180, 0],[115, 82, 59], [217, 213, 180], [51, 142, 137], [218, 147, 70], [234, 132, 163]])def __init__(self,img_suffix='.jpg',seg_map_suffix='.png',reduce_zero_label=False,# 因为上面METAINFO已经将背景0作为一种类别并且设置掩码色彩为0,0,0所以这里的reduce_zero_label需要设置为false**kwargs) -> None:super().__init__(img_suffix=img_suffix,seg_map_suffix=seg_map_suffix,reduce_zero_label=reduce_zero_label,**kwargs)

然后将 AppleLeafSegDataset 添加到 mmseg/datasets/__init__.py 中的__all__

__all__ = ['BaseSegDataset', 'BioMedical3DRandomCrop', 'BioMedical3DRandomFlip','CityscapesDataset', 'PascalVOCDataset', 'ADE20KDataset','PascalContextDataset', 'PascalContextDataset59', 'ChaseDB1Dataset','DRIVEDataset', 'HRFDataset', 'STAREDataset', 'DarkZurichDataset','NightDrivingDataset', 'COCOStuffDataset', 'LoveDADataset','MultiImageMixDataset', 'iSAIDDataset', 'ISPRSDataset', 'PotsdamDataset','LoadAnnotations', 'RandomCrop', 'SegRescale', 'PhotoMetricDistortion','RandomRotate', 'AdjustGamma', 'CLAHE', 'Rerange', 'RGB2Gray','RandomCutOut', 'RandomMosaic', 'PackSegInputs', 'ResizeToMultiple','LoadImageFromNDArray', 'LoadBiomedicalImageFromFile','LoadBiomedicalAnnotation', 'LoadBiomedicalData', 'GenerateEdge','DecathlonDataset', 'LIPDataset', 'ResizeShortestEdge','BioMedicalGaussianNoise', 'BioMedicalGaussianBlur','BioMedicalRandomGamma', 'BioMedical3DPad', 'RandomRotFlip','SynapseDataset', 'REFUGEDataset', 'MapillaryDataset_v1','MapillaryDataset_v2', 'Albu', 'LEVIRCDDataset','LoadMultipleRSImageFromFile', 'LoadSingleRSImageFromFile','ConcatCDInput', 'BaseCDDataset', 'DSDLSegDataset', 'BDD100KDataset','NYUDataset', 'HSIDrive20Dataset', 'AppleLeafSegDataset'
]

接下来,需要在 mmsegmentation/mmseg/utils/class_names.py 中补充数据集元信息

我的苹果树叶病害数据集相关片段如下:

def appleleafdiseases_classes():"""BDD100K class names for external use(the class name is compatible withCityscapes )."""return ['background', 'Alternaria_Boltch', 'Brown_spot', 'Frogeye_leaf_spot', 'Grey_spot', 'Mosaic','Powdery_mildew', 'Rust', 'Scab', 'Health']def appleleafdiseases_palette():"""bdd100k palette for external use(same with cityscapes)"""return [[0, 0, 0], [170, 0, 0], [99, 102, 129], [249, 193, 0], [160, 180, 0],[115, 82, 59], [217, 213, 180], [51, 142, 137], [218, 147, 70], [234, 132, 163]]dataset_aliases = {'cityscapes': ['cityscapes'],'ade': ['ade', 'ade20k'],'voc': ['voc', 'pascal_voc', 'voc12', 'voc12aug'],'pcontext': ['pcontext', 'pascal_context', 'voc2010'],'loveda': ['loveda'],'potsdam': ['potsdam'],'vaihingen': ['vaihingen'],'cocostuff': ['cocostuff', 'cocostuff10k', 'cocostuff164k', 'coco-stuff','coco-stuff10k', 'coco-stuff164k', 'coco_stuff', 'coco_stuff10k','coco_stuff164k'],'isaid': ['isaid', 'iSAID'],'stare': ['stare', 'STARE'],'lip': ['LIP', 'lip'],'mapillary_v1': ['mapillary_v1'],'mapillary_v2': ['mapillary_v2'],'bdd100k': ['bdd100k'],'hsidrive': ['hsidrive', 'HSIDrive', 'HSI-Drive', 'hsidrive20', 'HSIDrive20','HSI-Drive20'],'appleleafdiseases': ['appleleafdiseases']
}

然后,需要在mmsegmentation/configs/_base_/datasets/目录下创建一个新的数据集配置文件 mmsegmentation/configs/_base_/datasets/apple.py

这个数据集配置文件代码如下,可以看到,主要是告诉模型训练和测试的一些配置信息,包括数据集类和数据集路径,训练,测试的pipiline数据增强,不同的dataloader(训练集,验证集,测试集),验证集测试集的评价指标计算。

# dataset settings
dataset_type = 'AppleLeafSegDataset'
data_root = 'AppleLeafSegDataset/' # 自己数据集所在位置
img_scale = (320, 640) # img_scale是指图像在处理管道中将被调整到的尺寸
crop_size = (160, 320)
train_pipeline = [dict(type='LoadImageFromFile'),dict(type='LoadAnnotations', reduce_zero_label=False), # 不忽略背景dict(type='RandomResize',scale=img_scale,ratio_range=(0.5, 2.0),keep_ratio=True),dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),dict(type='RandomFlip', prob=0.5),dict(type='PhotoMetricDistortion'),dict(type='PackSegInputs')
]
test_pipeline = [dict(type='LoadImageFromFile'),dict(type='Resize', scale=img_scale, keep_ratio=True),# add loading annotation after ``Resize`` because ground truth# does not need to do resize data transformdict(type='LoadAnnotations', reduce_zero_label=False),dict(type='PackSegInputs')
]
img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75]
# 测试时增强 (TTA) 是一种在测试阶段使用的数据增强策略。它对同一张图片应用不同的增强,例如翻转和缩放,用于模型推理,然后将每个增强后的图像的预测结果合并,以获得更准确的预测结果。
tta_pipeline = [dict(type='LoadImageFromFile', backend_args=None),dict(type='TestTimeAug',transforms=[[dict(type='Resize', scale_factor=r, keep_ratio=True)for r in img_ratios],[dict(type='RandomFlip', prob=0., direction='horizontal'),dict(type='RandomFlip', prob=1., direction='horizontal')], [dict(type='LoadAnnotations')], [dict(type='PackSegInputs')]])
]
train_dataloader = dict(batch_size=4,num_workers=4,persistent_workers=True,sampler=dict(type='InfiniteSampler', shuffle=True),dataset=dict(type=dataset_type,data_root=data_root,data_prefix=dict(img_path='images/training', seg_map_path='annotations/training'),pipeline=train_pipeline))
val_dataloader = dict(batch_size=1,num_workers=4,persistent_workers=True,sampler=dict(type='DefaultSampler', shuffle=False),dataset=dict(type=dataset_type,data_root=data_root,data_prefix=dict(img_path='images/validation',seg_map_path='annotations/validation'),pipeline=test_pipeline))
test_dataloader = val_dataloaderval_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU'])
test_evaluator = val_evaluator

最后,我们需要创建一个总的配置文件,mmsegmentation/configs/unet/unet_s5-d16_deeplabv3_4xb4-40k_appleleafdiseases-320×640.py

这里可以选择mmsegmentation/configs/目录下的不同模型进行实验,这里以unet为例,我创建的这个文件代码如下:
可以看到,_base_定义了模型配置,数据集配置,调度策略配置,运行时配置。
然后也定义了裁剪大小,数据预处理。

_base_ = ['../_base_/models/apple_deeplabv3_unet_s5-d16.py', '../_base_/datasets/apple.py','../_base_/default_runtime.py', '../_base_/schedules/schedule_40k.py'
]
crop_size = (160, 320)
data_preprocessor = dict(size=crop_size)
model = dict(data_preprocessor=data_preprocessor,test_cfg=dict(crop_size=(160, 320), stride=(85, 85)))

然后,创建一个mmsegmentation/configs/_base_/models/apple_deeplabv3_unet_s5-d16.py

代码如下, 可以看到定义了数据预处理,模型结构,backbone类型,解码器头和辅助解码器头:

# model settings
norm_cfg = dict(type='BN', requires_grad=True)
data_preprocessor = dict(type='SegDataPreProcessor',mean=[123.675, 116.28, 103.53],std=[58.395, 57.12, 57.375],bgr_to_rgb=True,pad_val=0,seg_pad_val=255)
model = dict(type='EncoderDecoder',data_preprocessor=data_preprocessor,pretrained=None,backbone=dict(type='UNet',in_channels=3,base_channels=64,num_stages=5,strides=(1, 1, 1, 1, 1),enc_num_convs=(2, 2, 2, 2, 2),dec_num_convs=(2, 2, 2, 2),downsamples=(True, True, True, True),enc_dilations=(1, 1, 1, 1, 1),dec_dilations=(1, 1, 1, 1),with_cp=False,conv_cfg=None,norm_cfg=norm_cfg,act_cfg=dict(type='ReLU'),upsample_cfg=dict(type='InterpConv'),norm_eval=False),decode_head=dict(type='ASPPHead',in_channels=64,in_index=4,channels=16,dilations=(1, 12, 24, 36),dropout_ratio=0.1,num_classes=10,norm_cfg=norm_cfg,align_corners=False,loss_decode=dict(type='LovaszLoss', reduction='none', loss_weight=1.0)),auxiliary_head=dict(type='FCNHead',in_channels=128,in_index=3,channels=64,num_convs=1,concat_input=False,dropout_ratio=0.1,num_classes=10,norm_cfg=norm_cfg,align_corners=False,loss_decode=dict(type='LovaszLoss', reduction='none', loss_weight=0.4)),# model training and testing settingstrain_cfg=dict(),test_cfg=dict(mode='slide', crop_size=128, stride=85))

然后,重新启动

python setup.py install
pip install -v -e .

开始训练

python tools/train.py configs/unet/unet_s5-d16_deeplabv3_4xb4-40k_appleleafdiseases-320×640.py --work-dir mmseg_log

如何添加训练过程中日志所打印的评价指标?

默认的只打印 IoU ,Acc,mIoU,mAcc,aAcc,如果还想打印 Fscore ,Precision, Recall,mFscore ,mPrecision, mRecall,只需要在数据集配置文件中mmsegmentation/configs/_base_/datasets/apple.py,在这行代码中添加 mFscore

val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mFscore'])

下面的打印信息如何解读?

+-------------------+-------+-------+--------+-----------+--------+
|       Class       |  IoU  |  Acc  | Fscore | Precision | Recall |
+-------------------+-------+-------+--------+-----------+--------+
|     background    | 94.07 | 96.16 | 96.95  |   97.74   | 96.16  |
| Alternaria_Boltch |  58.0 | 72.75 | 73.42  |    74.1   | 72.75  |
|     Brown_spot    | 64.19 | 82.51 | 78.19  |   74.29   | 82.51  |
| Frogeye_leaf_spot | 44.46 | 55.28 | 61.55  |   69.43   | 55.28  |
|     Grey_spot     | 53.24 | 67.83 | 69.49  |   71.23   | 67.83  |
|       Mosaic      |  50.3 | 81.06 | 66.93  |   56.99   | 81.06  |
|   Powdery_mildew  | 59.52 | 93.42 | 74.63  |   62.13   | 93.42  |
|        Rust       | 61.07 | 71.43 | 75.83  |   80.82   | 71.43  |
|        Scab       | 28.49 | 50.39 | 44.35  |   39.61   | 50.39  |
|       Health      | 84.84 | 91.07 |  91.8  |   92.55   | 91.07  |
+-------------------+-------+-------+--------+-----------+--------+
07/11 18:55:19 - mmengine - INFO - Iter(val) [169/169]    aAcc: 94.1500  mIoU: 59.8200  mAcc: 76.1900  mFscore: 73.3100  mPrecision: 71.8900  mRecall: 76.1900  data_time: 0.0196  time: 0.0292

在这个表格中,每个类别的 Acc 表示的是该类别的分类准确率(Accuracy),也称为像素准确率(PA)。具体来说,Acc 是每个类别中被正确分类的像素数占该类别总像素数的比例。公式如下: Acc = TP TP + FN \text{Acc} = \frac{\text{TP}}{\text{TP} + \text{FN}} Acc=TP+FNTP其中:

  • TP \text{TP} TP 是该类别的真阳性像素数(正确分类为该类别的像素数)。
  • FN \text{FN} FN 是该类别的假阴性像素数(实际为该类别但被错误分类为其他类别的像素数)。

这个准确率反映了模型在特定类别上的预测准确度,表示模型有多少比例的该类别像素被正确识别。每个类别都有一个单独的 Acc 值,用于衡量该类别的分类性能。

总结:

  • 表格中的 Acc 表示的是每个类别的分类准确率,衡量模型在该类别上的预测准确度。

在 mmsegmentation 训练模型时,aAcc 和 mAcc 分别表示:

  1. aAcc(Overall Accuracy or Pixel Accuracy): 表示所有像素分类正确的比例。它是通过将所有类别的像素预测正确的数量除以总的像素数量来计算的。公式如下:

aAcc = ∑ i = 1 N TP i ∑ i = 1 N ( TP i + FP i + FN i + TN i ) \text{aAcc} = \frac{\sum_{i=1}^{N} \text{TP}_i}{\sum_{i=1}^{N} (\text{TP}_i + \text{FP}_i + \text{FN}_i + \text{TN}_i)} aAcc=i=1N(TPi+FPi+FNi+TNi)i=1NTPi

其中, TP \text{TP} TP 是真阳性, FP \text{FP} FP 是假阳性, FN \text{FN} FN 是假阴性, TN \text{TN} TN 是真阴性, N N N 是类别数量。

  1. mAcc(Mean Accuracy): 表示每个类别的平均准确率。它是对每个类别的准确率的平均值。公式如下:

mAcc = 1 N ∑ i = 1 N TP i TP i + FN i \text{mAcc} = \frac{1}{N} \sum_{i=1}^{N} \frac{\text{TP}_i}{\text{TP}_i + \text{FN}_i} mAcc=N1i=1NTPi+FNiTPi

其中, TP \text{TP} TP FN \text{FN} FN 是每个类别的真阳性和假阴性, N N N 是类别数量。

总结:

  • aAcc 表示所有像素分类正确的总体准确率。
  • mAcc 表示每个类别的平均准确率。

怎么使用mmsegmentation的tool/test.py

首先看一下命令行参数部分的代码

def parse_args():parser = argparse.ArgumentParser(description='MMSeg test (and eval) a model')parser.add_argument('config', help='train config file path')parser.add_argument('checkpoint', help='checkpoint file')parser.add_argument('--work-dir', help=('if specified, the evaluation metric results will be dumped into the directory as json'))parser.add_argument('--out', type=str, help='The directory to save output prediction for offline evaluation')parser.add_argument('--show', action='store_true', help='show prediction results')parser.add_argument('--show-dir', help='directory where painted images will be saved. If specified, it will be automatically saved to the work_dir/timestamp/show_dir')parser.add_argument('--wait-time', type=float, default=2, help='the interval of show (s)')parser.add_argument('--cfg-options', nargs='+', action=DictAction, help='override some settings in the used config, the key-value pair in xxx=yyy format will be merged into config file. If the value to be overwritten is a list, it should be like key="[a,b]" or key=a,b It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" Note that the quotation marks are necessary and that no white space is allowed.')parser.add_argument('--launcher', choices=['none', 'pytorch', 'slurm', 'mpi'], default='none', help='job launcher')parser.add_argument('--tta', action='store_true', help='Test time augmentation')parser.add_argument('--local_rank', '--local-rank', type=int, default=0)args = parser.parse_args()if 'LOCAL_RANK' not in os.environ:os.environ['LOCAL_RANK'] = str(args.local_rank)return args
  • config:训练配置文件路径。
  • checkpoint:模型检查点文件路径。
  • work-dir:指定工作目录,评估结果会保存为 JSON。
  • out:保存预测结果的目录,用于离线评估。
  • show:显示预测结果。
  • show-dir:保存绘制图像的目录。
  • wait-time:显示间隔时间(秒)。
  • cfg-options:覆盖配置文件中的一些设置。
  • launcher:选择作业启动器。
  • tta:启用测试时增强。
  • local_rank:本地排名。

这里的 config 是指模型的整体配置文件,而不是训练结束后保存到 --work-dir 目录下的配置文件。

最终我执行测试的命令是

python tools/test.py 
configs/segformer/apple_segformer_mit-b0_8xb2-160k_appleleaf-512x512.py 
mmseg_log/iter_20000.pth 
--work-dir mmseg_log --out outputs --show-dir outputs

第一个参数是模型配置文件,第二个参数是训练过程保存的权重文件,这里以最后一次iter保存的为例,–work-dir 会将测试集的评估结果和日志保存到我指定的mmseg_log目录下,–out和–show-dir我都指定为outputs目录下,测试结束后,会在outputs目录下得到测试所得到的结果图像,一种是灰度图像,看起来是纯黑色的,另一种是可视化的彩色对比图像,如下图:
在这里插入图片描述
左边是Ground Truth,右边是模型预测的结果。

将outputs目录下模型测试所得到的灰度图像转换为伪彩色图像

下面这段代码保存为convert_to_pseudo_color.py,然后执行python convert_to_pseudo_color.py 后就会将outputs目录下模型测试所得到的灰度图像转换为伪彩色图像并保存到 outputs/Pseudo/ 目录下了

import os
from PIL import Image
import numpy as np# METAINFO
METAINFO = dict(classes=('background', 'Alternaria_Boltch', 'Brown_spot', 'Frogeye_leaf_spot', 'Grey_spot', 'Mosaic', 'Powdery_mildew', 'Rust', 'Scab', 'Health'),palette=[[0, 0, 0], [170, 0, 0], [99, 102, 129], [249, 193, 0], [160, 180, 0],[115, 82, 59], [217, 213, 180], [51, 142, 137], [218, 147, 70], [234, 132, 163]]
)# Ensure output directory exists
output_dir = 'outputs/Pseudo/'
os.makedirs(output_dir, exist_ok=True)# Get the palette from METAINFO
palette = METAINFO['palette']
palette = np.array(palette, dtype=np.uint8)def convert_to_pseudo_color(image_path, save_path):"""Convert a grayscale image to pseudo color using the given palette."""gray_image = Image.open(image_path).convert('L')gray_array = np.array(gray_image)color_image = np.zeros((gray_array.shape[0], gray_array.shape[1], 3), dtype=np.uint8)for i in range(len(palette)):color_image[gray_array == i] = palette[i]color_image = Image.fromarray(color_image)color_image.save(save_path)# Process all .png files in the outputs directory
for file_name in os.listdir('outputs'):if file_name.endswith('.png'):file_path = os.path.join('outputs', file_name)save_path = os.path.join(output_dir, file_name)convert_to_pseudo_color(file_path, save_path)print("Pseudo color images have been saved to", output_dir)

怎么打印模型 flops 和参数量?

执行这个命令,第一个参数是模型配置文件,第二个参数–shape是可选项,表示测试的图像大小

python tools/analysis_tools/get_flops.py
configs/segformer/apple_segformer_mit-b0_8xb2-160k_appleleaf-512x512.py 
--shape 1024 512

打印输出的结果如下:

==============================
Compute type: direct: randomly generate a picture
Input shape: (1024, 512)
Flops: 17.917G
Params: 3.718M
==============================

怎么打印模型 fps?

怎么按照epoch训练,而非iter?

首先我重新编写了一个../_base_/schedules/schedule_20k_by_epoch.py

可以看到需要将 train_cfg 中的 type 设置为 EpochBasedTrainLoop,下面的默认hooks也需要调整为按epoch方式训练的

# optimizer
optimizer = dict(type='SGD', lr=0.001, momentum=0.9, weight_decay=0.0005)
optim_wrapper = dict(type='OptimWrapper', optimizer=optimizer, clip_grad=None)# learning policy
param_scheduler = [dict(type='PolyLR',eta_min=1e-4,power=0.9,begin=0,end=200,by_epoch=True)
]# training schedule for 20 epochs
train_cfg = dict(type='EpochBasedTrainLoop', max_epochs=200, val_interval=1)
val_cfg = dict(type='ValLoop')
test_cfg = dict(type='TestLoop')default_hooks = dict(timer=dict(type='IterTimerHook'),logger=dict(type='LoggerHook', interval=1, log_metric_by_epoch=True),param_scheduler=dict(type='ParamSchedulerHook'),checkpoint=dict(type='CheckpointHook', by_epoch=True, interval=20),sampler_seed=dict(type='DistSamplerSeedHook'),visualization=dict(type='SegVisualizationHook'))

然后需要修改整体配置文件mmsegmentation/configs/segformer/apple_segformer_mit-b0_8xb2-160k_appleleaf-512x512.py

_base_ = ['../_base_/models/apple_segformer_mit-b0.py', '../_base_/datasets/apple.py','../_base_/default_runtime.py', '../_base_/schedules/schedule_20k_by_epoch.py'
]

我将原先的../_base_/schedules/schedule_20k.py替换成了重新编写的../_base_/schedules/schedule_20k_by_epoch.py
然后还需要将整体配置文件中的param_scheduler进行修改,如下所示,前5个epoch按照LinearLR进行学习率调整,5-200按照PolyLR

param_scheduler = [dict(type='LinearLR', start_factor=0.1, by_epoch=True, begin=0, end=5),dict(type='PolyLR',eta_min=0.0,power=1.0,begin=5,end=200,by_epoch=True,)
]

然后我执行训练命令,发现训练期间,log所打印的仍然是按 iter 训练的信息,问题是../_base_/default_runtime.py的代码有覆盖,
需要将下面这行代码修改

log_processor = dict(by_epoch=True) # 修改为按 epoch 打印日志

此时遇到了第二个问题,虽然按照epoch打印了,但是在第一个 epoch 陷入了无限循环,解决办法是需要修改数据集配置文件../_base_/datasets/apple.py,需要将下面这一行代码修改为

sampler=dict(type='DefaultSampler', shuffle=True),  # 更改为 DefaultSampler

原先的 InfiniteSampler 导致无限循环

运行segmenter遇到的问题

需要升级 pytorch版本到 1.13.1 cuda117,然后我在虚拟环境升级之后,遇到mmcv版本不匹配的问题,解决办法是卸载 mmcv,然后安装mmcv 次最新版,问题得到解决。

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

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

相关文章

python:使用matplotlib库绘制图像(四)

作者是跟着http://t.csdnimg.cn/4fVW0学习的,matplotlib系列文章是http://t.csdnimg.cn/4fVW0的自己学习过程中整理的详细说明版本,对小白更友好哦! 四、条形图 1. 一个数据样本的条形图 条形图:常用于比较不同类别的数量或值&…

3dmax-vray5大常用材质设置方法

3dmax云渲染平台——渲染100 以高性价比著称,是预算有限的小伙伴首选。 15分钟0.2,60分钟内0.8;注册填邀请码【7788】可领30元礼包和免费渲染券 提供了多种机器配置选择(可以自行匹配环境)最高256G大内存机器,满足不同用户需求。 木纹材质 肌理调整&…

练习9.5 彩票分析

练习 9.14:彩票 创建⼀个列表或元素,其中包含 10 个数和 5 个字 ⺟。从这个列表或元组中随机选择 4 个数或字⺟,并打印⼀条消息, 指出只要彩票上是这 4 个数或字⺟,就中⼤奖了。 练习 9.15:彩票分析 可以使…

2.5 OJ 网站的使用与作业全解

目录 1 OJ 网站如何使用 1.1 注册账户 1.2 登录账户 1.3 做题步骤 2 本节课的 OJ 作业说明 3 章节综合判断题 4 课时2作业1 5 课时2作业2 6 课时2作业3 1 OJ 网站如何使用 〇J 是英文 Online Judge 的缩写,中文翻译过来是在线判题。当用户将自己编写的代码…

基于XC7VX690T FPGA+ZU15EG SOC的6U VPX总线实时信号处理平台(支持4路光纤)

6U VPX架构,符合VITA46规范板载高性能FPGA处理器:XC7VX690T-2FFG1927I板载1片高性能MPSOC:XCZU15EG-2FFVB1156I板载1片MCU,进行健康管理、时钟配置等V7 FPGA外挂2个FMC接口两片FPGA之间通过高速GTH进行互联 基于6U VPX总线架构的通…

从零开始做题:神奇的棋盘

题目 打开得到一副adfgvx加密棋盘 观察txt数据只有1-5,猜测是数字字母坐标转换,用notepad批量操作一下 解题 AGAXXDAGGVGGVDVADAVXDGADVGDVAADDDDFXAFAFDGDVXXDGGDGGDXDDFDDXVGXADGVDFXVVAADDXDXXADDVGGGXGXXXXGXXGGXGDVVVGGGAGAAAAGAAGGAGDDDAGAGGG…

翁恺-C语言程序设计-05-3. 求a的连续和

05-3. 求a的连续和 输入两个整数a和n,a的范围是[0,9],n的范围是[1,8],求数列之和S aaaaaa…aaa…a(n个a)。如a为2、n为8时输出的是222222…22222222的和。 输入格式: 输入在一行中给出两个整数&#xf…

VUE_TypeError: Cannot convert a BigInt value to a number at Math.pow 解决方法

错误信息 TypeError: Cannot convert a BigInt value to a number at Math.pow vue 或 react package.json添加 "browserslist": {"production": ["chrome > 67","edge > 79","firefox > 68","opera >…

实战演练-2021年电赛国一之三端口DC-DC变换器

文章目录 前言一、题目二、题目分析1、题目要求解析2、题目方案选定方案一(使用buck-boost电路+双向DC-DC电路(前端))方案二(使用同步整流Boost升压电路+双向DC-DC电路(前端))方案三(使用同步整流Boost升压…

二叉搜索树大冒险:寻找-插入-删除

OK,看我们题目就可知道啦,今天要分享学习的一种数据结构就是二叉搜索树。 内容题目也说了三个大概的,分别是寻找、插入、删除。 讲这个之前呢,那么就先讲讲这个二叉搜索树是何方神圣呢? 二叉搜索树: 又…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(五)-同时支持无人机和eMBB用户数据传输的用例

引言 本文是3GPP TR 22.829 V17.1.0技术报告,专注于无人机(UAV)在3GPP系统中的增强支持。文章提出了多个无人机应用场景,分析了相应的能力要求,并建议了新的服务级别要求和关键性能指标(KPIs)。…

全网最详细单细胞保姆级分析教程(二) --- 多样本整合

上一节我们研究了如何对单样本进行分析,这节我们就着重来研究一下如何对多样本整合进行研究分析! 1. 导入相关包 library(Seurat) library(tidyverse) library(patchwork)2. 数据准备 # 导入单样本文件 dir c(~/Desktop/diversity intergration/scRNA_26-0_filtered_featur…

【香橙派 Orange pi AIpro】| 开发板深入使用体验

目录 一. 🦁 写在前面二. 🦁 愉快的安装流程2.1 安装前准备2.2 流程准备2.2.1 烧录镜像2.2.2 开机2.2.3 连网2.2.4 SSH远程连接开发板 2.3 体验 AI 应用样例 三. 🦁 写在最后 一. 🦁 写在前面 大家好,我是狮子呀&…

医疗级微型导轨:保障医疗行业手术安全!

微型直线导轨能成为一种专为医疗行业设备运用的高精度线性运动设备,在现代医疗领域,精准的位置控制和平稳的运动对于确保医疗设备的高效性能至关重要。那么,医疗行业对微型导轨有哪些要求呢? 1、精度:在手术过程中&…

C++客户端Qt开发——开发环境

一、QT开发环境 1.安装三个部分 ①C编译器(gcc,cl.exe……) ②QT SDK SDK-->软件开发工具包 比如,windows版本QT SDK里已经内置了C的编译器(内置编译器是mingw,windows版本的gcc/g) ③QT的集成开发…

智慧园区规划建设解决方案PPT(40页)

智慧园区规划建设解决方案摘要 1. 园区定义与发展历程 园区,亦称开发区,是在特定产业和区域政策指导下形成的区域。它们通过提供基础设施和生产空间,吸引投资,形成技术、资本密集区,推动经济发展。园区发展经历了四代…

Docker 部署 ShardingSphere-Proxy 数据库中间件

文章目录 Github官网文档ShardingSphere-Proxymysql-connector-java 驱动下载conf 配置global.yamldatabase-sharding.yamldatabase-readwrite-splitting.yamldockerdocker-compose.yml Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为…

【qt】TCP客户端信息的接受和发送

当有信息时的槽函数关联 跟服务端收到信息一样,当可以读一行的时候,就从套接字读一行. 发送信息也是和服务端如出一辙,通过write(). 运行结果:

Spring MVC 中的文件上传 和 文件下载

Spring MVC 中的文件上传 和 文件下载 文章目录 Spring MVC 中的文件上传 和 文件下载1. Spring MVC 中的文件上传2. Spring MVC 中的文件下载3. 总结:4. 最后: 1. Spring MVC 中的文件上传 文件上传是:浏览器端向服务器发送文件&#xff0c…

C 语言结构体

由于近期项目需求,需使用到大量的指针与结构体,为更好的完成项目,故对结构体与指针的内容进行回顾,同时撰写本博客,方便后续查阅。 本博客涉及的结构体知识有: 1.0:结构体的创建和使用 2.0: typedef 关…