【即插即用涨点模块】DSConv动态蛇形卷积:自适应聚焦细长弯曲的局部结构特征,助力分割高效提点【附源码+注释】
《------往期经典推荐------》
一、AI应用软件开发实战专栏【链接】
项目名称 | 项目名称 |
---|---|
1.【人脸识别与管理系统开发】 | 2.【车牌识别与自动收费管理系统开发】 |
3.【手势识别系统开发】 | 4.【人脸面部活体检测系统开发】 |
5.【图片风格快速迁移软件开发】 | 6.【人脸表表情识别系统】 |
7.【YOLOv8多目标识别与自动标注软件开发】 | 8.【基于深度学习的行人跌倒检测系统】 |
9.【基于深度学习的PCB板缺陷检测系统】 | 10.【基于深度学习的生活垃圾分类目标检测系统】 |
11.【基于深度学习的安全帽目标检测系统】 | 12.【基于深度学习的120种犬类检测与识别系统】 |
13.【基于深度学习的路面坑洞检测系统】 | 14.【基于深度学习的火焰烟雾检测系统】 |
15.【基于深度学习的钢材表面缺陷检测系统】 | 16.【基于深度学习的舰船目标分类检测系统】 |
17.【基于深度学习的西红柿成熟度检测系统】 | 18.【基于深度学习的血细胞检测与计数系统】 |
19.【基于深度学习的吸烟/抽烟行为检测系统】 | 20.【基于深度学习的水稻害虫检测与识别系统】 |
21.【基于深度学习的高精度车辆行人检测与计数系统】 | 22.【基于深度学习的路面标志线检测与识别系统】 |
23.【基于深度学习的智能小麦害虫检测识别系统】 | 24.【基于深度学习的智能玉米害虫检测识别系统】 |
25.【基于深度学习的200种鸟类智能检测与识别系统】 | 26.【基于深度学习的45种交通标志智能检测与识别系统】 |
27.【基于深度学习的人脸面部表情识别系统】 | 28.【基于深度学习的苹果叶片病害智能诊断系统】 |
29.【基于深度学习的智能肺炎诊断系统】 | 30.【基于深度学习的葡萄簇目标检测系统】 |
31.【基于深度学习的100种中草药智能识别系统】 | 32.【基于深度学习的102种花卉智能识别系统】 |
33.【基于深度学习的100种蝴蝶智能识别系统】 | 34.【基于深度学习的水稻叶片病害智能诊断系统】 |
35.【基于与ByteTrack的车辆行人多目标检测与追踪系统】 | 36.【基于深度学习的智能草莓病害检测与分割系统】 |
37.【基于深度学习的复杂场景下船舶目标检测系统】 | 38.【基于深度学习的农作物幼苗与杂草检测系统】 |
39.【基于深度学习的智能道路裂缝检测与分析系统】 | 40.【基于深度学习的葡萄病害智能诊断与防治系统】 |
41.【基于深度学习的遥感地理空间物体检测系统】 | 42.【基于深度学习的无人机视角地面物体检测系统】 |
43.【基于深度学习的木薯病害智能诊断与防治系统】 | 44.【基于深度学习的野外火焰烟雾检测系统】 |
45.【基于深度学习的脑肿瘤智能检测系统】 | 46.【基于深度学习的玉米叶片病害智能诊断与防治系统】 |
47.【基于深度学习的橙子病害智能诊断与防治系统】 | 48.【基于深度学习的车辆检测追踪与流量计数系统】 |
49.【基于深度学习的行人检测追踪与双向流量计数系统】 | 50.【基于深度学习的反光衣检测与预警系统】 |
51.【基于深度学习的危险区域人员闯入检测与报警系统】 | 52.【基于深度学习的高密度人脸智能检测与统计系统】 |
53.【基于深度学习的CT扫描图像肾结石智能检测系统】 | 54.【基于深度学习的水果智能检测系统】 |
55.【基于深度学习的水果质量好坏智能检测系统】 | 56.【基于深度学习的蔬菜目标检测与识别系统】 |
57.【基于深度学习的非机动车驾驶员头盔检测系统】 | 58.【太基于深度学习的阳能电池板检测与分析系统】 |
59.【基于深度学习的工业螺栓螺母检测】 | 60.【基于深度学习的金属焊缝缺陷检测系统】 |
61.【基于深度学习的链条缺陷检测与识别系统】 | 62.【基于深度学习的交通信号灯检测识别】 |
63.【基于深度学习的草莓成熟度检测与识别系统】 | 64.【基于深度学习的水下海生物检测识别系统】 |
65.【基于深度学习的道路交通事故检测识别系统】 | 66.【基于深度学习的安检X光危险品检测与识别系统】 |
67.【基于深度学习的农作物类别检测与识别系统】 | 68.【基于深度学习的危险驾驶行为检测识别系统】 |
69.【基于深度学习的维修工具检测识别系统】 | 70.【基于深度学习的维修工具检测识别系统】 |
71.【基于深度学习的建筑墙面损伤检测系统】 | 72.【基于深度学习的煤矿传送带异物检测系统】 |
73.【基于深度学习的老鼠智能检测系统】 | 74.【基于深度学习的水面垃圾智能检测识别系统】 |
75.【基于深度学习的遥感视角船只智能检测系统】 | 76.【基于深度学习的胃肠道息肉智能检测分割与诊断系统】 |
77.【基于深度学习的心脏超声图像间隔壁检测分割与分析系统】 | 78.【基于深度学习的心脏超声图像间隔壁检测分割与分析系统】 |
79.【基于深度学习的果园苹果检测与计数系统】 | 80.【基于深度学习的半导体芯片缺陷检测系统】 |
81.【基于深度学习的糖尿病视网膜病变检测与诊断系统】 | 82.【基于深度学习的运动鞋品牌检测与识别系统】 |
83.【基于深度学习的苹果叶片病害检测识别系统】 | 84.【基于深度学习的医学X光骨折检测与语音提示系统】 |
85.【基于深度学习的遥感视角农田检测与分割系统】 | 86.【基于深度学习的运动品牌LOGO检测与识别系统】 |
87.【基于深度学习的电瓶车进电梯检测与语音提示系统】 | 88.【基于深度学习的遥感视角地面房屋建筑检测分割与分析系统】 |
89.【基于深度学习的医学CT图像肺结节智能检测与语音提示系统】 | 90.【基于深度学习的舌苔舌象检测识别与诊断系统】 |
91.【基于深度学习的蛀牙智能检测与语音提示系统】 | 92.【基于深度学习的皮肤癌智能检测与语音提示系统】 |
二、机器学习实战专栏【链接】,已更新31期,欢迎关注,持续更新中~~
三、深度学习【Pytorch】专栏【链接】
四、【Stable Diffusion绘画系列】专栏【链接】
五、YOLOv8改进专栏【链接】,持续更新中~~
六、YOLO性能对比专栏【链接】,持续更新中~
《------正文------》
目录
- 论文信息
- 摘要
- 方法
- 1. 动态蛇形卷积(DSConv)
- 2. 多视角特征融合
- 3. 拓扑连续性约束损失
- 创新点
- DSConv的作用
- 总结
- DSConv源码+注释
论文信息
论文地址:https://arxiv.org/abs/2307.08388
源码地址:https://github.com/YaoleiQi/DSCNet
摘要
本文提出了一种针对管状结构(如血管、道路)分割的新框架DSCNet,通过融合拓扑几何约束知识,在特征提取、特征融合和损失约束三阶段增强模型感知能力。主要贡献包括:
- 动态蛇形卷积(DSConv):自适应聚焦细长弯曲的局部结构特征(对应挑战1:脆弱局部结构)
- 多视角特征融合策略:通过多形态卷积核模板保留不同全局形态的关键信息(对应挑战2:复杂全局形态)
- 拓扑连续性约束损失(TCLoss):基于持续同调理论约束分割结果的拓扑连续性
实验表明,DSCNet在2D/3D数据集上均优于现有方法。
方法
1. 动态蛇形卷积(DSConv)
- 核心思想:将标准卷积核改造为蛇形路径,通过迭代式偏移累积适应管状结构形态。相比可变形卷积,DSConv通过轴向约束避免感知区域漂移。
- 实现细节:
- X/Y轴方向分别进行坐标线性化(图展示9×9核的变形过程)
- 使用双线性插值处理分数坐标
2. 多视角特征融合
- 策略流程:
- 生成多组DSConv模板提取不同视角特征
- 引入随机丢弃策略减少冗余噪声
- 保留最优模板组合用于测试阶段
3. 拓扑连续性约束损失
- 持续同调应用:
- 构建持久图(PD)记录拓扑特征(0维/1维同调)的生存周期
- 采用Hausdorff距离度量预测与真值的拓扑差异
- 联合损失: L T C = L C E + ∑ d H ∗ \mathcal{L}_{TC} = \mathcal{L}_{CE} + \sum d_H^* LTC=LCE+∑dH∗
创新点
创新模块 | 解决痛点 | 技术亮点 |
---|---|---|
DSConv | 细小局部结构易丢失 | 蛇形路径约束+迭代偏移 |
多视角融合 | 复杂形态导致过拟合 | 随机丢弃的模板组合优化 |
TCLoss | 分割断裂问题 | 持续同调+异常拓扑惩罚 |
DSConv的作用
-
形态适应性:
- 相比可变形卷积(易偏离目标),DSConv严格沿管状结构延伸
- 通过 Σ Δ \Sigma \Delta ΣΔ约束实现线性感知
-
特征增强:
- 热力图显示对管状区域的高响应
- 在DRIVE数据集上Dice提升1.23%
-
跨维度扩展:
- 支持3D数据(冠状动脉CTA)的分割,HD降低19.3%
总结
-
贡献总结:
- 提出首个融合几何形态与拓扑约束的管状结构分割框架
- DSConv和TCLoss可迁移至其他网络(表1中UNet+TCLoss提升 β 0 \beta_0 β0误差)
-
实验验证:
- 2D数据集:DRIVE道路分割OF指标提升6%(表2)
- 3D数据集:冠状动脉RCA分支HD降至5.787(表2)
-
未来方向:
- 探索其他形态目标的适应性(如神经元分支)
- 结合更多拓扑不变量(如Betti数高阶约束)
DSConv源码+注释
# -*- coding: utf-8 -*-
import os
import torch
import numpy as np
from torch import nn
import warnings
# 忽略警告信息以清洁输出
warnings.filterwarnings("ignore")"""
This code is mainly the deformation process of our DSConv
"""class DSConv(nn.Module):def __init__(self, in_ch, out_ch, kernel_size, extend_scope, morph, if_offset, device):"""初始化动态蛇形卷积层(Dynamic Snake Convolution)。:param in_ch: 输入通道数。:param out_ch: 输出通道数。:param kernel_size: 卷积核大小。:param extend_scope: 动态调整的最大位移范围。:param morph: 核变形方向,'0' 为沿x轴,'1' 为沿y轴。:param if_offset: 是否启用动态形变。:param device: 运算设备('cuda' 或 'cpu')。"""super(DSConv, self).__init__()# 可学习偏移量以实现动态形变self.offset_conv = nn.Conv2d(in_ch, 2 * kernel_size, 3, padding=1)self.bn = nn.BatchNorm2d(2 * kernel_size)self.kernel_size = kernel_size# 针对x轴和y轴形变的卷积操作self.dsc_conv_x = nn.Conv2d(in_ch, out_ch, kernel_size=(kernel_size, 1), stride=(kernel_size, 1), padding=0)self.dsc_conv_y = nn.Conv2d(in_ch, out_ch, kernel_size=(1, kernel_size), stride=(1, kernel_size), padding=0)# 分组归一化和ReLU激活函数self.gn = nn.GroupNorm(out_ch // 4, out_ch)self.relu = nn.ReLU(inplace=True)# 配置设置self.extend_scope = extend_scopeself.morph = morphself.if_offset = if_offsetself.device = devicedef forward(self, f):"""DSConv层的前向传播。:param f: 输入特征图。:return: 变换后的特征图。"""# 计算偏移量并应用批归一化offset = self.offset_conv(f)offset = self.bn(offset)offset = torch.tanh(offset) # 将偏移量规范化到[-1, 1]范围内# 根据输入形状和设置准备可变形卷积dsc = DSC(f.shape, self.kernel_size, self.extend_scope, self.morph, self.device)deformed_feature = dsc.deform_conv(f, offset, self.if_offset)# 根据形变方向应用卷积if self.morph == 0:x = self.dsc_conv_x(deformed_feature)else:x = self.dsc_conv_y(deformed_feature)# 归一化和激活输出x = self.gn(x)x = self.relu(x)return x# 辅助类处理形变过程
class DSC(object):def __init__(self, input_shape, kernel_size, extend_scope, morph, device):"""初始化用于处理形变的DSC对象。:param input_shape: 输入张量的形状。:param kernel_size: 卷积核大小。:param extend_scope: 形变范围。:param morph: 形变方向。:param device: 运算设备。"""self.num_points = kernel_sizeself.width = input_shape[2]self.height = input_shape[3]self.morph = morphself.device = deviceself.extend_scope = extend_scopeself.num_batch = input_shape[0]self.num_channels = input_shape[1]def _coordinate_map_3D(self, offset, if_offset):"""根据给定的偏移量生成3D坐标映射。:param offset: 卷积层学习到的偏移量。:param if_offset: 是否应用形变的标志。:return: 用于形变的坐标映射。"""# 分解偏移量为x轴和y轴分量y_offset, x_offset = torch.split(offset, self.num_points, dim=1)# 生成y和x的基础网格坐标y_center = torch.arange(0, self.width).repeat(self.height).view(self.height, self.width).permute(1, 0). \repeat(self.num_points, 1, 1).float().unsqueeze(0)x_center = torch.arange(0, self.height).repeat(self.width).view(self.width, self.height).permute(0, 1). \repeat(self.num_points, 1, 1).float().unsqueeze(0)if self.morph == 0:# 沿x轴形变的情况# 初始化网格的y坐标,所有y坐标都为0y = torch.linspace(0, 0, 1)# 初始化网格的x坐标,均匀分布在-kernel_size/2到kernel_size/2之间x = torch.linspace(-int(self.num_points // 2), int(self.num_points // 2), int(self.num_points))# 生成网格坐标y, x = torch.meshgrid(y, x)y_spread = y.reshape(-1, 1)x_spread = x.reshape(-1, 1)# 重复网格坐标以覆盖整个特征图的宽度和高度y_grid = y_spread.repeat([1, self.width * self.height])y_grid = y_grid.reshape([self.num_points, self.width, self.height])y_grid = y_grid.unsqueeze(0) # 增加批次维度x_grid = x_spread.repeat([1, self.width * self.height])x_grid = x_grid.reshape([self.num_points, self.width, self.height])x_grid = x_grid.unsqueeze(0) # 增加批次维度# 将基准中心坐标与网格坐标相加以生成新的形变坐标y_new = y_center + y_gridx_new = x_center + x_grid# 复制到每个批次y_new = y_new.repeat(self.num_batch, 1, 1, 1).to(self.device)x_new = x_new.repeat(self.num_batch, 1, 1, 1).to(self.device)# 根据偏移量调整y坐标y_offset_new = y_offset.detach().clone()if if_offset:y_offset = y_offset.permute(1, 0, 2, 3)y_offset_new = y_offset_new.permute(1, 0, 2, 3)center = int(self.num_points // 2)# 中心位置保持不变,其他位置根据偏移量动态调整y_offset_new[center] = 0for index in range(1, center):y_offset_new[center + index] = (y_offset_new[center + index - 1] + y_offset[center + index])y_offset_new[center - index] = (y_offset_new[center - index + 1] + y_offset[center - index])y_offset_new = y_offset_new.permute(1, 0, 2, 3).to(self.device)y_new = y_new.add(y_offset_new.mul(self.extend_scope))# 重塑形变后的坐标以适应下一步操作y_new = y_new.reshape([self.num_batch, self.num_points, 1, self.width, self.height])y_new = y_new.permute(0, 3, 1, 4, 2)y_new = y_new.reshape([self.num_batch, self.num_points * self.width, 1 * self.height])x_new = x_new.reshape([self.num_batch, self.num_points, 1, self.width, self.height])x_new = x_new.permute(0, 3, 1, 4, 2)x_new = x_new.reshape([self.num_batch, self.num_points * self.width, 1 * self.height])return y_new, x_newelse:# 沿y轴形变的情况# 初始化网格的y坐标,均匀分布在-kernel_size/2到kernel_size/2之间y = torch.linspace(-int(self.num_points // 2), int(self.num_points // 2), int(self.num_points))# 初始化网格的x坐标,所有x坐标都为0x = torch.linspace(0, 0, 1)# 生成网格坐标y, x = torch.meshgrid(y, x)y_spread = y.reshape(-1, 1)x_spread = x.reshape(-1, 1)# 重复网格坐标以覆盖整个特征图的宽度和高度y_grid = y_spread.repeat([1, self.width * self.height])y_grid = y_grid.reshape([self.num_points, self.width, self.height])y_grid = y_grid.unsqueeze(0) # 增加批次维度x_grid = x_spread.repeat([1, self.width * self.height])x_grid = x_grid.reshape([self.num_points, self.width, self.height])x_grid = x_grid.unsqueeze(0) # 增加批次维度# 将基准中心坐标与网格坐标相加以生成新的形变坐标y_new = y_center + y_gridx_new = x_center + x_grid# 复制到每个批次y_new = y_new.repeat(self.num_batch, 1, 1, 1)x_new = x_new.repeat(self.num_batch, 1, 1, 1)# 将坐标转移到设备上(如GPU)y_new = y_new.to(self.device)x_new = x_new.to(self.device)# 处理x轴偏移量x_offset_new = x_offset.detach().clone()if if_offset:# 调整偏移数据以应用于所有批次和位置x_offset = x_offset.permute(1, 0, 2, 3)x_offset_new = x_offset_new.permute(1, 0, 2, 3)center = int(self.num_points // 2)# 中心位置保持不变,其他位置根据偏移量动态调整x_offset_new[center] = 0for index in range(1, center):x_offset_new[center + index] = (x_offset_new[center + index - 1] + x_offset[center + index])x_offset_new[center - index] = (x_offset_new[center - index + 1] + x_offset[center - index])x_offset_new = x_offset_new.permute(1, 0, 2, 3).to(self.device)x_new = x_new.add(x_offset_new.mul(self.extend_scope))# 重塑形变后的坐标以适应下一步操作y_new = y_new.reshape([self.num_batch, 1, self.num_points, self.width, self.height])y_new = y_new.permute(0, 3, 1, 4, 2)y_new = y_new.reshape([self.num_batch, 1 * self.width, self.num_points * self.height])x_new = x_new.reshape([self.num_batch, 1, self.num_points, self.width, self.height])x_new = x_new.permute(0, 3, 1, 4, 2)x_new = x_new.reshape([self.num_batch, 1 * self.width, self.num_points * self.height])return y_new, x_new"""输入:输入特征图 [N,C,D,W,H];坐标映射 [N,K*D,K*W,K*H] 输出:[N,1,K*D,K*W,K*H] 形变后的特征图"""def _bilinear_interpolate_3D(self, input_feature, y, x):# 将坐标向量平铺并转换为浮点数y = y.reshape([-1]).float()x = x.reshape([-1]).float()# 定义网格边界zero = torch.zeros([]).int()max_y = self.width - 1max_x = self.height - 1# 计算网格的四个角的坐标y0 = torch.floor(y).int()y1 = y0 + 1x0 = torch.floor(x).int()x1 = x0 + 1# 限制坐标不超过特征图的边界y0 = torch.clamp(y0, zero, max_y)y1 = torch.clamp(y1, zero, max_y)x0 = torch.clamp(x0, zero, max_x)x1 = torch.clamp(x1, zero, max_x)# 展平输入特征图以便进行索引input_feature_flat = input_feature.flatten()input_feature_flat = input_feature_flat.reshape(self.num_batch, self.num_channels, self.width, self.height)input_feature_flat = input_feature_flat.permute(0, 2, 3, 1)input_feature_flat = input_feature_flat.reshape(-1, self.num_channels)dimension = self.height * self.width# 计算每个批次的基准索引base = torch.arange(self.num_batch) * dimensionbase = base.reshape([-1, 1]).float()repeat = torch.ones([self.num_points * self.width * self.height]).unsqueeze(0)repeat = repeat.float()# 将基准索引复制以匹配特征点数量base = torch.matmul(base, repeat)base = base.reshape([-1])base = base.to(self.device)# 计算周围4个点的索引base_y0 = base + y0 * self.heightbase_y1 = base + y1 * self.heightindex_a0 = base_y0 - base + x0index_c0 = base_y0 - base + x1index_a1 = base_y1 - base + x0index_c1 = base_y1 - base + x1# 获取这四个点的值value_a0 = input_feature_flat[index_a0.type(torch.int64)].to(self.device)value_c0 = input_feature_flat[index_c0.type(torch.int64)].to(self.device)value_a1 = input_feature_flat[index_a1.type(torch.int64)].to(self.device)value_c1 = input_feature_flat[index_c1.type(torch.int64)].to(self.device)# 计算插值权重x0_float = x0.float()x1_float = x1.float()y0_float = y0.float()y1_float = y1.float()vol_a0 = ((y1_float - y) * (x1_float - x)).unsqueeze(-1).to(self.device)vol_c0 = ((y1_float - y) * (x - x0_float)).unsqueeze(-1).to(self.device)vol_a1 = ((y - y0_float) * (x1_float - x)).unsqueeze(-1).to(self.device)vol_c1 = ((y - y0_float) * (x - x0_float)).unsqueeze(-1).to(self.device)# 根据权重和四个角的值计算插值结果outputs = (value_a0 * vol_a0 + value_c0 * vol_c0 + value_a1 * vol_a1 + value_c1 * vol_c1)# 重塑输出以匹配输入的形状if self.morph == 0:outputs = outputs.reshape([self.num_batch, self.num_points * self.width, 1 * self.height, self.num_channels])outputs = outputs.permute(0, 3, 1, 2)else:outputs = outputs.reshape([self.num_batch, 1 * self.width, self.num_points * self.height, self.num_channels])outputs = outputs.permute(0, 3, 1, 2)return outputsdef deform_conv(self, input, offset, if_offset):# 获取形变的坐标映射y, x = self._coordinate_map_3D(offset, if_offset)# 应用双线性插值deformed_feature = self._bilinear_interpolate_3D(input, y, x)return deformed_featureif __name__ == '__main__':os.environ["CUDA_VISIBLE_DEVICES"] = '0'device = torch.device("cuda" if torch.cuda.is_available() else "cpu")A = np.random.rand(4, 5, 6, 7)# A = np.ones(shape=(3, 2, 2, 3), dtype=np.float32)# print(A)A = A.astype(dtype=np.float32)A = torch.from_numpy(A)# print(A.shape)conv0 = DSConv(in_ch=5,out_ch=10,kernel_size=15,extend_scope=1,morph=0,if_offset=True,device=device)if torch.cuda.is_available():A = A.to(device)conv0 = conv0.to(device)out = conv0(A)print(out.shape)
好了,这篇文章就介绍到这里,喜欢的小伙伴感谢给点个赞和关注,更多精彩内容持续更新~~
关于本篇文章大家有任何建议或意见,欢迎在评论区留言交流!
相关文章:
【即插即用涨点模块】DSConv动态蛇形卷积:自适应聚焦细长弯曲的局部结构特征,助力分割高效提点【附源码+注释】
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...
守护数字家园:个人博客安全防护指南
前言 在之前的文章《WordPress个人博客搭建(一)》《WordPress个人博客搭建(二)》《WordPress个人博客搭建(三)》中,我们已经在非凡云云服务器上,借助1Panel搭建起属于自己的数字庭院…...
课外活动:简单了解原生测试框架Unittest前置后置的逻辑
简单了解原生测试框架Unittest前置后置的逻辑 一、测试框架执行顺序解析 1.1 基础执行流程 import unittestclass A(unittest.TestCase):classmethoddef setUpClass(cls):print(f"【CLASS START】{cls.__name__}")def setUp(self):print(f"【TEST START】{se…...
带你玩转 Flink TumblingWindow:从理论到代码的深度探索
0.前言 在深入探讨 TumblingWindow 之前,我们先来了解一下流处理或流计算中“窗口”的基本概念。在数据流中,源会持续不断地生成数据,因此计算最终值是不可行的。 在大多数用例中,为了获取有意义的信息,最好使用两种方…...
Java线程安全问题深度解析与解决方案
一、线程安全问题的本质 并发编程的核心挑战:当多个线程同时访问共享资源时,由于操作系统的抢占式调度特性,可能导致不可预期的结果。这种因非原子操作和竞态条件引发的数据不一致问题,称为线程安全问题。 二、经典线程安全问题案…...
python实现的音乐播放器
python实现的音乐播放器 音乐播放器,原来写过一个简陋的例子,可见 https://blog.csdn.net/cnds123/article/details/137874107 那个不能拖动播放进度条上的滑块到新的位置播放。下面介绍的可以拖动播放进度条上的滑块到新的位置播放。 简单实用的音乐播放器 这个简单实用的…...
SMT贴片工艺核心优化与生产实践
内容概要 作为现代电子制造的核心环节,SMT贴片工艺的优化直接决定了产品可靠性与生产效率。本文系统性梳理工艺链中的关键控制点,从锡膏印刷精度到回流焊温度曲线,再到AOI检测技术升级,形成覆盖全流程的优化框架。针对行业普遍存…...
趣味编程:爱心
概述:五月十一号就是母亲节了,本篇博客主要是为母亲所写,这是属于程序员的浪漫,这篇博客是对母亲这么多年无微不至爱的情书。 目录 1. 效果展示 2. 源码展示 3. 代码逻辑详解 3.1 头文件与常量定义 3.2 心形曲线参数方程 3.…...
C语言—指针2
1. const 修饰变量 1.1 const修饰变量 变量被const修饰时,变量此时为常变量,本质为常量,语法上不可被修改,但是如果此时需要修改变量值,可以通过指针的方式修改。 虽然此时通过指针的方式确实修改了变量的值ÿ…...
66、微服务保姆教程(九)微服务的高可用性
微服务的高可用性与扩展 服务的高可用性 集群搭建与负载均衡。服务的故障容错与自愈。分布式事务与一致性 分布式事务的挑战与解决方案。使用 RocketMQ 实现分布式事务。微服务的监控与可观测性 metrics 和日志的收集与分析。sentinel 的监控功能。容器化与云原生 将微服务部署…...
主场景 工具栏 植物卡牌的渲染
前置知识:使用easyx图形库 1.IMAGE内存变量存储的是一张位图(图像),存储了像素数据(颜色,尺寸等) 2.loadimage(&变量名,"加载的文件路径")表示从文件中加载图像到变量中 3. saveimage("文件路径", &变…...
超详细!RxSwift 中的 BehaviorRelay 使用教程(含原理 + 示例 + 实战)
目录 前言 1.什么是 BehaviorRelay 2.基本使用方式 3.BehaviorRelay的常用API 4.BehaviorRelay 和其它类型的对比 5.BehaviorRelay的使用场景 1.绑定UITableView 2.MVVM 场景下使用 BehaviorRelay 6.使用注意事项以及建议 1.注意事项 2.使用建议总结 7.推荐阅读 前…...
【软件测试学习day7】Junit5
Junit 是单元测试框架,本期掌握 Junit5 的基础用法。 1. 注解 首先引入 Junit 依赖: <dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.9.1</version…...
前端实战中的单例模式:以医疗药敏管理为例
目录 一、什么是单例模式?1. 状态共享性 —— 数据唯一,任意访问,任意修改2. 生命周期控制性 —— 自己掌控何时创建、何时销毁 二、实战分析:医疗药敏管理系统中的单例应用三、其他场景示例单例实现:ConfigManager.ts…...
如何在 Logback 日志框架中加入链路 ID
在 Logback 日志框架中加入链路 ID,能有效将同一条链路的日志串联起来,便于追踪和排查问题。 1. 生成和管理链路 ID 要保证在整个请求链路里都能获取到链路 ID,可借助 ThreadLocal 来实现。以下是一个简单的工具类示例: import…...
晶振:智能设备的“心跳”如何支撑5G与航天
在现代科技飞速发展的时代,智能设备已深度融入我们生活的方方面面,而晶振,作为智能设备的“心跳”,正默默发挥着不可替代的关键作用。无论是翱翔太空的神舟飞船,还是人们手中须臾不离的智能手机,亦或是推动…...
【HarmonyOS 5】App Linking 应用间跳转详解
目录 什么是 App Linking 使用场景 工作原理 如何开发 1.开通 App Linking 2.确定域名 3.服务端部署 applinking.json 文件 4.AGC绑定域名 5.项目配置 6.组装聚合链接 7.解析聚合链接中的参数 其他 如何获取应用ID 什么是 App Linking App Linking 是一款创建跨…...
neo4j官方示例
目录 一、准备数据 1.执行查看结果 二、操作 1.find 单个节点 2.同上,已某个属性去查询 3. 指定查询个数 4.条件查询 5.查询某个人出演的电影汇总 6.查询tom出演的电影中,还有其他演员的信息。 7.查询跟电影(Cloud Atlas)有关的演员࿰…...
基于vueflow可拖拽元素的示例(基于官网示例的单文件示例)
效果图 代码 <template><div style"width: 100%;height: calc(100vh - 84px)"><VueFlow :nodes"nodes" :edges"edges" drop"onDrop" dragover"onDragOver" dragleave"onDragLeave"><div cl…...
minio单点登录与集成(免密)
需求:系统A里,需要实现与MINIO单点登录集成,也就是说,登录了系统A,在访问MINIO时不需要再输入用户密码就可以直接访问。 具体场景如下: 在系统A的一个页面里,配置一个按钮链接,点击…...
深入理解 Docker 网络原理:构建高效、灵活的容器网络
在现代软件开发中,Docker 已经成为了容器化技术的代名词,广泛应用于开发、测试和生产环境。Docker 使得开发者能够将应用及其依赖打包成一个轻量级的容器,并通过 Docker 容器化技术来实现高效的部署与管理。 然而,在日常使用 Dock…...
Hutool中的Pair类详解
1. Pair类概述 Hutool工具库中的Pair类是一个简单的键值对数据结构,用于存储两个相关联的对象。它类似于Map的Entry,但更加轻量级,适用于需要临时存储两个相关联数据的场景。 2. Pair类的主要特点 简单轻量:不依赖复杂的数据结…...
没有Mac,我是怎么上传IPA到App Store的?
没有Mac,我是怎么上传IPA到App Store的? 最近赶一个小项目上线,写的是一个Flutter做的App。安卓版本一晚上搞定,iOS上架却差点把人整崩。 不是我技术菜,是实在太麻烦了。最关键的,是我这台Windows笔电根本…...
RISC-V hardfault分析工具,RTTHREAD-RVBACKTRACE
RV BACKTRACE 简介 本文主要讲述RV BACKTRACE 的内部主要原理 没有接触过rvbacktrace可以看下面两篇文章,理解一下如何使用RVBACKTRACE RVBacktrace RISC-V极简栈回溯组件:https://club.rt-thread.org/ask/article/64bfe06feb7b3e29.html RVBacktra…...
c语言if else语句格式(非常详细)
在C语言中,if else 语句是一种常用的条件控制结构,用于根据不同条件执行不同的代码块。 if-else 语句的基本格式 if-else 语句的基本格式如下: if (条件) { // 如果条件为真,执行这里的代码 } else { // 如果条件为假&a…...
Logback官方文档翻译章节目录
Logback官方文档翻译章节目录 第一章 Logback简介 第二章 Logback的架构(一) Logback的架构(二) Logback的架构(三) 持续更新中…...
按摩椅的机芯类型和材质
按摩椅的机芯类型和材质是影响其按摩效果、使用寿命以及舒适度的重要因素。下面我将从这两个方面详细为你解析: 一、按摩椅机芯类型 按摩椅的“机芯”相当于它的“心脏”,决定了按摩手法、力度、覆盖范围等关键性能。 常见机芯类型(按技术发…...
HarmonyOS-hdc远程网络方式连接设备
hdc工具使用手册 1 hdc简介 hdc(OpenHarmony Device Connector)是为开发人员提供的用于设备连接调试的命令行工具,pc端开发机使用命令行工具hdc,该工具需支持部署在Windows/Linux/Mac等系统上与OpenHarmony设备(或模…...
秋招准备——2.跨时钟相关
格雷码异步FIFO跨时钟域处理 格雷码 一、格雷码规律 相邻性:相邻两个数的格雷码只有一位不同,例如: 0000 → 0001(仅最低位变化)0001 → 0011(仅次低位变化)0011 → 0010(仅最低位…...
【开源版】likeshop上门家政系统PHP版全开源+uniapp前端
一.系统介绍 likeshop_上门家政系统,PHP版本更新至2.1.1最新版,全开源,适用于上门家政场景,系统拥有用户端、师傅端、无论运营还是二开都是性价比极高的100%开源家政系统。 二.搭建环境-教程 系统环境:CentOS、 运行…...
Memgraph 的安装教程
目录 Memgraph 安装步骤1. 使用 Docker 安装 Memgraph2. 使用 Memgraph Lab3. 使用 Python 客户端连接 Memgraph Memgraph 安装步骤 1. 使用 Docker 安装 Memgraph Memgraph 可以通过 Docker 快速安装和运行。以下是使用 Docker 安装 Memgraph 的步骤: 安装 Docke…...
华为网路设备学习-21 路由过滤(filter-policy)
一、路由过滤(filter-policy) 1、用于控制路由更新、接收的一个工具 2、只能过滤路由信息,无法过滤LSA 二、路由过滤(filter-policy)与动态路由协议 1、距离矢量路由协议 RIP动态路由协议 交换的是路由表࿰…...
Mac 平台 字体Unicode范围分析器
字体Unicode范围分析器 #include <CoreText/CoreText.h> // CoreText框架头文件,用于字体处理 #include <CoreFoundation/CoreFoundation.h> // CoreFoundation框架头文件 #include <stdio.h> // 标准输入输出 #include…...
Android不能下载Gradle,解决方法Could not install Gradle distribution from.......
外网下载速度太慢导致失败,换成国内镜像,可加速下载: 官网地址:https://services.gradle.org/distributions/ 腾讯云镜像 Gradle下载地址:https://mirrors.cloud.tencent.com/gradle/ 阿里云镜像 Gradle下载地址&…...
树状数组的操作问题--Python
树状数组的操作问题 一、问题引入二、解题步骤1.思维导图2.解题步骤 三、代码实现1.代码2.复杂度分析 四、个人总结 一、问题引入 请编写程序,实现树状数组区间求前缀和、单点修改的操作。 输入格式: 输入首先给出一个正整数 n(2≤n<10^…...
FEKO许可限制
随着科技的飞速发展,电磁仿真软件在多个领域发挥着越来越重要的作用。FEKO作为一款业界领先的电磁仿真软件,广泛应用于通信、雷达、航空航天、电子对抗等领域。然而,为了确保软件使用的合规性与高效性,FEKO设定了相应的许可限制。…...
第5章 深度学习和卷积神经网络
深度学习是人工智能的一种实现方法。本章我们将考察作为深度学习的代表的卷积神经网络的数学结构。 5-1小恶魔来讲解卷积神经网络的结构 深度学习是重叠了很多层的隐藏层(中间层)的神经网络。这样的神经网络使隐藏层具有一定的结构,从而更加…...
window 显示驱动开发-处理内存段(一)
视频内存管理器 (VidMm) 负责管理 GPU 的地址空间。 在此之前,内核模式显示微型端口驱动程序 (KMD) 必须通过使用内存段将 GPU 的地址空间描述为 VidMm。 KMD 创建内存段以概括和虚拟化视频内存资源。 它可以根据硬件支持的存储器类型(例如,…...
QT实现曲线图缩放、拖拽以及框选放大
.h文件 protected: void saveAxisRange();void wheelEvent(QWheelEvent *event) override;void mousePressEvent(QMouseEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;private:QPoint m_…...
龙虎榜——20250508
上证假阴包阳的走势,量能较昨天有萎缩,在前期压力附近~ 深证这两天假阴包阳的走势,60分钟未突破昨天的高点,缺口也未补等待明天的选择~ 2025年5月8日龙虎榜行业方向分析 一、核心行业方向 军工航天(政策催化地缘驱动…...
SEMI E40-0200 STANDARD FOR PROCESSING MANAGEMENT(加工管理标准)-(三)完结
10 消息服务详情 10.1 本章定义实现加工管理概念所需的消息服务。这些消息已在第8.1节中初步介绍。 协议无关性:这些服务独立于所使用的消息协议,可映射至SECS-II(SEMI E5)或其他类似协议。 10.1.1 消息服务定义内容包括&#…...
算法竞赛进阶指南.次小生成树
目录 题目算法标签: K r u s k a l Kruskal Kruskal, M S T MST MST, 倍增优化, l c a lca lca思路代码*警示后人 题目 356. 次小生成树 算法标签: K r u s k a l Kruskal Kruskal, M S T MST MST, 倍增优化, l c a lca lca 思路 因为要求的是严格次小生成树, 假设最…...
ElasticSearch基本概念
为什么要使用ElasticSearch Elasticsearch 主要为系统提供搜索功能, MySQL 这类传统关系型数据库主要为系统提供数据存储功能 Elasticsearch 的优势 : 支持多种数据类型,非结构化,数值,地理信息。简单的 RESTful AP…...
普通IT的股票交易成长史--20250508晚复盘
声明:本文章的内容只是自己学习的总结,不构成投资建议。价格行为理论学习可参考简介中的几位,感谢他们的无私奉献。 送给自己的话: 仓位就是生命,绝对不能满仓!!!!&…...
SAP 交货单行项目含税金额计算报cx_sy_zerodivide处理
业务背景:SAP交货单只有数量,没有金额,所以开发报表从订单的价格按数量计算交货单的金额。 用户反馈近期报表出现异常: ****2012/12/12 清风雅雨 规格变更 Chg 修改开始 ** 修改原因:由于余数为0时,可能会报错溢出。…...
基于译码器和锁存器的运行逻辑的简易算法
74HC138 def decoder_74hc138(E1, E2, E3, A0, A1, A2):output [1] * 8 # 默认全高电平# 检查使能条件:E1和E2低电平,E3高电平if E1 0 and E2 0 and E3 1:# 计算地址索引(A2为高位,A0为低位)index (A2 <<…...
用电信息采集中的天线种类
一、4G/3G/2G 频率范围“698-960/1710-2700MHz 输入阻抗:50Ω 电压驻波比:<3.0 增益:5dBi/7dBi/9dBi; 824MHz~960MHz频段本体增益≥3.0dBi 1710MHz~2700MHz频段本体增益≥5.0dBi 天线长度225*30mm…...
2025年4月AI算力领域热点事件全景报告
目录 一、政策要闻 01欧洲央行召开会议讨论AI影响 02中国生成式AI备案制落地 03多国政府公布AI基础设施投资计划 04香港发布生成式AI技术及应用指引 05美国出口管制政策影响 06欧盟《人工智能法案》落地 07中国 “东数西算” 工程深化 08美国CHIPS法案争议 09中国发…...
数据结构-非线性结构-二叉树
概述 /** * 术语 * 根节点(root node):位于二叉树顶层的节点,没有父节点。 * 叶节点(leaf node):没有子节点的节点,其两个指针均指向 None 。 * 边(edge)&…...
Android开发补充内容
Android开发补充内容 fragment通信生命周期 Okhttp基本使用websocket Retrofit基本使用 RxJava基本使用定时任务 Hilt基本使用进阶使用例子 组件库Material ComponentsJetpack Compose fragment 通信 fragment于activity通信的一种原生方法是使用Bundle: Bundle …...