原文出处:

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的更多相关文章

  1. [论文笔记] 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 ...

  2. Graph cuts图论分割

    Graph cuts是一种十分有用和流行的能量优化算法,在计算机视觉领域普遍应用于前背景分割(Image segmentation).立体视觉(stereo vision).抠图(Image matt ...

  3. Graph Cuts初步理解

    一些知识点的初步理解_8(Graph Cuts,ing...) Graph cuts是一种十分有用和流行的能量优化算法,在计算机视觉领域普遍应用于前背景分割(Image segmentation).立 ...

  4. Graph Cuts学习笔记2014.5.16----1

    进行了一段时间的论文学习后,现在下载了一些代码,准备从OpenCV跟matlab两个方面着手搭建自己的图像分割平台,计划耗时一个月左右的时间! 昨天去西工大,听了一场Graph Asia的报告,里面有 ...

  5. 图像分割——graph cuts

    Graph cuts是一种基于图论的方法,它是一种能量优化算法,在计算机视觉领域应用于前景背景分割,立体视觉,抠图等. 这类方法首先使用无向图G=<V,E>表示要分割的图像,V和E分别是顶 ...

  6. vs2015+opencv3.3.1+ maxflow-v3.01 c++实现Yuri Boykov 的Interactive Graph Cuts

    出的结果不理想. 感觉是tlink的权重的计算有问题,以及参数的设置.三个可设置参数是后面的 i j k  .如果你找到了一组好参数请告诉我. 下载地址 http://download.csdn.ne ...

  7. 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 ...

  8. 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 ...

  9. Ubuntu 16.04 + CUDA 8.0 + cuDNN v5.1 + TensorFlow(GPU support)安装配置详解

    随着图像识别和深度学习领域的迅猛发展,GPU时代即将来临.由于GPU处理深度学习算法的高效性,使得配置一台搭载有GPU的服务器变得尤为必要. 本文主要介绍在Ubuntu 16.04环境下如何配置Ten ...

随机推荐

  1. MFC误报内存泄露的修复

    在debug状态退出程序的时候,VS会在输出窗口列出可能的内存泄露的地方. MFC中使用DEBUG_NEW能够更方便的定位泄露的地点.但假如MFC的dll释放""过早"& ...

  2. Android简易实战教程--第三十二话《使用Lrucache和NetworkImageView加载图片》

    转载本专栏每一篇博客请注明转载出处地址,尊重原创.此博客转载链接地址:小杨的博客    http://blog.csdn.net/qq_32059827/article/details/5279131 ...

  3. Oracle EBS各个模块日志收集的方法

    MSCA(Mobile Supply Chain Application)日志的收集 Reference Note:338291.1 - Howto Enable WMS / MSCA Logging ...

  4. 磁盘管理,磁盘挂在mount,挂载光盘镜像文件,挂在U盘,umount 卸载命令, dd

    1 mount 命令格式: mount[-t vfstype] -o options device dir 其中: *-t vfstype 指定文件系统的类型,通常不必指定.mount会自动选择正确的 ...

  5. XMPP(二)-基于asmack+openfire的安卓客户端(仿QQ)的介绍以及个人心得

    关于XMPP第一篇-openfire的搭建写完后,就一直在赶本篇所要介绍的这个基于asmack+openfire的安卓客户端,费了不少精力,因为有不少同学在还在焦急的等待着(自恋了呵呵),所以紧赶慢赶 ...

  6. numpy教程:排序、搜索和计数

    http://blog.csdn.net/pipisorry/article/details/51822775 numpy排序.搜索和计数函数和方法.(重新整合过的) ],, , ], [, , ]] ...

  7. iOS开发之字数不一的多标签Demo

    有朋友让帮他写一个封装的字数不一的多标签视图,所以今天将代码展示一下,供大家学习 代码中封装了两种方法,分别是:1.传递数组,数组中是NSString类型的方法:2.传递数组,数组中是NSDictio ...

  8. 复习java逻辑---实现猜数字游戏

    package shopping; import java.util.*; public class SendGiftMenu { public static void main(String[] a ...

  9. Python 自动刷博客浏览量

    哈哈,今天的话题有点那什么了哈.咱们应该秉承学习技术的角度来看,那么就开始今天的话题吧. 思路来源 今天很偶然的一个机会,听到别人在谈论现在的"刷量"行为,于是就激发了我的好奇心. ...

  10. Ubuntu 16.04 安装和使用QQ最简洁的方式

    推荐参考网址: 1  http://www.ubuntukylin.com/ 2  http://www.ubuntukylin.com/application/ Wine QQ 1  http:// ...