MedSegDiff-v2
MedSegDiff-v2本文的贡献包括:
第一个将Transformer集成到基于扩散的通用医学图像分割模型中。
提出了具有U-SA(Uncertain Spatial Attention)的Anchor Condition以减小扩散方差。
提出了具有SS-Former的Semantic Condition,以建模分割噪声和语义特征的相互作用。
在包括5种图像模态的20个器官分割任务上实现了SOTA性能。
总体架构条件模型(绿色UNet):从原始图像中提取分割特征
扩散模型(蓝色UNet):有两个输入分别是锚点条件(蓝色箭头)和噪声分割信息(黑色箭头)
锚定条件与U-SA锚点条件:将条件模型的解码分割特征整合到扩散模型的编码器特征中(蓝色箭头)
U-SA机制用于从条件模型中提取一个粗糙的锚点特征,并将其整合到扩散模型中,为扩散模型提供了一个正确的预测范围,同时也让它进一步完善了预测结果,具体做法如下:
注1:f_c^{-1}是来自原始图像的条件分割特征,f_d^0是噪声分割图像的扩散特征
注2:k_{Gauss}为高斯卷积核目的是做平滑处理,然后取最大值是为了保留最相关的信 ...
ConvFormer
ConvFormer论文:《ConvFormer: Plug-and-Play CNN-Style Transformers for Improving Medical Image Segmentation》(MICCAI 2023)
以往方法的不足:
由于训练数据的不足,transformers效果较差(另一方面,医学图像本身的高冗余性)
在CNN-Transformer混合方法中,一方面,训练数据不足会使得transformers学习到次优的长距离依赖性,另一方面,直接将CNNs与transformers结合会使得网络偏向于学习CNNs,因为与transformers相比,CNNs的收敛性更容易实现,特别是在小规模训练数据上。
为解决该问题,作者提出了一个名为ConvFormer的即插即用模块
网络结构:
卷积+池化:
上图最左边是传统的ViT,用一个个的patch作为自注意力的输入。
而作者用二维图像直接建立足够长的长程依赖,而不是分割为一堆一维序列,对于一个输入的图像通过卷积和池化来降低分辨率。
注:
1.上图中CBR是指卷积、批量归一化和Relu的组合
2.d为ViT中的每个 ...
智能指针
1.RAllRAII:用于有效地管理资源的获取和释放。
基本思想:资源的获取应当在对象的构造函数中进行,而资源的释放则应当在对象的析构函数中进行。
RAII 的主要优势:
RAII 可以确保资源的正确获取和释放,避免了手动管理资源时可能发生的错误。
当使用 RAII 时,如果在构造函数中发生异常,对象会在析构函数中自动被销毁,从而保证资源被正确释放。
2.智能指针2.1 普通指针存在的问题内存泄漏: 使用普通指针时,需要手动分配和释放内存,这就需要确保在适当的时候调用 delete 或 delete[] 来释放动态分配的内存,否则会导致会导致内存泄漏。
12345678910111213#include <iostream>int main() { // 动态分配一个整数的内存 int* ptr = new int; // 其他代码... // 忘记释放内存 // delete ptr; // 此行代码注释掉了,导致内存泄漏 return 0;}
注:普通指针不会自动调用析构函数。
悬挂指针:程序中的某个部分释放 ...
C++零碎知识
1.静态绑定与动态绑定“绑定”指的是将一个名字(例如变量名或函数名)与一个特定的实体(变量或函数)关联起来的过程。
静态绑定:在编译阶段确定函数调用关系,编译器根据变量的声明类型或函数的定义位置来选择调用哪个函数
1234567891011121314151617181920class Base {public: void foo() { }};class Derived : public Base {public: void foo() { }};//调用的函数由变量的声明类型所决定int main() { Base obj; obj.foo(); // 静态绑定,调用Base类的foo()函数 Derived obj2; obj2.foo(); // 静态绑定,调用Derived类的foo()函数 return 0;}
动态绑定:在运行时确定函数的调用关系,根据对象的实际类型调用相应的函数。
注:动态绑定适用于虚函数,通过在基类 ...
SpectFormer
SpectFormer论文:《SpectFormer: Frequency and Attention is what you need in a Vision Transformer》(arxiv 2023)
频域层和多头注意力层结合起来,可以使Transformer能够捕捉到适当的特征表示,提升模型的特征建模能力,从而提升模型的性能。
频域层由一个快速傅里叶变换层(FFT)和一个逆傅里叶层(IFFT)构成
注:FFT和IFFT的操作,也可使用小波变换和逆小波变换来实现
FFT把图像信息转到频域空间,然后可以对频域信号进行操作,使用具有可学习权重参数W_c的门控层来确定每个频率分量的权重,以便适当地捕获图像的线条和边缘,如可以去除低频部分,保留高频部分,用于突出图像的主要特征,然后通过IFFT做一个逆变换,把频域图还原到时域中。频域层之后用层归一化和多层感知器 (MLP) 块用于通道混合。
SpecFormer考虑了局部特征,这有助于捕获局部频率,以及更深层的全局特征,这有助于捕获长期依赖关系。
与GFNnet对比:SpecFormer可以更加清晰地捕获局部特征,如图像的线条和边缘 ...
shader
1.GLSL中向量的数据类型
2.Uniformuniform是一种在顶点着色器和片段着色器之间进行数据传递的机制,uniform变量是全局的,其值在每个渲染迭代中对所有顶点或片段是一致的。
变量声明:
1uniform vec3 cameraPosition;
使用:
12345678//返回自窗口初始化以来的秒数float timeValue = glfwGetTime();//将timeValue缩放到[0, 1]范围float greenValue = sin(timeValue) / 2.0f + 0.5f;//查询uniform ourColor的位置值int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");//设置uniform值glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
3.颜色插值OpenGL会自动在顶点着色器和片段着色器之间进行插值
定义顶点着色器和片段着色器:
12345 ...
窗口与三角形
1.窗口创建GLFW窗口对象
GLFWwindow* window = glfwCreateWindow(800, 600, "opengl",NULL,NULL);
800:width
600:height
“opengl”:title
初始化GLEW
1234567glewExperimental = true;//设置 GLEW 的实验性模式if (glewInit() != GLEW_OK){ printf("Init GLEW failed"); glfwTerminate(); return -1;}
窗口渲染框架:
1234567891011121314151617181920212223242526272829303132333435363738394041424344#define GLEW_STATIC#include<GL/glew.h>#include<GLFW/glfw3.h>#include<cstdio>#include<iostream>voi ...
D-LKA Attention
D-LKA Attention论文:《Beyond Self-Attention: Deformable Large Kernel Attention for Medical Image Segmentation》(WACV 2024)
1.网络结构网络结构:
LKA:将卷积分解为三个部分:深度卷积、深度空洞卷积和逐点卷积
LKA吸收了卷积和self-attention的优点,包括局部结构信息、长依赖性和适应性。
DW-Conv:可以利用图像的局部上下文信息
DW-D-Conv:捕获LKA中的长程依赖性方面起到了作用
1×1 Conv:通道维度中的关系
2d-LKA的参数量:
注:普通卷积kernel大小为K,DW-Conv的kernel为K/d,DW-D-Conv的kernel为(2d-1)
3d-LKA的参数量:
d(扩张率)是通过对参数量求导确定的,找使参数量导数为0,即参数量最小的扩张率
D-LKA:在LKA的基础上,使用可变形深度卷积代替深度卷积,用可变形深度空洞卷积代替空洞卷积
注 ...
games作业4
递归绘制贝塞尔曲线1234567891011121314151617181920212223242526272829cv::Point2f recursive_bezier(const std::vector<cv::Point2f> &control_points, float t) { if (control_points.size() == 1) { return control_points[0]; } else { std::vector<cv::Point2f> points; for (int i = 0; i < control_points.size()-1; i++) { cv::Point2f p; p.x = (1-t) * control_points[i].x + t * control_points[i + 1].x; ...
光线追踪
1.Shadow Mapping光栅化的问题:不能很好地表示全局的效果
Shadow Mapping: 主要是为了解决点光源的硬阴影的问题
阴影区域:点对相机可见,而对光源不可见
Shadow Map记录每个pixel是否在阴影区域, 其生成步骤如下:
1.从光源位置出发找出可见点,记录光源可见点的深度,得到光源深度图。
2.从相机出发,找可见点,如果点可见,坐标变换求此点到光源的距离。如果此距离与光源深度图中此位置的深度一致,说明此点可以被光源照到,是为光源、相机能同时看到点;如果不一致,说明是阴影点。
硬阴影与软阴影:
软阴影的形成在于全影和半影的渐变,点光源不存在软阴影问题,出现软阴影一定是光源有大小、不同照射位置有全影和半影这种渐变。
2.Whitted-Styled Ray Tracing光线追踪利用的就是光的可逆性
利用递归的方法进行光线追踪,对每条光线,递归计算其多个弹射点,当前光线所对应的像素值是由全部弹射点共同决定的:
光源的定义:起点+方向
于是,光线上的点可表示为:
3.光线求交点3.1 隐式表面隐式表面求交点:将光线上的一点代入隐式方程中求解 ...