CUDA Cuts: Fast Graph Cuts on the GPU
原文出处:
http://lincccc.blogspot.tw/2011/03/cuda-cuts-fast-graph-cuts-on-gpu_03.html
现在需要代理才能访问,所以就转载了。
[论文笔记] CUDA Cuts: Fast Graph Cuts on the GPU
Paper:V. Vineet, P. J. Narayanan. CUDA cuts: Fast graph cuts on the GPU. In Proc. CVPR Workshop, 2008.
问题概述:Graph cut是一种十分有用和流行的能量优化算法,在计算机视觉领域普遍应用于前背景分割(Image segmentation)、立体视觉(stereo vision)、抠图(Image matting)等。但在获得不错效果的同时,Max-flow / Min-cost问题求解的时间代价却很大。本文作者称其所知最佳的Graph cut实现求解一张640×480的图至少需;从 s 出发的所有边初始化 f(e) = c(e),其余边 f(e) =0。Push-relabel算法将不断重复Push和Label操作,直至任意操作都无法进行。
(更详细的算法步骤推荐查阅Tutorial,点我)
比较形象点,Push-relabel是泛滥的洪水,奔腾向前,堵了就倒流;Ford-Fulkerson则是很温吞的做法,先找个人探路,回来报告能流多少水就开闸放多少。
Push-relabel算法的GPU版:
存储和线程结构:
Grid拥有和输入图片一样的维度,并被分为若干个Block,每个Block的维度为 B×B。每个线程对应一个节点(像素),即每个Block对应 B×B 个节点、需要访问 (B+2)×(B+2) 个节点的数据。每个节点包含以下数据:溢出量 e(u),高度 h(u),活跃状态 flag(u) 以及与其相邻节点间的边的容量。活跃状态共3种:Active,e(u) > 0 且 h(u) = h(v) + 1;Passive,e(u) > 0 且 h(u) ≠ h(v) + 1,这种状态在Relabel后可能变成Active;Inactive,没有溢出且没有相邻残留边,
这些数据存储在全局或设备内存中,被所有线程共享。
(GPU架构及Cuda指南参考NVidia相关手册,点我)
本文作者通过4个Kernel实现GPU版Push-relabel算法:
1) Push Kernel (node u):
| ■ | 将 h(u) 和 e(u) 从全局内存读入到Block共享内存中(使用共享内存是因为一些数据会被相邻线程共享,这种读入方式相对单独的读入更节省时间); |
| ■ | 同步线程(使用共享内存都需要做这一步,为了保证所有内存都被完全读入了); |
| ■ | 将 e(u) 按照Push规则推向相邻节点(不大于边的剩余容量,且 h(u) ≥ h(v) ); |
| ■ | 将以上Preflow记入一个特殊的全局数组 F。 |
之所以记入 F,而不直接写入相邻节点,是因为在并行Push操作时,一个节点的溢出值同时受到多个相邻节点的影响,如果直接写入,可能造成数据的不一致性(Read-after-write data consistency)。因此,作者将原来的Push操作分成了Push和Pull两个Kernel执行(另一种选择是在同一个Kernel中分两部分执行,之间进行一次同步,但是对于Block边缘的节点,这种同步需要等待其他Block的线程,这种Block间的同步并不被所有GPU支持)。
2) Pull Kernel (node u):
| ■ | 读入 F 中推向 u 的Preflow; |
| ■ | 累加所有新的Preflow,得到最终的溢出值,记入 e(u) 到全局内存。 |
3) Local Relabel Kernal (node u):
按照经典Push-relabel算法中的Relabel操作,局部地调整节点的高度
| ■ | 将 h(u) 和 flag(u) 从全局内存读入到Block共享内存中; |
| ■ | 同步线程; |
| ■ | 计算 u 相邻 active / passive 节点的最小高度; |
| ■ | 该最小高度+1,作为新高度写入 h(u) 到全局内存。 |
4) Global Relabel Kernal:
从终点 t 开始,按照广度优先策略,遍历所有节点,更新其高度至正确的距离(节点的高度总是其与终点距离的下限)。迭代次数 k 被记录与全局内存中。
| ■ | 如果 k == 1,所有与 t 相邻且有残留边的节点高度被设为 1; |
| ■ | 所有未被设置的节点检查其相邻节点,若其相邻节点的高度为 k,则设置该节点高度为 k+1; |
| ■ | 更新高度值到全局内存。 |
算法总体流程:
a. 计算能量矩阵 → b. Push+Pull Kernel循环 → c. Local Relabel Kernel循环 → d. Global Relabel Kernel循环 → e. 重复b到d至收敛(没有可进行的Push和Relabel操作)
作者还基于GPU实现了Dynamic graph cut,应用于连续细微变化的Graph cut,通过对前一帧的简单修改形成新图,重用其他数据,加速Max-flow的求解。作者的实验数据称GPU实现可以提速70-100倍。不过具体应用具体分析,提速肯定是有的,多少未知,要待我实现过试验过。据说这个印度人提供的代码Bug颇多,虽然不太信,但还是先做了要重新实现的准备。末了,吐个槽,这论文贡献不大,确实只是发Workshop的水平。
CUDA Cuts: Fast Graph Cuts on the GPU的更多相关文章
- [论文笔记] CUDA Cuts: Fast Graph Cuts on the GPU
Paper:V. Vineet, P. J. Narayanan. CUDA cuts: Fast graph cuts on the GPU. In Proc. CVPR Workshop, 200 ...
- Graph cuts图论分割
Graph cuts是一种十分有用和流行的能量优化算法,在计算机视觉领域普遍应用于前背景分割(Image segmentation).立体视觉(stereo vision).抠图(Image matt ...
- Graph Cuts初步理解
一些知识点的初步理解_8(Graph Cuts,ing...) Graph cuts是一种十分有用和流行的能量优化算法,在计算机视觉领域普遍应用于前背景分割(Image segmentation).立 ...
- Graph Cuts学习笔记2014.5.16----1
进行了一段时间的论文学习后,现在下载了一些代码,准备从OpenCV跟matlab两个方面着手搭建自己的图像分割平台,计划耗时一个月左右的时间! 昨天去西工大,听了一场Graph Asia的报告,里面有 ...
- 图像分割——graph cuts
Graph cuts是一种基于图论的方法,它是一种能量优化算法,在计算机视觉领域应用于前景背景分割,立体视觉,抠图等. 这类方法首先使用无向图G=<V,E>表示要分割的图像,V和E分别是顶 ...
- vs2015+opencv3.3.1+ maxflow-v3.01 c++实现Yuri Boykov 的Interactive Graph Cuts
出的结果不理想. 感觉是tlink的权重的计算有问题,以及参数的设置.三个可设置参数是后面的 i j k .如果你找到了一组好参数请告诉我. 下载地址 http://download.csdn.ne ...
- Win10 x64 + CUDA 10.0 + cuDNN v7.5 + TensorFlow GPU 1.13 安装指南
Win10 x64 + CUDA 10.0 + cuDNN v7.5 + TensorFlow GPU 1.13 安装指南 Update : 2019.03.08 0. 环境说明 硬件:Ryzen R ...
- Meet Dgraph — an open source, scalable, distributed, highly available and fast graph databas
https://dgraph.io/ Meet Dgraph — an open source, scalable, distributed, highly available and fast gr ...
- Ubuntu 16.04 + CUDA 8.0 + cuDNN v5.1 + TensorFlow(GPU support)安装配置详解
随着图像识别和深度学习领域的迅猛发展,GPU时代即将来临.由于GPU处理深度学习算法的高效性,使得配置一台搭载有GPU的服务器变得尤为必要. 本文主要介绍在Ubuntu 16.04环境下如何配置Ten ...
随机推荐
- Sqoop-1.4.6 Merge源码分析与改造使其支持多个merge-key
Sqoop中提供了一个用于合并数据集的工具sqoop-merge.官方文档中的描述可以参考我的另一篇博客Sqoop-1.4.5用户手册. Merge的基本原理是,需要指定新数据集和老数据集的路径,根据 ...
- Django项目实践4 - Django站点管理(后台管理员)
http://blog.csdn.net/pipisorry/article/details/45079751 上篇:Django项目实践3 - Django模型 Introduction 对于某一类 ...
- Python 3 智能发音
真是十分神奇.. import win32com.client import time s = win32com.client.Dispatch("SAPI.SpVoice") s ...
- 2.cocos2dx 3.2中语法的不同之处,lambada表达式的使用和function和bind函数的使用
1 打开建好的T32 Cocos2dx-3.2的一个项目 2 设置Cocos显示窗口的位置是在AppDelegate.cpp中: 3 设置自适应窗口大小的代码是在上面的 ...
- intent flags标记
Intent Flag介绍 FLAG_ACTIVITY_BROUGHT_TO_FRONT 这个标志一般不是由程序代码设置的,如在launchMode中设置singleTask模式时系统帮你设定. F ...
- frameset 与frame 设置的技巧
今天来写点不一样的.如下图: 实现的效果就是原生的类似于导航形式的frameset. frameset 注意: 包含frameset的网页应该只是作为框架而存在,所以不能有body标签. 这个标签可以 ...
- 给定一个数列a1,a2,a3,...,an和m个三元组表示的查询,对于每个查询(i,j,k),输出ai,ai+1,...,aj的升序排列中第k个数。
给定一个数列a1,a2,a3,...,an和m个三元组表示的查询,对于每个查询(i,j,k),输出ai,ai+1,...,aj的升序排列中第k个数. #include <iostream> ...
- Dynamics CRM 为Visual Studio 2015安装CRM Developer Toolkit
从CRM2015的SDK以后Tools的文件夹里就没有了DeveloperToolkit,而DeveloperToolkit还是停留在VS2012版本,这对于我们这种用新版本的童鞋来说比较头疼,我本地 ...
- 关于LT分发系统的设计构想
git地址 https://github.com/cxyxd/LtDistribution 背景 对tomcat做集群,在多机多tomcat的情况下,如果要更新代码,只能手动的将代码复制,粘贴,然后下 ...
- SYBASE的select into与insert into使用和区别
对于表的部分或全部字段的复制,Sybase数据库提供了两种方式:select into和insert into. select into: 语法:select value1, value2, val ...