当前位置: 首页 > news >正文

传知代码-智慧医疗:纹理特征VS卷积特征(论文复现)

代码以及视频讲解

本文所涉及所有资源均在传知代码平台可获取

论文链接:https://www.sciencedirect.com/science/article/abs/pii/S1076633223003537?__cf_chl_rt_tk=J9Aipfxyk5d.leu48P20ePFNd4B2aunaSmzVpXCg.7g-1721292386-0.0.1.1-6249

论文概述

在这里插入图片描述

今天我们把视线转回到AI应用的另外一个大领域——智慧医疗,来看看目前人工智能在这一领域的最新进展。

发表在影像学经典期刊《Academic Radiology》上的论文《Development and Validation of a Feature-Based Broad-Learning System for Opportunistic Osteoporosis Screening Using Lumbar Spine Radiographs》第一次阐述了在智慧医疗领域,纹理特征和卷积特征对于医学影像信息的抽取功能有什么差异,并给出了具体实验验证和指标分析。

作者指出,“宽度学习系统(BLS)的主要优势之一是其简单的平面结构,这使得学习特征表示和分类数据变得容易。与具有复杂架构的其他机器学习算法不同,BLS 具有简洁的设计,便于特征表示学习和数据分类。这种简单的结构还使得模型能够在大数据集上高效运行,而不需要大量的计算资源。BLS 模型的另一个优势是其权重通过解析计算确定,从而降低了过拟合的风险。就基于纹理特征(RF)的 BLS 模型而言,它产生的结果比基于深度卷积特征(DF) 的 BLS 模型更容易解释。原因是 RF 与 BMD 高度相关,这使得理解输入特征与输出之间的关系变得更容易。DF 可以捕捉高级语义信息,这对于某些类型的数据可能是有益的。然而,在这种情况下,基于 RF 的 BLS 模型的分类性能高于基于 DF 的 BLS 模型,表明 RF 更适合这个特定任务。输入特征的选择,例如 RF 或 DF,会影响结果的可解释性和准确性,在开发 BLS 模型时应谨慎考虑。”

纹理特征和深度卷积特征

在这里插入图片描述

  • 纹理特征是图像处理和计算机视觉中常用的概念,用于描述图像中像素的局部模式和结构,帮助区分不同类型的物体或场景。常见的纹理特征包括统计特征、频域特征、模型特征和结构特征。统计特征如灰度共生矩阵(GLCM)和局部二值模式(LBP),通过计算像素间的联合概率分布和局部二进制模式来描述纹理。频域特征如傅里叶变换和小波变换,通过分析图像的频率成分和多尺度细节来捕捉纹理信息。模型特征如自回归模型(AR),假设像素值可以用其周围像素的线性组合来表示,从而描述纹理。结构特征如边缘方向直方图(HOG)和Gabor滤波器,通过计算图像中局部梯度方向分布和使用一组不同方向和尺度的滤波器来提取纹理特征。这些纹理特征在图像分割、分类、模式识别和检索等应用中非常重要,例如在医学图像分析中可以检测和分类不同类型的组织,在遥感图像处理中可以区分不同类型的地表覆盖。

  • 深度卷积特征是由深度卷积神经网络(CNN)提取的特征,用于图像处理和计算机视觉任务。CNN通过多个卷积层、池化层和全连接层的级联,能够从原始图像中自动学习并提取出层次化的特征表示。在CNN中,低层的卷积层通常提取图像中的边缘、纹理和简单形状等低级特征;随着网络的加深,中间层会捕捉到更复杂的模式和结构,如角点、轮廓和局部区域;高层的卷积层则能够提取到语义级别的特征,如物体的类别和具体形状等高级特征。通过这种层次化的特征提取,CNN能够在图像分类、目标检测、图像分割等任务中取得显著的效果。卷积操作通过滑动窗口的方式,将滤波器(卷积核)应用于输入图像,生成特征图。每个卷积核能够检测特定的特征模式,如边缘或纹理。池化层则通过下采样操作,减小特征图的尺寸,从而降低计算复杂度并提高模型的鲁棒性。深度卷积特征的一个重要优势是它们能够自动从大量标注数据中学习特征表示,而无需人工设计特征。这使得深度学习模型能够在各种复杂的视觉任务中表现出色。此外,预训练的深度卷积网络(如VGG、ResNet、Inception等)可以用于迁移学习,通过在新的任务上进行微调,迅速适应不同的应用场景。总之,深度卷积特征在现代计算机视觉领域具有重要的地位,广泛应用于图像分类、目标检测、图像分割、图像生成等多种任务中,显著提升了这些任务的性能和准确性。

算法流程

在这里插入图片描述

下面我们来介绍一下论文中所设计的算法流程,原论文采用了两种不同方面的特征提取技术——纹理特征和深度卷积特征,并比较了他们的性能效果。对于纹理特征,论文采用了GLCM、GLRLM、GLDM、GLSZM、NGTDM和一阶形态学特征融合提取的方法来全面地提取到医学影像中的纹理信息。对于深度卷积特征,论文中使用了最经典的ResNet18和VGG11两种深度卷积网络来对医学影像进行特征提取。

下面我们将具体地讲解这篇文章所用到的数据预处理方法,纹理特征提取、深度卷积特征提取和分类网络搭建这四个步骤

数据预处理方法

首先,感兴趣区域(ROIs)在L1-L4椎体(前后视图)上手动分割,以确保诊断模型与DXA测试之间的准确对应。该操作使用开源软件ITK-SNAP (www.itk-snap.org)进行。分割由一位具有6年肌肉骨骼影像经验的放射科医生完成,并由一位具有20年肌肉骨骼影像经验的高级放射科医生验证。阅片者对患者的临床信息和DXA结果均不知情。

为了规范化,ROI图块被转换为灰度图像,并使用双线性插值方法调整为128 × 64像素。这种方法在图像处理应用中常用,因为它在计算效率和图像质量之间提供了一种折衷。使用对比度受限自适应直方图均衡化(CLAHE)对图像进行增强,以提高对比度并提供更清晰的特征细节可视化。CLAHE在增强医学图像方面具有优势,因为它不会增加噪声,并能保留大部分图像纹理细节。使用定量度量结构相似性指数(SSIM)评估CLAHE的效率。在训练集中的直方图均衡化后,SSIM方差显著降低(0.00102 vs. 0.00056,P < .0001),在测试集中也是如此(0.00196 vs. 0.00102,P < .0001)。图2展示了原始和增强的ROI图像及其灰度直方图。

为了处理数据集样本分布不均的问题,使用了合成少数过采样技术(SMOTE)。SMOTE分析少数样本,根据少数样本人工合成额外样本,并将其添加到数据集中,以防止模型学到的知识过于专门化而缺乏广泛性。

纹理特征提取

论文作者们利用PyRadiomics 3.0 从每个感兴趣区域(ROI)中提取二维形态特征和纹理特征。形态特征包括网格表面、像素表面、周长、周长与表面比、球形度、球形不对称、长轴长度、短轴长度和伸长率。纹理特征包括灰度共生矩阵(n = 24)、灰度游程长度矩阵(n = 16)、灰度尺寸区矩阵(n = 16)、相邻灰度差矩阵(n = 5)和灰度依赖矩阵(n = 14)。这些特征与多种骨骼特性有关,包括骨密度(BMD)、骨微观结构和骨组织成分。形态特征和纹理特征的计算和提取是根据图像生物标记标准化倡议(Image Biomarker Standardisation Initiative)指南进行的,以确保一致性和标准化。

深度卷积特征提取

他们使用了两种广泛应用的卷积神经网络(CNN)架构,即ResNet18和VGG11,作为任务的骨干网络。ResNet18由四个残差块组成,每个残差块包含两个卷积层,配有批量归一化和ReLU激活函数。这些层之后是一个快捷连接,将输入添加到第二个卷积层的输出中。而VGG11的特点是其架构中一致使用小的3×3卷积滤波器,这种方法确保了较大的感受野,同时保持了相对较少的参数。VGG11架构由五个堆叠的卷积层组成,称为“vggblocks”,并使用ReLU激活函数。它采用最大池化,并以几层全连接层结束。

他们利用了预训练CNN与迁移学习的强大功能,有效地从图像数据中生成并提取准确且富有表现力的特征。具体来说,他们使用了已经在ImageNet数据集上预训练的ResNet18和VGG11模型。在特征提取过程中,他们冻结了大部分卷积模块,并添加了新的展平和全连接层,以获得所需的特征维度。具体来说,对于VGG11,他们选择并冻结了五个vggblocks。随后,添加了自适应平均池化层和全连接层,以获得4096维的特征表示。对于ResNet18,他们冻结了前四层,每层包含两个Basicblock模块,并添加了自适应平均池化层,以实现512维的特征表示。

分类网络搭建

在这里插入图片描述

BLS基于随机向量功能连接神经网络和伪逆理论设计,使其能够快速、增量地学习,并且无需重新训练即可重构系统。BLS模型(如图所示)由输入层、特征和增强节点复合层以及输出层组成。在复合层中,使用不同组的随机权重从输入数据生成多个映射特征组,形成特征节点。此外,特征节点被增强为增强节点,每个增强节点使用不同的随机权重生成。输出是通过所有连接到输出层的特征节点和增强节点计算得出的。

BLS的一个显著优势是训练和输出结果所需的时间非常少。由于采用伪逆理论,输出层的权重可以通过简单的矩阵运算与上一层的数据进行快速计算和更新。RF和DF被用作BLS模型的输入,用于图像分类。

代码复现

本文的复现代码我放在了附件当中,大家可以自行下载下来进行对比实验。下面我将结合伪代码流程图对代码的逻辑进行简单地讲解

BLS_Model.py文件——分类器搭建

1. 初始化必要的库和函数- numpy, sklearn.preprocessing, numpy.random, scipy.linalg, time, sklearn.metrics- 函数: show_accuracy, tansig, sigmoid, linear, tanh, relu, pinv, shrinkage, sparse_bls2. 定义函数 show_accuracy- 输入: predictLabel, Label- 计算正确预测的数量- 使用混淆矩阵计算灵敏度(Sen), 特异度(Spe), 阴性预测值(npv), 阳性预测值(ppv), AUC- 返回: 准确率, Sen, Spe, npv, ppv, auc, 预测标签, 实际标签3. 定义激活函数 tansig, sigmoid, linear, tanh, relu4. 定义函数 pinv- 输入: A, reg- 计算伪逆矩阵- 返回: 伪逆矩阵5. 定义函数 shrinkage- 输入: a, b- 计算收缩结果- 返回: z6. 定义函数 sparse_bls- 输入: A, b- 设置参数 lam, itrs- 初始化变量- 迭代计算稀疏BLS- 返回: wk7. 定义函数 BLS_AddFeatureEnhanceNodes- 输入: train_x, train_y, test_x, test_y, N1, N2, N3, L, M1, s, c, M2, M3- 初始化变量 u, train_x, FeatureOfInputDataWithBias, OutputOfFeatureMappingLayer, Beta1OfEachWindow, distOfMaxAndMin, minOfEachWindow, train_acc, test_acc, train_time, test_time- 记录开始时间 time_start- 对每个窗口进行以下操作:- 生成随机权重- 计算窗口特征- 预处理特征- 计算稀疏BLS- 计算窗口输出- 记录最大最小值- 规范化窗口输出- 更新输出特征映射层- 生成增强层输入- 计算增强层权重- 计算增强层输出- 计算输出层输入- 计算输出权重- 记录结束时间 time_end- 计算训练时间 trainTime- 计算训练输出- 调用 show_accuracy 计算训练准确率等- 记录训练准确率和时间- 对测试数据进行同样的处理- 记录结束时间 time_end- 计算测试时间 testTime- 计算测试输出- 调用 show_accuracy 计算测试准确率等- 记录测试准确率和时间- 返回: testAcc, trainAcc, Sentr, Spetr, npvtr, ppvtr, auctr, Sen, Spe, npv, ppv, auc, predtt, labeltt, predtr, labeltr

在BLS_Model.py文件中,我实现了基于随机向量功能连接神经网络和伪逆理论的快速增量学习方法。代码首先导入必要的库和函数,包括用于数据预处理、矩阵运算、时间测量和模型评估的库。定义了一些辅助函数,例如激活函数(tansig、sigmoid、linear、tanh、relu),用于计算伪逆矩阵的函数(pinv),以及用于稀疏BLS计算的函数(sparse_bls)。主要的函数是BLS_AddFeatureEnhanceNodes,它实现了BLS模型的训练和测试。首先对输入数据进行预处理,将其标准化并添加偏置项。然后,在特征映射层中,使用不同组的随机权重生成多个映射特征组,形成特征节点,并通过稀疏BLS方法计算每个窗口的权重和输出。接着,在增强层中,生成增强节点,并计算其输出。在输出层中,结合特征映射层和增强层的输出,计算输出权重。训练阶段,记录训练时间,并计算训练输出,通过show_accuracy函数评估模型的训练准确率、灵敏度、特异度、阴性预测值、阳性预测值和AUC。同样地,在测试阶段,对测试数据进行同样的处理,记录测试时间,并评估模型的测试性能。最终,返回测试准确率、训练准确率及其他评估指标。整个过程旨在通过快速、增量地学习,从输入数据中提取特征,并通过简单的矩阵运算进行模型的更新和评估。

pyradioextraction.py文件——纹理特征提取

1. 导入必要的库和模块
2. 定义函数 listdirInMac:a. 初始化空列表 listsb. 遍历输入列表 list:i. 如果项的第一个字符是 '.',跳过该项ii. 否则,将该项添加到 listsc. 返回 lists3. 定义函数 catch_features:a. 检查 imagePath 或 maskPath 是否为空:i. 如果为空,抛出异常b. 初始化 settings 字典并设置提取参数c. 创建 RadiomicsFeatureExtractor 实例 extractor,传入 settingsd. 禁用所有特征e. 启用所需的特征类别(shape2D, glcm, glszm, glrlm, ngtdm, gldm)f. 执行特征提取并获取结果 resultg. 初始化空列表 feature_names 和 feature_valuesh. 遍历 result 中的每个键值对:i. 如果键匹配特定的特征类别,打印键和值,将键和值添加到相应的列表i. 打印特征维度和特征名称j. 返回 feature_values 和 feature_names4. 在 main 函数中:a. 定义 image_dir 和 mask_dir 的路径b. 获取患者列表 patient_list 并使用 listdirInMac 函数过滤c. 对 patient_list 进行排序d. 初始化空列表 all_data 和 all_namee. 遍历 patient_list 中的每个患者:i. 打印患者名称ii. 遍历患者文件夹中的每个文件:- 如果文件名是 'data.nii.gz',设置 imagePath- 如果文件名是 'zw.nii.gz',设置 maskPathiii. 调用 catch_features 函数提取特征,并保存结果到 all_data,特征名称保存到 all_namef. 打印所有数据和特征名称g. 打开 CSV 文件进行写入:i. 写入列名(特征名称)ii. 写入每行特征数据

这段代码的目的是从医学图像中提取纹理特征。首先,代码导入了一些必要的库和模块,包括用于处理图像的SimpleITK和用于特征提取的pyradiomics。定义了一个函数listdirInMac来过滤掉隐藏文件。主函数catch_features接受图像和掩码的路径,使用特定的设置来初始化一个特征提取器,并提取2D形状特征、灰度共生矩阵(GLCM)、灰度大小区域矩阵(GLSZM)、灰度运行长度矩阵(GLRLM)、灰度依赖矩阵(GLDM)和邻域灰度差矩阵(NGTDM)的特征。这些特征被保存为名称和值,并返回给主程序。

主程序首先定义了图像目录和掩码目录的路径,并获取患者列表。对于每个患者,找到相应的图像和掩码文件路径,并调用catch_features函数提取特征。所有提取的特征被保存到一个CSV文件中,方便后续分析和处理。

这个过程通过一系列的步骤和函数调用,实现了从医学图像中自动提取纹理特征并保存到文件中,便于后续的分析和研究。

CNNextraction.py 文件——深度卷积特征提取

1. 导入必要的库和模块- urllib- torch- matplotlib.pyplot as plt- torch.nn as nn- torchvision.models- torchvision.transforms- numpy as np- cv2- os- ssl- PIL.Image- scipy.io as scio- urllib3.util.url2. 设置 HTTPS 上下文3. 定义函数 listdirInMac:a. 初始化空列表 listsb. 遍历输入列表 list:i. 如果项的第一个字符是 '.',跳过该项ii. 否则,将该项添加到 listsc. 返回 lists4. 定义类 FeatureExtractor (继承自 nn.Module):a. 初始化方法:i. 提取 VGG-16 特征层并将其设置为 nn.Sequentialii. 提取 VGG-16 的平均池化层iii. 转换图像为一维向量iv. 提取 VGG-16 全连接层的第一部分v. 添加新的全连接层(fc2)b. 前向传播方法:i. 通过特征层提取特征ii. 通过池化层提取特征iii. 打印特征的形状iv. 转换张量为 numpy 数组并重塑v. 使用 matplotlib 显示特征图vi. 返回提取的特征5. 定义类 FeaExtractor (继承自 nn.Module):a. 初始化方法:i. 提取模型的卷积层、批量归一化层、激活函数、最大池化层和自适应平均池化层ii. 提取模型的各个层iii. 转换图像为一维向量b. 前向传播方法:i. 通过各个层提取特征ii. 转换张量为 numpy 数组并重塑iii. 使用 matplotlib 显示特征图iv. 返回提取的特征6. 加载预训练的 EfficientNet 模型
7. 替换 EfficientNet 的第一个卷积层
8. 将模型移动到 GPU
9. 定义图像预处理步骤10. 定义函数 extract:a. 初始化空列表 featuresb. 获取并过滤路径中的文件列表c. 对文件列表进行排序d. 遍历文件列表:i. 加载并预处理每个图像ii. 将图像合并为一个批次并添加一个维度iii. 将图像移动到 GPUiv. 禁用梯度计算并提取特征v. 将提取的特征转换为 numpy 数组并保存到 features 列表e. 将特征转换为 numpy 数组并返回11. 如果是主程序:a. 设置训练数据路径

在这段代码中,我使用预训练的ResNet模型提取图像特征并保存到MAT文件中。首先,导入了必要的库,包括PyTorch、PIL、Matplotlib等,并设置了HTTPS上下文以跳过SSL验证。定义了辅助函数listdirInMac,用于过滤目录列表,去掉以’.'开头的隐藏文件或目录。定义了特征提取器类FeatureExtractor,继承自nn.Module,用于从ResNet模型中提取特征。初始化方法中提取了ResNet的特征层、平均池化层,并添加了一个新的全连接层。在前向传播方法中,通过特征层和池化层提取特征,并使用Matplotlib显示特征图。代码还定义了另一个特征提取器类FeaExtractor,未被使用,其作用类似于FeatureExtractor。

然后,代码使用torchvision.models加载预训练的ResNet模型,并将其移动到GPU,同时定义了一系列图像预处理步骤。接着,定义了特征提取函数extract,该函数初始化一个空列表用于存储特征,获取图像目录中的文件列表并进行排序,遍历文件列表,加载并预处理每张图像,将预处理后的图像合并为一个批次,移动到GPU,并使用新定义的模型提取特征,最后将提取到的特征保存到MAT文件中。

main.py——顶层文件

开始
|
|-- 函数: Texture_preparation()
|   |
|   |-- 从 "train_dataset_smote_84.mat" 加载 train_data
|   |-- 打印 train_data 的形状
|   |-- 从 "test_features.mat" 加载 test1_data
|   |-- 打印 test1_data 的形状
|   |-- 从 "train_dataset_smote_84.mat" 加载 train_label
|   |-- 打印 train_label 的形状
|   |-- 从 "test1_flag.mat" 加载 test1_label
|   |-- 删除 test1_label 中的特定行
|   |-- 打印 test1_label 的形状
|   |-- 返回 train_data, train_label, test1_data, test1_label
| 
|-- 主块||-- 定义参数: N1, N2, N3, L, M1, s, c, M2, M3||-- 调用 Texture_preparation() 并将返回值赋给 train_data, train_label, test1_data, test1_label||-- 打印 test1_data|-- 打印 test1_label||-- 调用 BLS_AddFeatureEnhanceNodes() 并将返回值赋给各个指标变量||-- 打印测试和训练的准确率及其他指标
|
结束

这个文件起到了一个集成的作用,用于将不同的特征数据加载到内存环境中,并输入到BLS分类器中进行对比实验,从而分析不同特征对医学影像信息的提取性能。

实验结果

在本次实验中,由于原论文的数据涉及病人隐私无法公开,因此我使用了同样类型的医学公开数据集进行实验,链接如下:https://data.mendeley.com/datasets/fxjm8fb6mw

在这里插入图片描述

如图所示,我们按照论文步骤,将三种不同类型的特征分别输入到BLS分类器中进行性能的对比实验,可以得到与论文中一致的结果。在到达相似的训练程度时,输入纹理特征的模型相比其他两种特征模型能够在各项指标上取得更好的结果。特别是在医疗领域最为关注的曲线下面积(AUC)这一项中,该模型拉开了比较大的差距。因此我们可以推测出,在基于纹理特征(RF)的BLS模型与基于深度卷积特征(DF)的BLS模型的对比中,前者的结果更容易解释。这是因为RF与BMD高度相关,使得理解输入特征与输出结果之间的关系更加直观。尽管DF可以捕捉高级语义信息,在某些数据类型中可能更有利,但在这个特定任务中,基于RF的BLS模型的分类性能优于基于DF的BLS模型,表明RF在此任务中更为适用。

论文中结果:
在这里插入图片描述
在这里插入图片描述

使用方式

下面我们来介绍一下如何使用附件代码来进行运行三种不同的特征模型。文件格式如下所示:

在这里插入图片描述

一键运行

前面已经为大家介绍了各个文件的功能,这里需要注意的,为了便于理解,我将main.py文件拆分成了三个文件BLS_ResnetFeatures.py、BLS_TextureFeatures.py和BLS_VGGFeatures.py,分别代表了三种不同的特征输入BLS分类器进行实验。在这里为了方便大家一键运行,我已经将原始数据进行处理好,三种类型的特征分别存入了CNNFeatures(Resnet特征)、TextureFeatures(纹理特征)和VGGFeatures(VGG特征)文件夹中。大家进入对应的主文件中就可以一键运行实验。

本地训练

如果大家还希望能使用自己的私人数据集进行训练,可以按照我前面所说的算法步骤进行一步步地处理。使用pyradioextraction.py文件可以直接对医学影像数据进行纹理特征的提取,使用CNNextraction.py可以对转换后的医学图像进行两种深度卷积特征的提取。

提取纹理特征时注意要在pyradioextraction.py文件中修改对应的文件路径
在这里插入图片描述

提取深度卷积特征时同样要注意文件保存路径问题
在这里插入图片描述

处理结束后就可以看到在目录下会生成相应的文件,接下来输入到BLS分类器中就可以进行训练了!

环境配置

  • python版本3.6及以上;
  • 预先安装第三方库:radiomics、SimpleITK、torch、torchvision和scipy

源码下载

相关文章:

传知代码-智慧医疗:纹理特征VS卷积特征(论文复现)

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 论文链接&#xff1a;https://www.sciencedirect.com/science/article/abs/pii/S1076633223003537?__cf_chl_rt_tkJ9Aipfxyk5d.leu48P20ePFNd4B2aunaSmzVpXCg.7g-1721292386-0.0.1.1-6249 论文概述 今天我们把视线…...

数据结构中的八大金刚--------八大排序算法

目录 引言 一&#xff1a;InsertSort(直接插入排序) 二&#xff1a;ShellSort(希尔排序) 三&#xff1a;BubbleSort(冒泡排序) 四&#xff1a; HeapSort(堆排序) 五&#xff1a;SelectSort(直接选择排序) 六&#xff1a;QuickSort(快速排序) 1.Hoare版本 2.前后指针版本 …...

ACC2.【C语言】经验积累 栈区简单剖析

int main() {int i0;int arr[10]{1,2,3,4,5,6,7,8,9,10};for (i0;i<12;i){arr[i]0;printf("A");}return 0; } 执行后无限打印A 在VS2022&#xff0c;X86,Debug环境下&#xff0c;用监视后&#xff0c;原因是arr[12]的地址与i的地址重合&#xff08;数组越界&…...

c# 索引器

索引器&#xff08;Indexer&#xff09;允许你像访问数组一样&#xff0c;通过索引访问对象的属性或数据。索引器的主要用途是在对象内部封装复杂的数据结构&#xff0c;使得数据访问更加直观。下面是关于 C# 索引器的详细解释及示例&#xff1a; 基本语法 索引器的语法类似于…...

低代码如何加速数字化转型

数字化转型&#xff0c;正日益决定企业成功的关键。这里的一个关键因素是它可以以更快的速度和质量来实施技术计划。在当今瞬息万变的商业环境中&#xff0c;战略性地采用低代码平台对于旨在加快上市时间、增强业务敏捷性和促进跨团队无缝协作的首席技术官来说至关重要。日益增…...

Pytest进阶之fixture的使用(超详细)

目录 Fixture定义 Fixture使用方式 作为参数使用 Fixture间相互调用(作为参数调用) 作为conftest.py文件传入 Fixture作用范围Scope function class module session Fixture中params和ids Fixture中autouse Fixture中Name 总结 pytest fixture 是一种用来管理测试…...

GitHub 详解教程

1. 引言 GitHub 是一个用于版本控制和协作的代码托管平台&#xff0c;基于 Git 构建。它提供了强大的功能&#xff0c;使开发者可以轻松管理代码、追踪问题、进行代码审查和协作开发。 2. Git 与 GitHub 的区别 Git 是一个分布式版本控制系统&#xff0c;用于跟踪文件的更改…...

边界网关IPSEC VPN实验

拓扑&#xff1a; 实验要求&#xff1a;通过IPSEC VPN能够使PC2通过网络访问PC3 将整个路线分为三段 IPSEC配置在FW1和FW2上&#xff0c;在FW1与FW2之间建立隧道&#xff0c;能够传递IKE&#xff08;UDP500&#xff09;和ESP数据包&#xff0c;然后在FW1与PC2之间能够流通数据…...

力扣高频SQL 50题(基础版)第六题

文章目录 1378. 使用唯一标识码替换员工ID题目说明思路分析实现过程结果截图总结 1378. 使用唯一标识码替换员工ID 题目说明 Employees 表&#xff1a; ---------------------- | Column Name | Type | ---------------------- | id | int | | name | varchar | ------…...

在一个事物方法中开启新事物,完成对数据库的修改

在Java中&#xff0c;使用Transactional注解来管理事务非常常见。但是&#xff0c;在一个已经标记为Transactional的方法内部调用另一个也标记了Transactional的方法时&#xff0c;如果不正确处理&#xff0c;可能会导致一些意料之外的行为。这是因为默认情况下&#xff0c;Spr…...

ffmpeg的vignetting filter

vignetting filter是暗角过滤器 vignetting filter在官网是vignette。但是我查了一下&#xff0c;vignetting应该是正确的表达&#xff0c;vignette是什么鬼&#xff1f; 官网参数 官书参数 参数解释 angle,x0,y0可以使用表达式。 angle&#xff1a;不知道什么意思&#xf…...

商场导航系统:从电子地图到AR导航,提升顾客体验与运营效率的智能解决方案

商场是集娱乐、休闲、社交于一体的综合性消费空间&#xff0c;随着商场规模的不断扩大和布局的日益复杂&#xff0c;顾客在享受丰富选择的同时&#xff0c;也面临着寻路难、店铺曝光率低以及商场管理效率低下等挑战。商场导航系统作为提升购物体验的关键因素&#xff0c;其重要…...

vue3中父子组件的双向绑定defineModel详细使用方法

文章目录 一、defineProps() 和 defineEmits()二、defineModel() 的双向绑定2.1、基础示例2.2、定义类型2.3、声明prop名称2.4、其他声明2.5、绑定多个值2.6、修饰符和转换器2.7、修饰符串联 一、defineProps() 和 defineEmits() 组件之间通讯&#xff0c;通过 props 和 emits…...

耳机、音响UWB传输数据模组,飞睿智能低延迟、高速率超宽带uwb模块技术音频应用

在数字化浪潮席卷全球的今天&#xff0c;无线通信技术日新月异&#xff0c;其中超宽带&#xff08;Ultra-Wideband&#xff0c;简称UWB&#xff09;技术以其独特的优势&#xff0c;正逐步成为无线传输领域的新星。本文将深入探讨飞睿智能UWB传输数据模组在音频应用中的创新应用…...

webpack配置报错:Invalid options object.

前言&#xff1a; 今天在使用webpack进行项目配置的时候&#xff0c;运行之后终端报错&#xff1a;Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. - options has an unknown property inline. Thes…...

Java 并发编程:一文了解 Java 内存模型(处理器优化、指令重排序与内存屏障的深层解析)

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 022 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…...

谷粒商城实战笔记-64-商品服务-API-品牌管理-OSS前后联调测试上传

文章目录 1&#xff0c;拷贝文件到前端工程2&#xff0c;局部修改3&#xff0c;在品牌编辑界面使用上传组件4&#xff0c;OSS配置允许跨域5&#xff0c;测试multiUpload.vue完整代码singleUpload.vue完整代码policy.js代码 在Web应用开发中&#xff0c;文件上传是一项非常常见的…...

Springboot 开发之 RestTemplate 简介

一、什么是RestTemplate RestTemplate 是Spring框架提供的一个用于应用中调用REST服务的类。它简化了与HTTP服务的通信&#xff0c;统一了RESTFul的标准&#xff0c;并封装了HTTP连接&#xff0c;我们只需要传入URL及其返回值类型即可。RestTemplate的设计原则与许多其他Sprin…...

Django transaction.atomic()事务处理

在Django中&#xff0c;transaction.atomic()是一个上下文管理器&#xff0c;它会自动开始一个事务&#xff0c;并在代码块执行完毕后提交事务。如果在代码块中抛出异常&#xff0c;事务将被自动回滚&#xff0c;确保数据库的一致性和完整性。 在实际应用中&#xff0c;你可能需…...

2024.07-电视版免费影视App推荐和猫影视catvod、TVBox源(最新接口地址)

文章目录 电视版免费影视App推荐精选列表&#xff08;2024.07可用筛选列表&#xff09;&#xff1a;2024.07可用筛选列表&#xff0c;盲盒资源打包合集下载安装说明真的是盲盒&#xff1f; 猫影视catvod、TVBoxTVBox源推荐可用列表目前不可用列表&#xff08;前缀为错误状态码&…...

【Python】 基于Q-learning 强化学习的贪吃蛇游戏(源码+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…...

谷粒商城实战笔记-44-前端基础-Vue-整合ElementUI快速开发/设置模板代码

文章目录 一&#xff0c;安装导入ElementUI1&#xff0c;安装 element-ui2&#xff0c;导入 element-ui 二&#xff0c;ElementUI 实战1&#xff0c;将 App.vue 改为 element-ui 中的后台布局2&#xff0c;开发导航栏2.1 开发MyTable组件2.2 注册路由2.3 改造App.vue2.4 新增左…...

Android adb shell ps进程查找以及kill

Android adb shell ps进程查找以及kill 列出当前Android手机上运行的所有进程信息如PID等&#xff1a; adb shell ps 但是这样会列出一大堆进程信息&#xff0c;不便于定向查阅&#xff0c;可以使用关键词查找&#xff1a; adb shell "ps | grep 关键词" 关键词查…...

[OJ]水位线问题,1.采用回溯法(深度优先遍历求解)2.采用广度优先遍历求解

1.深度优先遍历 使用回溯法,深度优先遍历利用栈先进后出的特点,在加水控制水量失败时, 回到最近一次可对水进行加水与否的位置1.对于给定水量k,是否在[l,r]之间&#xff0c; 是:是否加水(加水y,用掉x,是否在[l,r]之间)(不加水y,用掉x,是否在[l,r]之间)先尝试加水&#xff0c;如…...

《华为数据之道》读书笔记六---面向自助消费的数据服务建设

七、从结果管理到过程管理&#xff0c; 从能“看”到能“管” 1、数据赋能业务运营 数字化运营旨在利用数字化技术获取、管理和分析数据&#xff0c;从而为企业的战略决策与业务运营提供可量化的、科学的支撑。 数字化运营归根结底是运营&#xff0c;旨在推动运营效率与能力的…...

go语言day18 reflect反射

Golang-100-Days/Day16-20(Go语言基础进阶)/day19_Go语言反射.md at master rubyhan1314/Golang-100-Days (github.com) 7-19 接口&#xff1a;底层实现_哔哩哔哩_bilibili 一、interface接口 接口类型内部存储了一对pair(value,Type) type interface { type *Type // 类型信…...

理解 Objective-C 中 `+load` 方法的执行顺序

理解 Objective-C 中 load 方法的执行顺序 在 Objective-C 中&#xff0c;load 方法是在类或分类被加载到内存时调用的。它在程序启动过程中非常早的阶段执行&#xff0c;用于在类或分类被加载时进行一些初始化工作。理解 load 方法的执行顺序对于编写可靠的 Objective-C 代码…...

C++:类和对象2

1.类的默认成员函数 默认成员函数就是用户没有显示实现编译器会自动生成的成员函数称为默认成员函数。一个类&#xff0c;我们在不写的情况下编译器会默认生成6个默认成员函数&#xff0c;分别是构造函数&#xff0c;析构函数&#xff0c;拷贝构造函数&#xff0c;拷贝赋值运算…...

Docker安装kkFileView实现在线文件预览

kkFileView为文件文档在线预览解决方案,该项目使用流行的spring boot搭建,易上手和部署,基本支持主流办公文档的在线预览,如doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,rar,图片,视频,音频等等 官方文档地址:https://kkview.cn/zh-cn/docs/production.html 一、拉取镜像 do…...

ElasticSearch(四)— 数据检索与查询

一、基本查询语法 所有的 REST 搜索请求使用_search 接口&#xff0c;既可以是 GET 请求&#xff0c;也可以是 POST请求&#xff0c;也可以通过在搜索 URL 中指定索引来限制范围。 _search 接口有两种请求方法&#xff0c;一种是基于 URI 的请求方式&#xff0c;另一种是基于…...

Pytest之parametrize()实现数据驱动

一、Pytest之parametrize()实现数据驱动 方法: pytest.mark-parametrize(argsname,args_value) args_name:参数名称&#xff0c;用于将参数值传递给函数 args value:参数值:(列表和字典列表&#xff0c;元组和字典元组)&#xff0c;有n个值那么用例执行n次 第一种用法&#xf…...

关于鸿蒙系统前景

鸿蒙系统的前景看起来非常乐观。‌ 鸿蒙系统以其全新的分布式架构和快速运行速度&#xff0c;‌展现了其独特的优势。‌它没有历史包袱&#xff0c;‌可以轻量前进&#xff0c;‌这一点在开发适配上具有明显优势。‌此外&#xff0c;‌鸿蒙系统的最大优势在于其“万物互联”的…...

针对datax-web 中Swagger UI接口未授权访问

application.yml 添加以下配置 实现访问doc.html 以及/v2/api-docs 接口时需要进行简单的校验 swagger:basic:enable: trueusername: adminpassword: 12345 配置重启后再进行相关访问则需要输入用户名和密码...

生成式AI如何帮助小型企业高效运营?

即使只有几家或几十家店的小规模生意&#xff0c;也可以利用AI技术来提升效率。不管企业组织规模如何&#xff0c;未来可能会有新的工作流程需要适应。就像计算机编程一样&#xff0c;我们需要将业务逻辑拆解成多个可管理的小任务&#xff0c;并设计它们之间的协同关系。这样&a…...

2024最新网络安全自学路线,内容涵盖3-5年技能提升

01 什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面…...

Postman API测试数据生成秘籍:技巧与实践

Postman API测试数据生成秘籍&#xff1a;技巧与实践 在API测试过程中&#xff0c;生成合适的测试数据是确保测试覆盖率和准确性的关键步骤。Postman作为流行的API开发和测试工具&#xff0c;提供了多种方法来生成和管理测试数据。本文将深入探讨Postman中API测试数据生成的技…...

【接口自动化_07课_Pytest+Excel+Allure完整框架集成_下】

目标&#xff1a;优化框架场景 1. 生成对应的接口关联【重点】 2. 优化URL基础路径封装【理解】 3. 利用PySQL操作数据库应用【理解】--- 怎么用python连接数据库、mysql 4. 通过数据库进行数据库断言【重点】 5. 通过数据库进行关联操作【重点】 一、接口关联&#xff1a…...

Java开发之反射与动态代理

#来自ゾフィー&#xff08;佐菲&#xff09; 1 反射&#xff08;Reflect&#xff09; 运行期间&#xff0c;获取类的信息&#xff0c;进行一些操作。 运行时构造类的对象。运行时获取类的成员变量和方法。运行时调用对象的方法&#xff08;属性&#xff09;。 2 Class 类 Cla…...

实习日志1之大模型相关知识概览

一、RAB 1、介绍&#xff08;提供检索和生成&#xff09; RAG&#xff0c;全称为Retrieval-Augmented Generation&#xff0c;中文可以翻译为"检索增强生成"&#xff0c;也有人说是召回增强生成。这是一种结合了检索和生成两种机器学习方法的新型框架&#xff0c;主…...

华为嵌入式面试题及参考答案(持续更新)

目录 详细讲TCP/IP协议的层数 材料硬度由什么决定? SD3.0接口电压标准 晶振市场失效率 RS232-C的硬件接口组成 详细讲眼图的功能 局域网传输介质有哪几类? 详细讲OSI模型 NMOS与PMOS的区别 I2C和SPI的区别 Static在C语言中的用法 堆栈和队列的区别 数组的时间复…...

Java二十三种设计模式-装饰器模式(7/23)

装饰器模式&#xff1a;动态扩展功能的灵活之选 引言 装饰器模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;用于在不修改对象自身的基础上&#xff0c;通过添加额外的职责来扩展对象的功能。 基础知识&#xff0c;java设计模式总体来说设计…...

正则表达式与文本处理

目录 一、正则表达式 1、正则表达式定义 1.1正则表达式的概念及作用 1.2、正则表达式的工具 1.3、正则表达式的组成 2、基础正则表达式 3、扩展正则表达式 4、元字符操作 4.1、查找特定字符 4.2、利用中括号“[]”来查找集合字符 4.3、查找行首“^”与行尾字符“$”…...

Python | Leetcode Python题解之第283题移动零

题目&#xff1a; 题解&#xff1a; class Solution:def moveZeroes(self, nums: List[int]) -> None:n len(nums)left right 0while right < n:if nums[right] ! 0:nums[left], nums[right] nums[right], nums[left]left 1right 1...

微信小程序面试题汇总

面试题 1. 请简述微信小程序主要目录和文件的作用&#xff1f; 参考回答&#xff1a; 微信小程序主要目录和文件的作用&#xff1a;&#xff08;1&#xff09;project.config.json&#xff1a;项目配置文件&#xff0c;用的最多的就是配置是否开启https校验 &#xff08;2&am…...

学习日志:JVM垃圾回收

文章目录 前言一、堆空间的基本结构二、内存分配和回收原则对象优先在 Eden 区分配大对象直接进入老年代长期存活的对象将进入老年代主要进行 gc 的区域空间分配担保 三、死亡对象判断方法引用计数法可达性分析算法引用类型总结1&#xff0e;强引用&#xff08;StrongReference…...

Vue前端页面嵌入mermaid图表--流程图

一、安装Mermaid 首先&#xff0c;你需要在你的项目中安装Mermaid。可以通过npm或yarn来安装&#xff1a; npm install mermaid --save # 或者 yarn add mermaid结果如图&#xff1a; 二、Vue 方法一&#xff1a;使用pre标签 使用ref属性可以帮助你在Vue组件中访问DOM元素 …...

【web]-反序列化-easy ? not easy

打开后看到源码 <?php error_reporting(0); highlight_file(__FILE__);class A{public $class;public $para;public $check;public function __construct(){$this->class "B";$this->para "ctfer";echo new $this->class ($this->para…...

python 内置函数、math模块

一、内置函数 内置函数是 Python 解释器内置的一组函数&#xff0c;它们可以直接在 Python 程序中使用&#xff0c;无需额外导入模块。这些内置函数提供了基本的操作和功能&#xff0c;涵盖了广泛的用途&#xff0c;从数学运算到数据结构操作等等。 import mathprint(type(10)…...

Ubuntu Docker 安装

Ubuntu Docker 安装 1. 引言 Docker 是一个开源的应用容器引擎,它允许开发者打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 2. 系统要求 在安装 Docker 之前,…...

vue接入google map自定义marker教程

需求背景 由于客户需求&#xff0c;原来系统接入的高德地图&#xff0c;他们不接受&#xff0c;需要换成google地图。然后就各种百度&#xff0c;各种Google&#xff0c;却不能实现。----无语&#xff0c;就连google地图官方的api也是一坨S-H-I。所以才出现这篇文章。 google地…...