深度學習·mmsegmentation基礎教程

mmsegmentation的使用教程

mmsegmentation微調方法總結

  • 自定義自己的數據集:mmsegmentation\configs\_base_\datasets\ZihaoDataset_pipeline.py
  • 注冊:mmsegmentation\configs\_base_\datasets\__init__.py
  • 定義訓練和測試的pipeline:mmsegmentation\configs\_base_\datasets\ZihaoDataset_pipeline.py,修改關鍵參數(與之前匹配)
  • 融合預訓練模型:configs/fastscnn/fast_scnn_8xb4-160k_cityscapes-512x1024.py和pipeline:mmsegmentation\configs\_base_\datasets\ZihaoDataset_pipeline.py文件,注意微調分割頭!!!注意微調分割頭!!!注意微調分割頭!!!
  • 得到最后的config文件ZihaoDataset_FastSCNN_20230818.py
  • 下載預訓練模型:修改mmsegmentation\configs\segformer\segformer_mit-b5_8xb2-160k_ade20k-512x512.py的pth路徑,避免下載!
  • 訓練:命令tools/train.py Zihao-Configs/ZihaoDataset_PSPNet_20230818.py,默認使用預訓練模型開始微調
  • 測試:需要用到訓練時的.pth文件
  • 推理:根據融合后的config文件和.pth文件調用inference_model()API對圖片進行推理。
  • 可視化:可以使用官方提供的針對單個圖片的可視化結果
  • 所有指標和日志保存在work_dirs/xxx/.json文件下,如果需要單個class的指標結果,可以使用.log文件匹配。
  • 注意:opencv加載圖片的格式是:bgr格式

自定義數據集mmsegmentation\mmseg\datasets\ZihaoDataset.py

  • 繼承BaseSegDatasetfrom .basesegdataset import BaseSegDataset
class ZihaoDataset(BaseSegDataset):
  • 類別和RGB標簽的映射關系
METAINFO = {'classes':['background', 'red', 'green', 'white', 'seed-black', 'seed-white'],'palette':[[127,127,127], [200,0,0], [0,200,0], [144,238,144], [30,30,30], [251,189,8]]}
  • 指定圖像擴展名、標注擴展名
    def __init__(self,seg_map_suffix='.png',   # 標注mask圖像的格式reduce_zero_label=False, # 類別ID為0的類別是否需要除去**kwargs) -> None:super().__init__(seg_map_suffix=seg_map_suffix,reduce_zero_label=reduce_zero_label,**kwargs)
from mmseg.registry import DATASETS
from .basesegdataset import BaseSegDataset@DATASETS.register_module()
class ZihaoDataset(BaseSegDataset):# 類別和對應的 RGB配色METAINFO = {'classes':['background', 'red', 'green', 'white', 'seed-black', 'seed-white'],'palette':[[127,127,127], [200,0,0], [0,200,0], [144,238,144], [30,30,30], [251,189,8]]}# 指定圖像擴展名、標注擴展名def __init__(self,seg_map_suffix='.png',   # 標注mask圖像的格式reduce_zero_label=False, # 類別ID為0的類別是否需要除去**kwargs) -> None:super().__init__(seg_map_suffix=seg_map_suffix,reduce_zero_label=reduce_zero_label,**kwargs)

注冊修改mmsegmentation\mmseg\datasets\__init__.py

  • 導入ZihaoDataset
from .ZihaoDataset import ZihaoDataset
  • __all__ 后面加入'ZihaoDataset'
# yapf: enable
__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','ZihaoDataset'
]

`mmsegmentation\mmseg相當于源碼部分

configs中自定義訓練和測試pipeline mmsegmentation\configs\_base_\datasets\ZihaoDataset_pipeline.py

必須修改的地方有:

  • 類名和數據集根地址,注意接下來的img_pathseg_map_path參數會和data_root拼接在一起
  • 還包括一些數據增強和訓練相關的參數。
dataset_type = 'ZihaoDataset' # 數據集類名
data_root = 'Watermelon87_Semantic_Seg_Mask/' # 數據集路徑(相對于mmsegmentation主目錄)
  • img_pathseg_map_path參數
train_dataloader = dict(batch_size=2,num_workers=2,persistent_workers=True,sampler=dict(type='InfiniteSampler', shuffle=True),dataset=dict(type=dataset_type,data_root=data_root,data_prefix=dict(img_path='img_dir/train', seg_map_path='ann_dir/train'),pipeline=train_pipeline))# 驗證 Dataloader
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='img_dir/val', seg_map_path='ann_dir/val'),pipeline=test_pipeline))
# 數據處理 pipeline
# 數據集路徑
dataset_type = 'ZihaoDataset' # 數據集類名
data_root = 'Watermelon87_Semantic_Seg_Mask/' # 數據集路徑(相對于mmsegmentation主目錄)# 輸入模型的圖像裁剪尺寸,一般是 128 的倍數,越小顯存開銷越少
crop_size = (512, 512)# 訓練預處理
train_pipeline = [dict(type='LoadImageFromFile'),dict(type='LoadAnnotations'),dict(type='RandomResize',scale=(2048, 1024),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=(2048, 1024), keep_ratio=True),dict(type='LoadAnnotations'),dict(type='PackSegInputs')
]# TTA后處理(增強性能的技巧)
img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] # 先縮放后全部加權得到結果
tta_pipeline = [dict(type='LoadImageFromFile', file_client_args=dict(backend='disk')),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')]])
]# 訓練 Dataloader
train_dataloader = dict(batch_size=2,num_workers=2,persistent_workers=True,sampler=dict(type='InfiniteSampler', shuffle=True),dataset=dict(type=dataset_type,data_root=data_root,data_prefix=dict(img_path='img_dir/train', seg_map_path='ann_dir/train'),pipeline=train_pipeline))# 驗證 Dataloader
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='img_dir/val', seg_map_path='ann_dir/val'),pipeline=test_pipeline))# 測試 Dataloader
test_dataloader = val_dataloader# 驗證 Evaluator
val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice', 'mFscore'])# 測試 Evaluator
test_evaluator = val_evaluator

微調(遷移學習)方法

  • 導入兩個py文件,一個是預訓練模型的文件configs/fastscnn/fast_scnn_8xb4-160k_cityscapes-512x1024.py
  • 一個是我們定義好的訓練和測試pipeline文件./configs/_base_/datasets/ZihaoDataset_pipeline.py
  • 兩個要結合起來
from mmengine import Config
cfg = Config.fromfile('configs/fastscnn/fast_scnn_8xb4-160k_cityscapes-512x1024.py')
dataset_cfg = Config.fromfile('./configs/_base_/datasets/ZihaoDataset_pipeline.py')
cfg.merge_from_dict(dataset_cfg)

微調方法

  • 修改分割頭
NUM_CLASS = 6
cfg.norm_cfg = dict(type='BN', requires_grad=True) # 只使用GPU時,BN取代SyncBN
cfg.model.backbone.norm_cfg = cfg.norm_cfg
cfg.model.decode_head.norm_cfg = cfg.norm_cfgcfg.dump('Zihao-Configs/ZihaoDataset_FastSCNN_20230818.py')
cfg.model.auxiliary_head[0].norm_cfg = cfg.norm_cfg
cfg.model.auxiliary_head[1].norm_cfg = cfg.norm_cfg# 模型 decode/auxiliary 輸出頭,指定為類別個數
cfg.model.decode_head.num_classes = NUM_CLASS
cfg.model.auxiliary_head[0]['num_classes'] = NUM_CLASS
cfg.model.auxiliary_head[1]['num_classes'] = NUM_CLASScfg.train_dataloader.batch_size = 4cfg.test_dataloader = cfg.val_dataloader# 結果保存目錄
cfg.work_dir = './work_dirs/ZihaoDataset-FastSCNN'cfg.train_cfg.max_iters = 30000 # 訓練迭代次數
cfg.train_cfg.val_interval = 500 # 評估模型間隔
cfg.default_hooks.logger.interval = 100 # 日志記錄間隔
cfg.default_hooks.checkpoint.interval = 2500 # 模型權重保存間隔
cfg.default_hooks.checkpoint.max_keep_ckpts = 2 # 最多保留幾個模型權重
cfg.default_hooks.checkpoint.save_best = 'mIoU' # 保留指標最高的模型權重# 隨機數種子
cfg['randomness'] = dict(seed=0)

保存為最終的Config配置文件

cfg.dump('Zihao-Configs/ZihaoDataset_FastSCNN_20230818.py')

修改預訓練模型

mmsegmentation\configs\segformer\segformer_mit-b5_8xb2-160k_ade20k-512x512.py:默認會下載預訓練模型(見下面的url鏈接),可以手動修改為預先下載的文件

_base_ = ['./segformer_mit-b0_8xb2-160k_ade20k-512x512.py']# checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b5_20220624-658746d9.pth'  # noqa
checkpoint = 'C:\\Users\\ASUS\\PycharmProjects\\pythonProject\\research\\MMSegmentation_Tutorials-main\\MMSegmentation_Tutorials-main\\20230816\\mmsegmentation\\pretrained\\mit_b5_20220624-658746d9.pth'  # noqa
# model settings
model = dict(backbone=dict(init_cfg=dict(type='Pretrained', checkpoint=checkpoint),embed_dims=64,num_heads=[1, 2, 5, 8],num_layers=[3, 6, 40, 3]),decode_head=dict(in_channels=[64, 128, 320, 512]))

訓練細節

08/02 12:35:34 - mmengine - INFO - Iter(val) [11/11]    aAcc: 87.5900  mIoU: 56.0600  mAcc: 71.7300  mDice: 65.9000  mFscore: 79.0800  mPrecision: 75.2700  mRecall: 71.7300  data_time: 0.0069  time: 0.0345
08/02 12:35:47 - mmengine - INFO - Iter(train) [ 9600/10000]  lr: 1.1351e-01  eta: 0:00:50  time: 0.1238  data_time: 0.0031  memory: 864  loss: 0.0688  decode.loss_ce: 0.0305  decode.acc_seg: 92.9966  aux_0.loss_ce: 0.0163  aux_0.acc_seg: 87.6057  aux_1.loss_ce: 0.0220  aux_1.acc_seg: 87.0640
08/02 12:35:59 - mmengine - INFO - Iter(train) [ 9700/10000]  lr: 1.1344e-01  eta: 0:00:37  time: 0.1298  data_time: 0.0033  memory: 864  loss: 0.1297  decode.loss_ce: 0.0651  decode.acc_seg: 71.6496  aux_0.loss_ce: 0.0297  aux_0.acc_seg: 69.3979  aux_1.loss_ce: 0.0349  aux_1.acc_seg: 58.9588
08/02 12:36:12 - mmengine - INFO - Iter(train) [ 9800/10000]  lr: 1.1337e-01  eta: 0:00:25  time: 0.1242  data_time: 0.0031  memory: 864  loss: 0.1223  decode.loss_ce: 0.0587  decode.acc_seg: 51.1257  aux_0.loss_ce: 0.0292  aux_0.acc_seg: 53.5561  aux_1.loss_ce: 0.0345  aux_1.acc_seg: 46.3654
08/02 12:36:25 - mmengine - INFO - Iter(train) [ 9900/10000]  lr: 1.1330e-01  eta: 0:00:12  time: 0.1261  data_time: 0.0032  memory: 864  loss: 0.0845  decode.loss_ce: 0.0380  decode.acc_seg: 86.1641  aux_0.loss_ce: 0.0210  aux_0.acc_seg: 77.3401  aux_1.loss_ce: 0.0255  aux_1.acc_seg: 62.3304
08/02 12:36:37 - mmengine - INFO - Exp name: ZihaoDataset_FastSCNN_20230818_20250802_121506
08/02 12:36:37 - mmengine - INFO - Iter(train) [10000/10000]  lr: 1.1323e-01  eta: 0:00:00  time: 0.1213  data_time: 0.0031  memory: 864  loss: 0.0956  decode.loss_ce: 0.0432  decode.acc_seg: 93.6745  aux_0.loss_ce: 0.0243  aux_0.acc_seg: 90.1726  aux_1.loss_ce: 0.0281  aux_1.acc_seg: 90.2538
08/02 12:36:37 - mmengine - INFO - Saving checkpoint at 10000 iterations
08/02 12:36:38 - mmengine - INFO - per class results:
08/02 12:36:38 - mmengine - INFO - 
+------------+-------+-------+-------+--------+-----------+--------+
|   Class    |  IoU  |  Acc  |  Dice | Fscore | Precision | Recall |
+------------+-------+-------+-------+--------+-----------+--------+
| background | 85.65 | 89.88 | 92.27 | 92.27  |   94.79   | 89.88  |
|    red     |  81.3 | 98.28 | 89.69 | 89.69  |   82.47   | 98.28  |
|   green    | 59.15 | 67.73 | 74.33 | 74.33  |   82.37   | 67.73  |
|   white    | 58.04 | 69.85 | 73.45 | 73.45  |   77.44   | 69.85  |
| seed-black | 61.43 | 78.07 | 76.11 | 76.11  |   74.24   | 78.07  |
| seed-white |  0.0  |  0.0  |  0.0  |  nan   |    nan    |  0.0   |
+------------+-------+-------+-------+--------+-----------+--------+
08/02 12:36:38 - mmengine - INFO - Iter(val) [11/11]    aAcc: 88.9900  mIoU: 57.5900  mAcc: 67.3000  mDice: 67.6400  mFscore: 81.1700  mPrecision: 82.2600  mRecall: 67.3000  data_time: 0.0075  time: 0.0340

可視化數據mmsegmentation\work_dirs\ZihaoDataset-FastSCNN\20250802_121506\vis_data

vis_data目錄下的log_path = './work_dirs/ZihaoDataset-FastSCNN/20250802_121506/vis_data/scalars.json'的文件,用于記錄整體各種指標的記錄情況。

with open(log_path, "r") as f:json_list = f.readlines()eval(json_list[4])

輸出結果如下:

{'lr': 0.11973086417099389,'data_time': 0.004000043869018555,'loss': 0.1377907693386078,'decode.loss_ce': 0.07181963995099068,'decode.acc_seg': 88.35430145263672,'aux_0.loss_ce': 0.032481906749308107,'aux_0.acc_seg': 85.88199615478516,'aux_1.loss_ce': 0.03348922152072191,'aux_1.acc_seg': 81.13632202148438,'time': 0.12697319984436034,'iter': 400,'memory': 863,'step': 400}

針對每一個類別的各種指標可視化
存儲在log文件中:work_dirs/ZihaoDataset-FastSCNN/20250802_121506/20250802_121506.log
我們要讀取的就是這種格式的指標:

+------------+-------+-------+-------+--------+-----------+--------+
|   Class    |  IoU  |  Acc  |  Dice | Fscore | Precision | Recall |
+------------+-------+-------+-------+--------+-----------+--------+
| background | 85.65 | 89.88 | 92.27 | 92.27  |   94.79   | 89.88  |
|    red     |  81.3 | 98.28 | 89.69 | 89.69  |   82.47   | 98.28  |
|   green    | 59.15 | 67.73 | 74.33 | 74.33  |   82.37   | 67.73  |
|   white    | 58.04 | 69.85 | 73.45 | 73.45  |   77.44   | 69.85  |
| seed-black | 61.43 | 78.07 | 76.11 | 76.11  |   74.24   | 78.07  |
| seed-white |  0.0  |  0.0  |  0.0  |  nan   |    nan    |  0.0   |
+------------+-------+-------+-------+--------+-----------+--------+

pth權重保存路徑mmsegmentation\work_dirs\ZihaoDataset-FastSCNN

我將這個pth文件移動到mmsegmentation\pretrained\ZihaoDataset_FastSCNN_20230818.pth這個路徑下

測試方法

最終config配置文件+模型的權重文件

python tools/test.py Zihao-Configs/ZihaoDataset_FastSCNN_20230818.py pretrained/ZihaoDataset_FastSCNN_20230818.pth

默認保存路徑mmsegmentation\work_dirs\ZihaoDataset-FastSCNN\20250802_134015與訓練的保存目錄一致

推理

使用合并后的config配置文件和權重

載入模型

# 模型 config 配置文件
config_file = 'Zihao-Configs/ZihaoDataset_FastSCNN_20230818.py'
# 模型 checkpoint 權重文件
checkpoint_file = 'pretrained/ZihaoDataset_FastSCNN_20230818.pth'
# device = 'cpu'
device = 'cuda:0'
model = init_model(config_file, checkpoint_file, device=device)

推理過程

result = inference_model(model, img_bgr),好像要用BGR格式的圖片進行推理?返回一個result,SegDataSample類型,分為兩個東西,一個是預測的類別,一個是概率,其余就是tensor的使用方法

result = inference_model(model, img_bgr)
result.keys()  ['pred_sem_seg', 'seg_logits']
pred_mask = result.pred_sem_seg.data[0].cpu().numpy()
pred_mask.shape (1280, 1280)
result.seg_logits.data.shape torch.Size([6, 1280, 1280])

批量推理

其實就是將每個圖像都預測一下,然后與掩碼矩陣疊加一下,保存到輸出文件夾下

def process_single_img(img_path, save=False):img_bgr = cv2.imread(img_path)# 語義分割預測result = inference_model(model, img_bgr)pred_mask = result.pred_sem_seg.data[0].cpu().numpy()# 將預測的整數ID,映射為對應類別的顏色pred_mask_bgr = np.zeros((pred_mask.shape[0], pred_mask.shape[1], 3))for idx in palette_dict.keys():pred_mask_bgr[np.where(pred_mask==idx)] = palette_dict[idx]pred_mask_bgr = pred_mask_bgr.astype('uint8')# 將語義分割預測圖和原圖疊加顯示pred_viz = cv2.addWeighted(img_bgr, opacity, pred_mask_bgr, 1-opacity, 0)# 保存圖像至 outputs/testset-pred 目錄if save:save_path = os.path.join('../','../','../','outputs', 'testset-pred', 'pred-'+img_path.split('/')[-1])cv2.imwrite(save_path, pred_viz)

攝像頭推理(實時分割)

但是我沒有攝像頭😒

python demo/video_demo.py 0 Zihao-Configs/ZihaoDataset_FastSCNN_20230818.py pretrained/ZihaoDataset_FastSCNN_20230818.pth --device cuda:0 --opacity 0.5 --show

可視化

官方提供的可視化分割圖片的代碼

根據在Dataset中定義METAINFO來繪制掩碼矩陣的,最后返回處理好的圖片

 METAINFO = {'classes':['background', 'red', 'green', 'white', 'seed-black', 'seed-white'],'palette':[[127,127,127], [200,0,0], [0,200,0], [144,238,144], [30,30,30], [251,189,8]]}
from mmseg.apis import show_result_pyplot
img_viz = show_result_pyplot(model, img_path, result, opacity=0.8, title='MMSeg', out_file='outputs/K1-4.jpg')
plt.figure(figsize=(14, 8))
plt.imshow(img_viz)
plt.show()

批量可視化代碼:用于獲得n行n列的圖像

不用記憶

# n 行 n 列可視化
n = 4fig, axes = plt.subplots(nrows=n, ncols=n, figsize=(16, 10))for i, file_name in enumerate(os.listdir()[:n**2]):img_bgr = cv2.imread(file_name)# 可視化axes[i//n, i%n].imshow(img_bgr[:,:,::-1])axes[i//n, i%n].axis('off') # 關閉坐標軸顯示
fig.suptitle('Semantic Segmentation Predictions', fontsize=30)
# plt.tight_layout()
plt.savefig('../K3.jpg')
plt.show()

在這里插入圖片描述







數據集的存儲要求(待續)

整數掩碼/掩膜

  • 存儲格式必須是png,目的是為了無損
    在這里插入圖片描述
    像素太小,什么都看不出來。

在這里插入圖片描述

雖然掩碼是一個整數矩陣,但是保存為png格式時,必須存儲3通道

img.shape
mask.shape
(300, 440, 3)
(300, 440, 3)

整數掩碼轉換為RGB通道可視化
取圖像的任一一個通道,關鍵是使用np.where()

mask = mask[:,:,0]# 將整數ID,映射為對應類別的顏色
viz_mask_bgr = np.zeros((mask.shape[0], mask.shape[1], 3))
for idx in palette_dict.keys():viz_mask_bgr[np.where(mask==idx)] = palette_dict[idx]
viz_mask_bgr = viz_mask_bgr.astype('uint8')# 將語義分割標注圖和原圖疊加顯示
opacity = 0.1 # 透明度越大,可視化效果越接近原圖
label_viz = cv2.addWeighted(img, opacity, viz_mask_bgr, 1-opacity, 0)

在這里插入圖片描述

opencv的注意事項

注意opencv載入圖片是bgr格式,要進行一個轉換img_bgr[:,:,::-1]

img_bgr = cv2.imread(img_path)

在這里插入圖片描述
在這里插入圖片描述




參考文獻

同濟子豪兄

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917415.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917415.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917415.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

InfluxDB 與 Node.js 框架:Express 集成方案(二)

四、優化與注意事項 (一)性能優化技巧 連接池管理:使用連接池可以有效減少創建和銷毀數據庫連接的開銷。在 Node.js 中,可以借助influx模塊結合第三方連接池庫,如generic-pool來實現連接池的管理 。通過設置連接池的…

單位長度上的RC參數

1inch1000mil25.4mm2.54cm 使用SI9000計算導線上電容電感參數并使用Q2D進行仿真驗證。使用SI9000建立一個阻抗為50歐的微帶線模型,后對該模型進行1GHz頻域計算 通過計算得到結果,可知1GHz頻率下單位傳輸線上的RLGC參數使用SI9000計算好單位長度上的RLGC參…

基于Dockerfile 部署一個 Flask 應用

Docker 與 Python:容器化部署應用,實現快速發布與彈性伸縮 以下是一個簡單的 Flask 應用 # app.py - 一個簡單的Flask應用 from flask import Flask import osapp Flask(__name__)app.route("/") def hello():env os.environ.get(FLASK_ENV,…

DFT設計中的不同階段介紹

在DFT(Design for Test,可測試性設計)軟件開發中,針對設計檢測的完整流程通常包含Setup(設置)、Analysis(分析)、Insertion(插入)和Verification(…

自動化測試準備工作:概念篇

自動化 什么是自動化? 超市的自動閘門,不需要手動的開門關門生活中的自動動化案例有效的減少了人力的消耗,同時也提高了生活的質量。 軟件自動化測試同理,通過編寫自動化測試程序(減少人力和時間的消耗,提高軟件的…

每日主題切換網頁:用純前端技術打造隨心情變化的動態界面

🎨 每日主題切換網頁:用純前端技術打造隨心情變化的動態界面 項目地址:https://github.com/hhse/daily-theme-switcher 在線演示:https://hhse.github.io/daily-theme-switcher 這里寫目錄標題🎨 每日主題切換網頁&…

TOPSIS(Technique for Order Preference by Similarity to Ideal Solution )簡介與簡單示例

前言 提醒: 文章內容為方便作者自己后日復習與查閱而進行的書寫與發布,其中引用內容都會使用鏈接表明出處(如有侵權問題,請及時聯系)。 其中內容多為一次書寫,缺少檢查與訂正,如有問題或其他拓展…

uniapp 富文本rich-text 文本首行縮進和圖片居中

1. uniapp 富文本rich-text 文本首行縮進和圖片居中 1.1. rich-text 文本首行縮進使用 rich-text 組件渲染html格式的代碼,常常因為不能自定義css導致文本不能縮進,以及圖片不能居中等問題,這里可以考慮使用js的replace方法,替換…

Apple基礎(Xcode③-Singbox Core)

brew install go open ~/.bash_profile export PATH="$PATH:$(go env GOPATH)/bin" 先確保工具鏈完整 go install github.com/sagernet/gomobile/cmd/gomobile@v0.1.4 go install github.com/sagernet/gomobile/cmd/gobind@v0.1.4 gomobile init -v # 關鍵:-v …

JVM學習日記(十四)Day14——性能監控與調優(一)

經過前幾篇的鋪墊,現在開始正式進入調優篇,也是大火實際用的到的和感興趣的,但是前期的知識積累還是有必要的,所以還對JVM基礎沒什么了解的,建議還是回看主包的前幾篇內容,當然看其他優秀的博主也是可以的。…

使用 Elasticsearch 和 AI 構建智能重復項檢測

作者:來自 Elastic Dayananda Srinivas 探索組織如何利用 Elasticsearch 檢測和處理貸款或保險申請中的重復項。 Elasticsearch 帶來了大量新功能,幫助你為你的使用場景構建最佳搜索方案。深入了解我們的示例 notebooks,開始免費云試用&#…

如何在不依賴 Office 的情況下轉換 PDF 為可編輯文檔

在日常工作里,我們經常需要處理各種文件格式的轉換問題,像Word轉PDF或者PDF轉Excel這樣的需求屢見不鮮。它是一款功能全面的PDF轉換工具,能夠幫助你輕松應對多種文檔處理任務。不僅能夠實現PDF與其他格式之間的轉換,如Word、Excel…

嵌入式學習筆記-MCU階段--DAY09

1. oled屏幕的接口IIC應用場合:2.IIC通信原理概念:IIC(Inter-Integrated Circuit)其實是IICBus簡稱,所以中文應該叫集成電路總線,它是一種串行通信總線,使用多主從架構,由飛利浦公司…

解決 Node.js 托管 React 靜態資源的跨域問題

在 Node.js 項目中托管 React 打包后的靜態資源時,可能會遇到跨域問題(CORS)。以下是幾種解決方案: 1. 使用 Express 中間件設置 CORS 頭 const express require(express); const path require(path); const app express();// …

【Linux】多路轉接之epoll

優化poll進行拷貝的開銷poll開銷過大將整個 pollfd 數組拷貝到內核態,以便內核檢查 fd 是否就緒(從用戶態 → 內核態)。內核檢查 fd 狀態,并填充 revents。將 pollfd 數組從內核態拷貝回用戶態,讓應用程序可以讀取 rev…

下載一個JeecgBoot-master項目 導入idea需要什么操作啟動項目

官網:開發環境搭建 | JEECG 文檔中心 一般做開發的電腦里都是有的,沒有的只能下載了 前端安裝 node官網:https://nodejs.org/zh-cnpnpm安裝:通過命令 后端安裝: jdk17 :https://www.oracle.com/cn/java/technologies/downloads/#java17maven :https://m…

解決 InputStream 只能讀取一次問題

是的,InputStream 的一個重要特性是它通常只能被讀取一次。這是因為:輸入流通常是單向的、順序訪問的數據源很多流(如網絡流、文件流)讀取后指針就移動了,無法回退有些流(如Socket流)甚至讀取后…

數據分析面試題

技都測試 1、請列舉5個 Excel 中常用的函數及寫法。[ if ] IF(A1>60, "及格", "不及格") —— 若 A1 單元格數值≥60,返回 “及格”,否則返回 “不及格”。IF(B2>100, B2*0.8, B2) —— 若 B2 數值 > 100&#xff0c…

【07】VisionMaster入門到精通——Blob分折

文章目錄0 視屏講解與演示1 案例演示2 參數詳解1 運行參數0 視屏講解與演示 1 案例演示 周長使能查找U型槽 短軸使能查找U型槽 面積篩選區域 當條件不符合是,該模塊顯示紅色,狀態為NG 顯示二值圖像 顯示Blob圖像 2 參數詳解 Blob分折,…

解釋 MySQL 中的 EXPLAIN 命令的作用和使用場景

解釋 MySQL 中的 EXPLAIN 命令的作用和使用場景 總結性回答 EXPLAIN 是 MySQL 中用于分析 SQL 查詢執行計劃的命令,它能展示 MySQL 如何執行一個查詢,包括使用的索引、表連接順序、掃描行數等關鍵信息。主要用于查詢性能優化,幫助開發者識別潛…