自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(84)
  • 收藏
  • 关注

原创 3Dslicer显示体数据

2024-04-26 14:06:42 37

原创 Anatomy of High-Performance MatrixMultiplication 论文阅读和解析。矩阵乘法GEMM的cache优化

为了高效计算矩阵相乘,并进行并行化放到GPU中运算。需要将矩阵切分成子矩阵,用子矩阵相乘的结果组合为原矩阵相乘的结果:上图是拆分矩阵的方法,M表示矩阵,X方向和Y方向的两个维度都是未知的。P表示横条或竖条,X方向或Y方向有一个方向的维度是极小的。B表示block块,X方向和Y方向的两个维度都是极小的。为了减小单个子矩阵计算量,要拆开A的整行和B的整列。不能让A的整行和B的整列作为子矩阵放入缓存进行计算。因此下图中第二列的Fig8和Fig10拆得最好,把A按列拆,使A的行不再完整,把B按行拆,

2024-04-23 13:49:20 444

原创 读入DICOM图像序列,使用marching cube重建为三维体数据,并输出为.stl格式的文件

【代码】读入DICOM图像序列,使用marching cube重建为三维体数据,并输出为.stl格式的文件。

2024-04-23 13:39:50 234

原创 VTK使用交互器来从三维体数据中提取二维切片

然后根据两点的Y坐标差deltaY,计算新的中心点center并变换至vtkImageSlice当前变换矩阵中,得到变换中心点,将其设置到原来的变换矩阵matrix中,并设置到vtkImageSlice中,最后执行interactor->Render()即可不断的根据鼠标移动刷新图像。当响应到这三个消息时,立即执行vtkImageInteractionCallback的Execute函数,以便实现切片的实时提取和更新。这样在鼠标移动时,只有在确定切片提取标志为1时,执行切片提取功能。

2024-04-05 13:25:03 932

原创 VTK的交互器

也就是说,当vtkRenderWindowInteractor(实际上是它在平台上的具体一个子类,比如在Windows平台下会使用vtkWin32RenderWindowInteractor)看到依赖于平台的事件时,它会使用。4.将对象iren初始化Initialize,调用Start开始进行交互;Start()方法表示开始进入事件响应循环,交互器处于等待状态,等待用户交互事件的发生。r能捕捉渲染窗口中的鼠标和键盘事件,并将这些事件转变为对相机、演员和属性对象的相应操作,具体的转变由交互方式确定;

2024-04-05 13:09:16 816

原创 VTK的派生子类观察者-事件回调方案

派生子类是在vtkCommand类派生的子类内定义一个Execute()函数。在主函数内用这个子类定义一个指针,将指针加入观察者。

2024-04-03 17:27:06 104

原创 VTK的观察者-事件回调方案

calldata:是执行vtkObject::InvokeEvent()函数时,随着回调函数发送得数据,比如说,当调用ProgressEvent事件时,会自动发送当前的进度值作为callback。clientdata:是与VTKCallbackCommand实例相关的数据,简单地说,是指回调函数里需要访问主程序里面得数据时,由主程序向回调函数传递的数据。1.创建一个VTKCallbackCommand对象,并调用VTKCallbackCommand::SetCallback()函数设置所定义的回调函数。

2024-04-03 17:21:56 267

原创 矩阵乘法优化:GEMM中如何将大矩阵切割成小矩阵

此时运算 ops 为 2∗m∗kc∗nc ,同时做的数据搬运量为 kc∗nc+m(kc+2nc) ,我们期望做最小的 io 产生最大的计算,即。就已知的情况来看,fp32 GEMM 极限可达到 10-11 gflops 左右(即 CPU 峰值的 80+%,packA 和 packB 开销跟着矩阵形状走大约是20%),结合具体的任务,例如 2D 卷积、全连接,可以做到 90% 左右。先做第一次拆分,取 A 的 kc 列(PanelA)和 B 的 kc 行(PanelB),得到待累加的一部分结果;

2024-04-01 11:24:26 1157

原创 VTK中polydata的属性数据结构表示和用法

在VTK中多边形数据集是由顶点、多顶点、线、多线、多边形各三角带构成,多边形数据是非结构化的,并且多边形数据集的单元在拓扑维度上有多种变化,顶点、线和多边形构成了用来表达0、1和2维几何图形的基本要素的最小集合,同时用多顶点、多线和三角形带单元来提高效率和性能,特别是用一个三角形带表达N个三角形只需要用N+2个点,但是用传统的表达方法需要用3N个点。是排列在矩形方格中的点和单元的集合,线性网格的拓扑结构是规则的,但其几何结构只有一部分是规则的,也就是说,它的点是沿着坐标轴排列的,但是两点间的间隔可能不同。

2024-04-01 10:52:58 948

原创 VTK对属性参数的设置,以及用vtkFieldData存储属性数据的方法

字段的模型是一个m × n的数据值矩阵,其中m是元组的数量,n是组件的数量。)该字段假定是由一个或多个数据数组组成的集合,其中数组中的数据是不同类型的(例如,int, double, char等),并且每个数组中可能有不同数量的组件。注意,假设每个数据数组的长度为“m”(即元组的数量),这通常对应于数据集中的点或单元格的数量。Interpolate使用提供的权重从源数据中选择的元组进行插值,以在目标数据中生成新的元组。vtkFieldData用来存储数据的属性数据,该数据是对拓扑结构和几何结构信息的补充。

2024-03-26 09:40:55 538 1

原创 VTK的属性数据

VTK的属性数据类型包括:标量属性数据、矢量属性数据、纹理坐标数据、张量属性数据。

2024-03-26 09:35:46 163

原创 在VS2013中搭建opengl环境(glfw+glad+glm)

清单列表命令行:/verbose /out:"Debug\glfwtemplate.exe.embed.manifest" /nologo "Debug\glfwtemplate.exe.embed.manifest.res"

2024-03-18 15:46:38 433

原创 VTK中GetOutput()、GetOutputPort()和GetOutput()的区别

GetOutputPort() 返回的是输出端口(output port)的引用。它是一个用于连接到其他算法输入端口的对象,通常在构建VTK管道时使用。

2024-03-18 15:09:54 265

原创 裁剪分割-vtkClipVolume-vtkSelectPolyData类

【代码】裁剪分割-vtkClipVolume-vtkSelectPolyData类。

2024-03-17 10:23:01 223

原创 Anatomy Of High Performance Matrix Multiplication 高性能矩阵乘法剖析

下图左边是一个非常简单的多层内存模型,只有寄存器/ cache/RAM。在这种简单模型结构下考虑优化GEBP,Cmc,n+=Amc,kcBkc,nCmc,n+=Amc,kcBkc,n,其中3个假设基于以上三点假设,上图中GEBP的RAM和cache之间的数据搬移开销为mckc+kcn+2mcnmemops而Cj:=ABj+Cj的计算量为2mckcnflops,那么计算量和数据搬移的比例。问题变成,现实中kckc的选择还受一些其他因素制约,我们将在6.3章节看到。类似地可以分析GEPB和GEDOT操作。

2024-02-19 13:43:13 732

原创 ITK解决无法读取PNG图像的问题

【代码】ITK解决无法读取PNG图像的问题。

2024-02-19 13:39:36 445

原创 【Python】使用vtkJPEGReader从一个目录中读取50张二维图像,将它们使用marchingcube转化为vtkImagedata的三维体数据,并保存为.stl格式输出

请注意,你需要将"input_directory/"替换为你实际的输入目录。

2024-01-19 09:57:16 449

原创 VTK拓扑结构的使用以及不同维度下的操作

在上例的基础上做一些更改,将零维的点拓扑结构改成一维的线拓扑结构。这里实例化了一个vtkCellArray的对象,前文说“点数据(Point Data)定义数据集的几何结构,单元数据(Cell Data)定义数据集的拓扑结构”。所以,vtkCellArray类型的对象vertices就是用来指定数据集polydata的拓扑结构,而polydata的几何结构则是由points来定义的。只有几何结构,没有拓扑结构的vtkDataSet。此处定义的数据集的拓扑结构是零维的点,即单元类型是Vertex(顶点)。

2024-01-19 09:16:47 521

原创 ITK imagedata三维体数据与VTK imagedata三维体数据的互相转换

【代码】ITK imagedata三维体数据与VTK imagedata三维体数据的互相转换。

2024-01-16 10:50:54 420

原创 多帧的DICOM二维图像转化为VTK的imagedata格式三维体数据(C++)

对于多帧的DICOM数据的三维重建,由于VTK不支持多帧数据的直接读取,因此可以利用DCMTK库先读取DICOM数据,再将其转换为vtkimagedata进行后续处理。

2024-01-16 10:49:16 668

原创 VTK将二维图像向三维空间中无参数化的曲面表面进行纹理映射(含代码)

而对于简单的参数模型,可以方便地建立模型与纹理空间的映射关系,例如。,例如,如果要实现重复纹理,只需通过 vtkTransformTextureCoords::SetScale()将纹理坐标每个方向进行放大,如由[0,1]变换到[0,101即可。而根据图形学三维空间变换容易实现模型空间到屏幕空间的变换,因此最终显示在计算机屏幕上的图像即是纹理映射后的结果。实现纹理映射主要是建立纹理空间与模型空间、模型空间与屏幕空间之间的映射关系。的纹理映射技术,通常需要将纹理空间到模型空间的映射分解为两。

2024-01-08 13:10:59 435

原创 Marching Cubes算法再回顾

三维空间中,平行且相邻的两个二维图像(每个图像中的正方形四个像素顶点组成一个基本的像素图像单元)组成一个基本的三维图像单元。一般来说,会出现一个角点在内,一个角点在外,则角点之间的连线(也就是体元的边)必然与等值面相交,根据这个原理就能判断等值面与哪些体元相交。找到含有等值面的体元之后,接下来就是确定等值面与体元边界的交点,体元间的数值都是呈线性变化,求交点时一般采用的是线性插值,如。间距是体素的高度、长度和宽度,或相邻像素之间的距离,这取决于是将数据视为相同的方框还是连续函数中的样本点。

2024-01-08 10:04:39 1269

原创 UNET和FCN的不同

按照论文中的解释,镜像填充的原因是:因为图像 的边界的外面是空白的,没有其它有效像素,而我们预测图像中的像素类别时往往需要参考它的周围像素作为上下文信息,这样才能保持分割的准确性,为了预测边界像素,论文对边界区域进行镜像,来补全边界周围缺失的内容,然后进行预测。大型网络的优点是更强的图像表述能力,而较为简单、数量少的医学影像并没有那么多的内容需要表述,因此也有人发现在小数量级中,分割的SOTA模型与轻量的Unet并没有优势。医学影像往往是多模态的。,而不用要求所有的训练图像和测试图像具有同样的尺寸。

2023-12-06 11:23:57 396

原创 语义分割网络FCN

于是FCN把conv4中的特征对conv7进行2倍上采样之后的特征图进行融合,然后这时候特征图的尺寸为原始图像的1/16,所以再上采样16倍就可以得到原始图像大小的特征图,这种模型叫做FCN-16s。输入图像经过卷积和池化之后,得到的特征图的宽高相对原图缩小了好几倍,所产生图叫做heatmap----热图,热图就是我们最重要的高维特征图图,得到高维特征之后就是最重要的一步也是最后的一步对原图像进行upsampling,也就是上采样,将图像进行放大直到到原图像的大小。这时候就需要物体的一些细节特征。

2023-12-04 13:49:13 158

原创 图像语义分割算法(FCN/U-net)

另外,还有一个问题在于,patch的大小(对context的使用)和定位的准确性这两者之间具有一个trade-off的过程,patch越大,能利用的信息就越多,但是max pooling也更多,导致分类的结果不一定就是中心点的类别,有可能会受到其它点的影响,因此定位会不准确。除此以外,由于U-net处理的是尺寸较大的医学图像,因此也需要切分成小一些的区域分别进行训练,为了处理边界问题,对于大图内部的小区域,可以切的大一些,然后输出只保留内部的部分(相当于用周围真实的图像内容进行镶边);然后将三者进行求和。

2023-12-04 13:44:51 145

原创 YOLOV1 每个网格预测的两个bounding box是怎么得到的

可以想象,一开始的时候,权重是随机的,面对抽象出来的图像的feature信息,其预测的box的信息、confidence的信息、物体类别的条件概率都是随机的,经过了loss函数进行惩罚与优化,使得预测行为越来越好。如此反复进行,直到权重参数调整到这样的情况,面对同样的grid cell,其计算出来的box的信息完全与ground box的位置符合,confidence=1,正确类别的条件概率为1。的宽度和高度相对于整幅图片的宽度和高度的比例,比如图中的框住狗的蓝色网格的宽度。),以及该网格包含的物体属于。

2023-11-16 15:45:53 458

原创 YOLO的bounding boxes

并且为 S x S(S = 7)个grid,如果物体的中心落入该grid中,那么该grid就需要负责检测该物体。YOLO使用了 7×7 网格 (S×S)、2 个bounding boxes (B=2) 和 20 个类别 ©。网络输出就是一个 S × S × (5×B+C)。3.每个框还要负责预测这个框中的物体是什么。4.综上,S×S 个网格,每个网格要预测。1.YOLO将输入的图片resize成。3.2.2 预测形状。

2023-11-13 11:32:56 264

原创 YOLO V1中关于bounding boxs的部分要点

函数公式中 x, y 是使用 平方差值 来描述,而对于 w, h 使用了根号,是为了检测小物体时候,减小偏移量小的时候对于小物体的的敏感度。平方置信度与真实值之间的差异(分为不同的情况讨论:前景(要检测的物体)、背景(无目标处))每个点只有两个候选框,小物体考虑的少,检测效果一般,多标签检测效果不好。网络中,每个 cell 只预测一个类别,若物体的位置重合时,检测困难。对应的损失函数要尽量减小预测值与真实值之间的差距。每个框还要负责预测这个框中的物体是什么。损失函数中的系数,是相应的权重。

2023-11-13 10:07:04 427

原创 量化网络的注意事项

即用一个尾数(Mantissa,尾数有时也称为有效数字,它实际上是有效数字的非正式说法),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数。因为对称量化的缩放方法可能会将 FP32 零映射到 INT8 零,但我们不希望这种情况出现,于是出现了数字信号处理中的均一量化,即。可以看出,对称量化的浮点值和量化值范围都是相对于零对称的。当浮点值域落在 (−1,1) 之间,权重浮点数据的量化运算可使用下式的方法将 FP32 映射到 INT8,这是。取值范围非常广,因此,将网络从。

2023-10-26 09:49:12 77

原创 onnx转换TensorRT的步骤

在onnx-parser中一旦模型parser解析完成,network就自动填好了,成为了serialized network。builder.create_optimization_profile():创建用于dynamic shape输入的配置器。创建network(计算图)是API独需的因为其他两种方法使用parser从onnx导入,不用一层层添加。模型搭建的入口,网络的trt内部表示和引擎都是builder的成员方法生成的。已有的trt不适配,需要将onnx转为trt。推理引擎,可执行的代码段。

2023-10-10 14:03:37 1048 1

原创 TensorRT的步骤详情

Builder紧随着logger出现,是用于构建推理引擎的核心对象,在比较旧的TRT版本中,builder常用于设置一些模式,比如开启int8和fp16,指定最大batch size和work space等等,但随着builder config的完善,这些设置都统一转到了builder config中,以后builder仅作为构建引擎的入口,而不再用于设置这些网络属性,其中相应的成员将被废弃(如上图所示)。1.实际场景中经常需要使用同一个模型来处理不同输入尺寸的数据(不同分辨率的图像,不同长短的句子)

2023-10-10 13:39:55 82

原创 使用Tensorrt的一般步骤

以onnx模型为例检测介绍,主要分为3步,如下图所示,第一步是导入模型,这包括从磁盘上保存的文件加载模型,并将其从原始框架转换为TensorRT网络。该阶段主要完成模型转换(从caffe或TensorFlow到TensorRT),如下图所示,在模型转换时会完成前述优化过程中的层间融合,精度校准。这一步的输出是一个针对特定GPU平台和网络模型的优化过的TensorRT模型,这个TensorRT模型可以序列化存储到磁盘或内存中。TensorRT的使用包括两个阶段:build and deployment。

2023-10-10 13:30:57 179

原创 TensorRT的结构

Network(计算图内容):网络的主体,在使用api搭建网络的过程当中,将不断地向其中添加一些层,并标记网络的输入输出节点,在其他两种workflow中,则使用Parser来加载来自Onnx文件中的网络,就无需一层一层手工添加。buffer相关(数据的内存、显存相关):我们将需要把数据从cpu端搬到gpu端,执行推理计算后,再把数据由gpu端搬回cpu端。Builder(网络原数据):模型搭建的入口,网络的tensorRT内部表示以及可执行程序引擎都是由该对象的成员方法生成的。

2023-10-10 13:29:48 78

原创 我的创作纪念日

提示:你过去写得最好的一段代码是什么?提示:当前创作和你的工作、学习是什么样的关系。提示:可以和大家分享最初成为创作者的初心。提示:在创作的过程中都有哪些收获。提示:职业规划、创作规划等​​。

2023-08-16 13:04:18 35

原创 将朴素矩阵乘法在共享内存中分块,每个线程只计算结果矩阵中的单个元素

在上面的代码例子中,假设对于16×16的块来说,每个块使用16×16×4 = 1KB的存储空间来存放Mds,同理需要1KB空间存放Nds,每个块需要使用2KB的共享存储空间,但是因为线程的硬件限制,每个SM最多容纳768个线程,使得最多只有3个块,那么只能使用共享存储器的6KB的空间,就浪费了10KB的空间了,不过硬件的限制是因显卡的更新换代而不同的,比如GT200中每个SM最大支持1024个线程。用Md_(0,1),Md(1,1)和Nd_(0,0)和Nd(0,1)来计算Pd_(0,1),Pd(1,1)。

2023-08-09 09:44:41 134

原创 【最细节】在矩阵乘法GEMM中优化Shared Memory的访问

1.向量外积的矩阵乘法要取A中一列,B中一行。但A是行主序存储的,要把它改成列主序存储,来使得。这也能避免Bank Conflict。A的长度为TM,B的长度为TN。一次外积共TM * TN次乘累加。一共需要循环BK次,取BK次循环,每次循环中进行TM * TN次乘累加。得到的结果累加为C矩阵的结果。

2023-08-08 10:58:07 227

原创 【GEMM预备工作】行主序和列主序矩阵的内存中的连续性,解决理解问题

在内存存储中,默认矩阵是按照行优先储存的,即矩阵的每一列在内存中是连续的。行优先矩阵储存中行数据是不连续的。而对于列主序的矩阵,是按照列优先储存的,即矩阵的每一行在内存中是连续的。

2023-08-04 10:06:18 1180

原创 论文阅读:矩阵乘法GEMM的cache优化,子矩阵的切分方法Anatomy of High-Performance MatrixMultiplication

矩阵乘法的优化需要将矩阵切分成子矩阵,用子矩阵相乘的结果组合为原矩阵相乘的结果:上图是拆分矩阵的方法,M表示矩阵,X方向和Y方向的两个维度都是未知的。P表示横条或竖条,X方向或Y方向有一个方向的维度是极小的。B表示block块,X方向和Y方向的两个维度都是极小的。为了减小单个子矩阵计算量,要拆开A的整行和B的整列。不能让和作为子矩阵。因此下图中第二列的Fig8和Fig10拆得最好,把A按列拆,使A的行不再完整,把B按行拆,使B的列不再完整。

2023-07-21 09:22:54 589 1

原创 矩阵乘法优化:4x4矩阵块优化方法【CPU端】

MMult_4x4_3:一次计算C矩阵的16个元素:

2023-07-12 10:59:23 488

原创 矩阵乘法优化:1x4矩阵块的各种优化方法【CPU端】

我们一次计算C矩阵的一个元素,这个时候需要遍历A矩阵的一行和B矩阵的一列并做乘加运算。一次计算4个元素(我们在寄存器中累加C的元素,并对a的元素使用寄存器),用指针来寻址B中的元素。NEON指令集优化, 并且为了保持较小问题规模所获得的性能,我们分块矩阵C(以及相应的A和B)一次计算C中的4x4小块(我们在寄存器中累加C的元素,并对a的元素使用寄存器)在MMult_4x4_6的基础上用指针来寻址B中的元素。一次计算C中的4x4小块,将16个循环合并一个。一次计算4个元素(将4个循环合并为1个)

2023-07-12 09:59:33 579

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除