医疗图像之基于UNet3+(UNet+++)的X射线图像牙齿分割

   第一步:准备数据

X射线图像牙齿分割,总共有2000张

第二步:搭建模型

UNet3+主要是参考了UNet和UNet++两个网络结构。尽管UNet++采用了嵌套和密集跳过连接的网络结构(见图1(b)红色三角区域),但是它没有直接从多尺度信息中提取足够多的信息。此部分,在我理解而言UNet++虽然名义上通过嵌套和密集跳过连接进行了多尺度信息的利用,但是从本质上看基本都是短连接,基本上都对解码特征进行了再次处理,再加上各个连接的融合,多尺度信息的原始特征几乎没有得到特别好的利用,信号处理有些矫枉过正或是丢失。UNet3+利用了全尺度的跳跃连接(skip connection)和深度监督(deep supervisions)。全尺度的跳跃连接把来自不同尺度特征图中的高级语义与低级语义直接结合(当然需要必要的上采样操作);而深度监督则从多尺度聚合的特征图中学习层次表示。注意一点:UNet++和UNet3+都用到了深度监督,但是监督的位置是完全不一样的,从图1(b)、(c)中的Sup部分可以清楚的看到不同之处。

在UNet3+中,可以从全尺度捕获细粒度的细节和粗粒度的语义。为了进一步从全尺寸的聚合特征图中学习层次表示法,每个边的输出都与一个混合损失函数相连接,这有助于精确分割,特别是对于在医学图像体积中出现不同尺度的器官。从图1中也可以看出,UNet3+的参数量明显小于UNet++。

第三步:代码

1)损失函数为:交叉熵损失函数

2)网络代码:

class UNet3Plus(nn.Module):def __init__(self, n_channels=3, n_classes=1, bilinear=True, feature_scale=4,is_deconv=True, is_batchnorm=True):super(UNet3Plus, self).__init__()self.n_channels = n_channelsself.n_classes = n_classesself.bilinear = bilinearself.feature_scale = feature_scaleself.is_deconv = is_deconvself.is_batchnorm = is_batchnormfilters = [16, 32, 64, 128, 256]## -------------Encoder--------------self.conv1 = unetConv2(self.n_channels, filters[0], self.is_batchnorm)self.maxpool1 = nn.MaxPool2d(kernel_size=2)self.conv2 = unetConv2(filters[0], filters[1], self.is_batchnorm)self.maxpool2 = nn.MaxPool2d(kernel_size=2)self.conv3 = unetConv2(filters[1], filters[2], self.is_batchnorm)self.maxpool3 = nn.MaxPool2d(kernel_size=2)self.conv4 = unetConv2(filters[2], filters[3], self.is_batchnorm)self.maxpool4 = nn.MaxPool2d(kernel_size=2)self.conv5 = unetConv2(filters[3], filters[4], self.is_batchnorm)## -------------Decoder--------------self.CatChannels = filters[0]self.CatBlocks = 5self.UpChannels = self.CatChannels * self.CatBlocks'''stage 4d'''# h1->320*320, hd4->40*40, Pooling 8 timesself.h1_PT_hd4 = nn.MaxPool2d(8, 8, ceil_mode=True)self.h1_PT_hd4_conv = nn.Conv2d(filters[0], self.CatChannels, 3, padding=1)self.h1_PT_hd4_bn = nn.BatchNorm2d(self.CatChannels)self.h1_PT_hd4_relu = nn.ReLU(inplace=True)# h2->160*160, hd4->40*40, Pooling 4 timesself.h2_PT_hd4 = nn.MaxPool2d(4, 4, ceil_mode=True)self.h2_PT_hd4_conv = nn.Conv2d(filters[1], self.CatChannels, 3, padding=1)self.h2_PT_hd4_bn = nn.BatchNorm2d(self.CatChannels)self.h2_PT_hd4_relu = nn.ReLU(inplace=True)# h3->80*80, hd4->40*40, Pooling 2 timesself.h3_PT_hd4 = nn.MaxPool2d(2, 2, ceil_mode=True)self.h3_PT_hd4_conv = nn.Conv2d(filters[2], self.CatChannels, 3, padding=1)self.h3_PT_hd4_bn = nn.BatchNorm2d(self.CatChannels)self.h3_PT_hd4_relu = nn.ReLU(inplace=True)# h4->40*40, hd4->40*40, Concatenationself.h4_Cat_hd4_conv = nn.Conv2d(filters[3], self.CatChannels, 3, padding=1)self.h4_Cat_hd4_bn = nn.BatchNorm2d(self.CatChannels)self.h4_Cat_hd4_relu = nn.ReLU(inplace=True)# hd5->20*20, hd4->40*40, Upsample 2 timesself.hd5_UT_hd4 = nn.Upsample(scale_factor=2, mode='bilinear')  # 14*14self.hd5_UT_hd4_conv = nn.Conv2d(filters[4], self.CatChannels, 3, padding=1)self.hd5_UT_hd4_bn = nn.BatchNorm2d(self.CatChannels)self.hd5_UT_hd4_relu = nn.ReLU(inplace=True)# fusion(h1_PT_hd4, h2_PT_hd4, h3_PT_hd4, h4_Cat_hd4, hd5_UT_hd4)self.conv4d_1 = nn.Conv2d(self.UpChannels, self.UpChannels, 3, padding=1)  # 16self.bn4d_1 = nn.BatchNorm2d(self.UpChannels)self.relu4d_1 = nn.ReLU(inplace=True)'''stage 3d'''# h1->320*320, hd3->80*80, Pooling 4 timesself.h1_PT_hd3 = nn.MaxPool2d(4, 4, ceil_mode=True)self.h1_PT_hd3_conv = nn.Conv2d(filters[0], self.CatChannels, 3, padding=1)self.h1_PT_hd3_bn = nn.BatchNorm2d(self.CatChannels)self.h1_PT_hd3_relu = nn.ReLU(inplace=True)# h2->160*160, hd3->80*80, Pooling 2 timesself.h2_PT_hd3 = nn.MaxPool2d(2, 2, ceil_mode=True)self.h2_PT_hd3_conv = nn.Conv2d(filters[1], self.CatChannels, 3, padding=1)self.h2_PT_hd3_bn = nn.BatchNorm2d(self.CatChannels)self.h2_PT_hd3_relu = nn.ReLU(inplace=True)# h3->80*80, hd3->80*80, Concatenationself.h3_Cat_hd3_conv = nn.Conv2d(filters[2], self.CatChannels, 3, padding=1)self.h3_Cat_hd3_bn = nn.BatchNorm2d(self.CatChannels)self.h3_Cat_hd3_relu = nn.ReLU(inplace=True)# hd4->40*40, hd4->80*80, Upsample 2 timesself.hd4_UT_hd3 = nn.Upsample(scale_factor=2, mode='bilinear')  # 14*14self.hd4_UT_hd3_conv = nn.Conv2d(self.UpChannels, self.CatChannels, 3, padding=1)self.hd4_UT_hd3_bn = nn.BatchNorm2d(self.CatChannels)self.hd4_UT_hd3_relu = nn.ReLU(inplace=True)# hd5->20*20, hd4->80*80, Upsample 4 timesself.hd5_UT_hd3 = nn.Upsample(scale_factor=4, mode='bilinear')  # 14*14self.hd5_UT_hd3_conv = nn.Conv2d(filters[4], self.CatChannels, 3, padding=1)self.hd5_UT_hd3_bn = nn.BatchNorm2d(self.CatChannels)self.hd5_UT_hd3_relu = nn.ReLU(inplace=True)# fusion(h1_PT_hd3, h2_PT_hd3, h3_Cat_hd3, hd4_UT_hd3, hd5_UT_hd3)self.conv3d_1 = nn.Conv2d(self.UpChannels, self.UpChannels, 3, padding=1)  # 16self.bn3d_1 = nn.BatchNorm2d(self.UpChannels)self.relu3d_1 = nn.ReLU(inplace=True)'''stage 2d '''# h1->320*320, hd2->160*160, Pooling 2 timesself.h1_PT_hd2 = nn.MaxPool2d(2, 2, ceil_mode=True)self.h1_PT_hd2_conv = nn.Conv2d(filters[0], self.CatChannels, 3, padding=1)self.h1_PT_hd2_bn = nn.BatchNorm2d(self.CatChannels)self.h1_PT_hd2_relu = nn.ReLU(inplace=True)# h2->160*160, hd2->160*160, Concatenationself.h2_Cat_hd2_conv = nn.Conv2d(filters[1], self.CatChannels, 3, padding=1)self.h2_Cat_hd2_bn = nn.BatchNorm2d(self.CatChannels)self.h2_Cat_hd2_relu = nn.ReLU(inplace=True)# hd3->80*80, hd2->160*160, Upsample 2 timesself.hd3_UT_hd2 = nn.Upsample(scale_factor=2, mode='bilinear')  # 14*14self.hd3_UT_hd2_conv = nn.Conv2d(self.UpChannels, self.CatChannels, 3, padding=1)self.hd3_UT_hd2_bn = nn.BatchNorm2d(self.CatChannels)self.hd3_UT_hd2_relu = nn.ReLU(inplace=True)# hd4->40*40, hd2->160*160, Upsample 4 timesself.hd4_UT_hd2 = nn.Upsample(scale_factor=4, mode='bilinear')  # 14*14self.hd4_UT_hd2_conv = nn.Conv2d(self.UpChannels, self.CatChannels, 3, padding=1)self.hd4_UT_hd2_bn = nn.BatchNorm2d(self.CatChannels)self.hd4_UT_hd2_relu = nn.ReLU(inplace=True)# hd5->20*20, hd2->160*160, Upsample 8 timesself.hd5_UT_hd2 = nn.Upsample(scale_factor=8, mode='bilinear')  # 14*14self.hd5_UT_hd2_conv = nn.Conv2d(filters[4], self.CatChannels, 3, padding=1)self.hd5_UT_hd2_bn = nn.BatchNorm2d(self.CatChannels)self.hd5_UT_hd2_relu = nn.ReLU(inplace=True)# fusion(h1_PT_hd2, h2_Cat_hd2, hd3_UT_hd2, hd4_UT_hd2, hd5_UT_hd2)self.conv2d_1 = nn.Conv2d(self.UpChannels, self.UpChannels, 3, padding=1)  # 16self.bn2d_1 = nn.BatchNorm2d(self.UpChannels)self.relu2d_1 = nn.ReLU(inplace=True)'''stage 1d'''# h1->320*320, hd1->320*320, Concatenationself.h1_Cat_hd1_conv = nn.Conv2d(filters[0], self.CatChannels, 3, padding=1)self.h1_Cat_hd1_bn = nn.BatchNorm2d(self.CatChannels)self.h1_Cat_hd1_relu = nn.ReLU(inplace=True)# hd2->160*160, hd1->320*320, Upsample 2 timesself.hd2_UT_hd1 = nn.Upsample(scale_factor=2, mode='bilinear')  # 14*14self.hd2_UT_hd1_conv = nn.Conv2d(self.UpChannels, self.CatChannels, 3, padding=1)self.hd2_UT_hd1_bn = nn.BatchNorm2d(self.CatChannels)self.hd2_UT_hd1_relu = nn.ReLU(inplace=True)# hd3->80*80, hd1->320*320, Upsample 4 timesself.hd3_UT_hd1 = nn.Upsample(scale_factor=4, mode='bilinear')  # 14*14self.hd3_UT_hd1_conv = nn.Conv2d(self.UpChannels, self.CatChannels, 3, padding=1)self.hd3_UT_hd1_bn = nn.BatchNorm2d(self.CatChannels)self.hd3_UT_hd1_relu = nn.ReLU(inplace=True)# hd4->40*40, hd1->320*320, Upsample 8 timesself.hd4_UT_hd1 = nn.Upsample(scale_factor=8, mode='bilinear')  # 14*14self.hd4_UT_hd1_conv = nn.Conv2d(self.UpChannels, self.CatChannels, 3, padding=1)self.hd4_UT_hd1_bn = nn.BatchNorm2d(self.CatChannels)self.hd4_UT_hd1_relu = nn.ReLU(inplace=True)# hd5->20*20, hd1->320*320, Upsample 16 timesself.hd5_UT_hd1 = nn.Upsample(scale_factor=16, mode='bilinear')  # 14*14self.hd5_UT_hd1_conv = nn.Conv2d(filters[4], self.CatChannels, 3, padding=1)self.hd5_UT_hd1_bn = nn.BatchNorm2d(self.CatChannels)self.hd5_UT_hd1_relu = nn.ReLU(inplace=True)# fusion(h1_Cat_hd1, hd2_UT_hd1, hd3_UT_hd1, hd4_UT_hd1, hd5_UT_hd1)self.conv1d_1 = nn.Conv2d(self.UpChannels, self.UpChannels, 3, padding=1)  # 16self.bn1d_1 = nn.BatchNorm2d(self.UpChannels)self.relu1d_1 = nn.ReLU(inplace=True)# outputself.outconv1 = nn.Conv2d(self.UpChannels, n_classes, 3, padding=1)# initialise weightsfor m in self.modules():if isinstance(m, nn.Conv2d):init_weights(m, init_type='kaiming')elif isinstance(m, nn.BatchNorm2d):init_weights(m, init_type='kaiming')def forward(self, inputs):## -------------Encoder-------------h1 = self.conv1(inputs)  # h1->320*320*64h2 = self.maxpool1(h1)h2 = self.conv2(h2)  # h2->160*160*128h3 = self.maxpool2(h2)h3 = self.conv3(h3)  # h3->80*80*256h4 = self.maxpool3(h3)h4 = self.conv4(h4)  # h4->40*40*512h5 = self.maxpool4(h4)hd5 = self.conv5(h5)  # h5->20*20*1024## -------------Decoder-------------h1_PT_hd4 = self.h1_PT_hd4_relu(self.h1_PT_hd4_bn(self.h1_PT_hd4_conv(self.h1_PT_hd4(h1))))h2_PT_hd4 = self.h2_PT_hd4_relu(self.h2_PT_hd4_bn(self.h2_PT_hd4_conv(self.h2_PT_hd4(h2))))h3_PT_hd4 = self.h3_PT_hd4_relu(self.h3_PT_hd4_bn(self.h3_PT_hd4_conv(self.h3_PT_hd4(h3))))h4_Cat_hd4 = self.h4_Cat_hd4_relu(self.h4_Cat_hd4_bn(self.h4_Cat_hd4_conv(h4)))hd5_UT_hd4 = self.hd5_UT_hd4_relu(self.hd5_UT_hd4_bn(self.hd5_UT_hd4_conv(self.hd5_UT_hd4(hd5))))hd4 = self.relu4d_1(self.bn4d_1(self.conv4d_1(torch.cat((h1_PT_hd4, h2_PT_hd4, h3_PT_hd4, h4_Cat_hd4, hd5_UT_hd4), 1))))  # hd4->40*40*UpChannelsh1_PT_hd3 = self.h1_PT_hd3_relu(self.h1_PT_hd3_bn(self.h1_PT_hd3_conv(self.h1_PT_hd3(h1))))h2_PT_hd3 = self.h2_PT_hd3_relu(self.h2_PT_hd3_bn(self.h2_PT_hd3_conv(self.h2_PT_hd3(h2))))h3_Cat_hd3 = self.h3_Cat_hd3_relu(self.h3_Cat_hd3_bn(self.h3_Cat_hd3_conv(h3)))hd4_UT_hd3 = self.hd4_UT_hd3_relu(self.hd4_UT_hd3_bn(self.hd4_UT_hd3_conv(self.hd4_UT_hd3(hd4))))hd5_UT_hd3 = self.hd5_UT_hd3_relu(self.hd5_UT_hd3_bn(self.hd5_UT_hd3_conv(self.hd5_UT_hd3(hd5))))hd3 = self.relu3d_1(self.bn3d_1(self.conv3d_1(torch.cat((h1_PT_hd3, h2_PT_hd3, h3_Cat_hd3, hd4_UT_hd3, hd5_UT_hd3), 1))))  # hd3->80*80*UpChannelsh1_PT_hd2 = self.h1_PT_hd2_relu(self.h1_PT_hd2_bn(self.h1_PT_hd2_conv(self.h1_PT_hd2(h1))))h2_Cat_hd2 = self.h2_Cat_hd2_relu(self.h2_Cat_hd2_bn(self.h2_Cat_hd2_conv(h2)))hd3_UT_hd2 = self.hd3_UT_hd2_relu(self.hd3_UT_hd2_bn(self.hd3_UT_hd2_conv(self.hd3_UT_hd2(hd3))))hd4_UT_hd2 = self.hd4_UT_hd2_relu(self.hd4_UT_hd2_bn(self.hd4_UT_hd2_conv(self.hd4_UT_hd2(hd4))))hd5_UT_hd2 = self.hd5_UT_hd2_relu(self.hd5_UT_hd2_bn(self.hd5_UT_hd2_conv(self.hd5_UT_hd2(hd5))))hd2 = self.relu2d_1(self.bn2d_1(self.conv2d_1(torch.cat((h1_PT_hd2, h2_Cat_hd2, hd3_UT_hd2, hd4_UT_hd2, hd5_UT_hd2), 1))))  # hd2->160*160*UpChannelsh1_Cat_hd1 = self.h1_Cat_hd1_relu(self.h1_Cat_hd1_bn(self.h1_Cat_hd1_conv(h1)))hd2_UT_hd1 = self.hd2_UT_hd1_relu(self.hd2_UT_hd1_bn(self.hd2_UT_hd1_conv(self.hd2_UT_hd1(hd2))))hd3_UT_hd1 = self.hd3_UT_hd1_relu(self.hd3_UT_hd1_bn(self.hd3_UT_hd1_conv(self.hd3_UT_hd1(hd3))))hd4_UT_hd1 = self.hd4_UT_hd1_relu(self.hd4_UT_hd1_bn(self.hd4_UT_hd1_conv(self.hd4_UT_hd1(hd4))))hd5_UT_hd1 = self.hd5_UT_hd1_relu(self.hd5_UT_hd1_bn(self.hd5_UT_hd1_conv(self.hd5_UT_hd1(hd5))))hd1 = self.relu1d_1(self.bn1d_1(self.conv1d_1(torch.cat((h1_Cat_hd1, hd2_UT_hd1, hd3_UT_hd1, hd4_UT_hd1, hd5_UT_hd1), 1))))  # hd1->320*320*UpChannelsd1 = self.outconv1(hd1)  # d1->320*320*n_classesreturn F.sigmoid(d1)

第四步:统计一些指标(训练过程中的loss和miou)

第五步:搭建GUI界面

第六步:整个工程的内容

有训练代码和训练好的模型以及训练过程,提供数据,提供GUI界面代码

代码见:

有问题可以私信或者留言,有问必答

e0420b8919fe4c1cb3d1e3dd52176a8a.png

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

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

相关文章

探索机器学习中的特征选择技术

在机器学习和数据科学领域,特征选择是一个关键步骤,它不仅有助于提高模型的性能,还能帮助我们更好地理解数据。本文将深入探讨特征选择的重要性、常见方法以及如何在实际项目中应用这些技术。 一、特征选择的重要性 降低维度:减…

二叉查找树(Binary Search Tree)Java语言实现

一、二叉查找树 二叉查找树(Binary Search Tree),也称为二叉搜索树、有序二叉树(Ordered Binary Tree)或排序二叉树(Sorted Binary Tree)。 是指一棵空树或者具有下列性质的二叉树&#xff1a…

Android 无Bug版 多语言设计方案!

出海业务为什么要做多语言? 1.市场扩大与本地化需求: 通过支持多种语言,出海项目可以触及更广泛的国际用户群体,进而扩大其市场份额。 本地化是吸引国际用户的重要策略之一,而语言本地化是其中的核心。使用用户的母语…

NFT Insider #151:The Sandbox 推出 Alpha 第4季;腾讯或将收购育碧

市场数据 加密艺术及收藏品新闻 Beeple 将于 11 月在南京德基美术馆举办个人首展 著名数字艺术家 Beeple 近日在X平台发布视频,宣布将于 2024 年 11 月 14 日在南京德基美术馆举办个人首次展览,名为《Beeple:来自合成未来的故事》。该展览将…

【计算机网络】详谈TCP协议确认应答机制捎带应答机制超时重传机制连接管理机制流量管理机制滑动窗口拥塞控制延迟应答

一、TCP 协议段格式 1.1、4位首部长度 4位首部长度的基本单位是4字节,也就是说如果4位首部长度填6,那报头长度就是24字节。报头长度的取值范围为[0,60]字节,也就是说选项的最大长度为40字节。 二、确认应答机制 发送数据和发送应答&#x…

vue3 在store的index.js

导入vuex,在store的index.js创建store对象 在main.js挂载store import store from ./storenew Vue ({/* 将store对象实例挂载到vue实例中 所有组件就可以直接从store中获取全局数据了*/ store, render: h > h(App) }).$mount(#app) 在store中的index.js进行声明…

Chainbase :链原生的 Web3 AI 基建设施

“随着 Chainbase 在生态系统和市场方面的进一步拓展,其作为链原生 Web3 AI 基建设施的价值将愈发显著。” 算法、算力和数据是 AI 技术的三大核心要素。实际上,几乎所有的 AI 大模型都在不断革新算法,以确保模型能够跟上行业的发展趋势&…

react实现实时计时的最简方式

js中时间的处理,不借助于moment/dayjs这样的工具库,原生获取格式化的时间,最简单的实现方式可以参考下面这样。 实现效果 代码实现 封装hooks import { useState, useEffect } from "react";export function useCountTime() {c…

手动nginx平滑升级

一、下载nginx安装包 wget http://nginx.org/download/nginx-1.24.0.tar.gz 二、解压缩 tar -zxf nginx-1.24.0.tar.gz 三、进入解压缩后文件 3.1 cd /usr/local/nginx/sbin 预编译 进入如下命令 ./configure -prefix/usr/local/nginx --with-http_ssl_module --with…

免费设计元素下载,设计师必备,建议收藏!

设计师找设计素材、免抠元素,背景图等等,就上这6个网站,免费下载! 1、菜鸟图库 免抠图片素材-免抠图片模板免费下载 - 菜鸟图库 这是一个专门为新手设计师提供免费设计素材的网站,站内有非常多设计素材,其…

为什么说期限提醒系统是项目申报的必备工具?

在项目申报的征程中,时间就是生命,时机决定成败。然而,当前项目申报时间管理却面临着诸多棘手的问题,这也让期限提醒系统成为了必不可少的必备工具。那么,它究竟为何如此关键? 目前项目申报时间管理方面面临…

uniapp 锁屏显示插件 Ba-LockShow(可让vue直接具备锁屏显示能力)

简介 Ba-LockShow 是一款可以直接使uniapp的vue界面在锁屏页展示的插件。 支持使vue直接具备锁屏显示能力支持设置锁屏显示和不显示支持唤醒屏幕 截图展示(仅参考) 支持定制、本地包、源码等,有建议和需要,请点击文章结尾“Unia…

世界空间到观察空间的矩阵

1)世界空间到观察空间的矩阵 2)Addressable在不同工程中如何实现打包和加载 3)如何设计角色在下蹲时允许跳跃 4)如何实时编辑玩家的近裁剪面距离 这是第403篇UWA技术知识分享的推送,精选了UWA社区的热门话题&#xff0…

算法系列之十二:多边形区域填充算法--扫描线填充算法(有序边表法)

二、扫描线算法(Scan-Line Filling) 扫描线算法适合对矢量图形进行区域填充,只需要直到多边形区域的几何位置,不需要指定种子点,适合计算机自动进行图形处理的场合使用,比如电脑游戏和三维CAD软件的渲染等等…

智能优化算法-蛇优化算法(SO)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1.内容介绍 蛇优化算法 (Snake Optimization Algorithm, SO) 是一种基于群体智能的元启发式优化算法,它模拟了蛇的捕食行为、运动模式和社会互动,用于解决复杂的优化问题。 SO的工作机制主要包括&a…

二分类-多机器学习模型算法实现对比

准备数据 import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.preprocessing import StandardScaler from sklearn.preprocessing import OneHotEncoder from sklearn.preprocessing import PolynomialFeatures from sklearn.compose impo…

每日一刷——10.14——括号匹配(手写栈来实现)

栈与队列题目 第一题 题目 问题描述】设计一个算法判别一个算术表达式的圆括号是否正确配对 【输入形式】一个以为结尾的算术表达式 【输出形式】若配对,则输出圆括号的对数;否则输出no 【样例输入】 (ab)/(cd) 【样例输出】 2 【样例说明】共有两对括…

学习Redisson实现分布式锁

官网&#xff1a;https://redisson.org/ 官方文档&#xff1a;https://redisson.org/docs/getting-started/ 官方中文文档&#xff1a;https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95 1、引入依赖 <!--redisson--> <dependency><groupId>or…

【软件工程】数据流图DFD

文章目录 数据流图DFD概述一、数据流图的基本元素二、数据流图的绘制步骤三、数据流图的分层设计四、数据流图的绘制原则五、数据流图的应用 一个完整的数据流包含哪些要素从图中找出所有数据流1. **理解数据流图的结构**2. **识别外部实体**3. **追踪数据流**4. **记录数据流*…

SAP S/4 HANA 销售返利

目录 1 简介 2 后台配置 3 主数据 4 业务操作 4.1 场景 1 - 返利应计 4.2 场景 2 - 最终结算 1 简介 在过去 SAP ECC 把“返利”功能集成在了 SD 模块当中&#xff0c;而 SAP S/4 HANA 把“返利”集成在了结算管理功能模块当中。究其原因&#xff0c;主要是 ECC “返利”…