Selective Search与Graph-Based Segmentation python实现(一)

  在用深度学习做完肿瘤分割后,因为需要对比实验,所以当时(2019-4-13)在传统方法里找到过Felzen的Graph-Based Segmentation,而且那个时候还混淆了Graph-Cut分割和Graph-Based分割,因为看名字以为Graph-Based segmentation是一个大的类别,其实并不是。
  当时虽然也学习了关于这个分割算法的知识,但是流于形式,一下就忘了,仅用python里的sklearn包两句话实现了分割,分割后的结果表现为超像素,并不是我需要的,所以不了了之。时隔一个多月,再次因为项目需要借用学姐的代码去分割肝脏,去重新学习这个算法。现在竟然不知不觉对同一个东西有了新的理解高度,虽然说相对于其他人来说可能早就知道这些算法了,但自己相比较与过去有了进步,光这点来说,都是我继续坚持下的动力。
  这篇还未写完,最近很多杂事,过段时间来补充,文中若有错误,望指出。

概念总结:
在这里插入图片描述
这些概念的依赖关系对于我自己理解而言还挺重要的,自底向上理解与实践会更加透彻,所以代码的实现会依次包括如下:(注:这些实现均不是我自己写的,来自于github与教学网站)
1、检测图中是否有回路(两种实现方式,DFS与Union-Find)
2、MST算法
3、Graph-Based segmentation
4、Selective-Search

为了避免篇幅过长,本文 python实现(一),将实现detect cycle

(一)DFS 实现 detect graph cycle

# Python program to detect cycle  
# in a graph 
  
from collections import defaultdict 
  
class Graph(): 
    def __init__(self,vertices): 
        self.graph = defaultdict(list) 
        self.V = vertices 
  
    def addEdge(self,u,v): 
        self.graph[u].append(v) 
  
    def isCyclicUtil(self, v, visited, recStack): 
  
        # Mark current node as visited and  
        # adds to recursion stack 
        visited[v] = True #自己理解,若自己输入的边没有重复或错误时,该结构可以不要
        recStack[v] = True # 自己理解为当前搜索路径上的临时栈
  
        # Recur for all neighbours 
        # if any neighbour is visited and in  
        # recStack then graph is cyclic 
        for neighbour in self.graph[v]: 
            if visited[neighbour] == False: 
                if self.isCyclicUtil(neighbour, visited, recStack) == True: 
                    return True
            elif recStack[neighbour] == True: 
                return True
  
        # The node needs to be poped from  
        # recursion stack before function ends 
        recStack[v] = False
        return False
  
    # Returns true if graph is cyclic else false 
    def isCyclic(self): 
        visited = [False] * self.V 
        recStack = [False] * self.V 
        for node in range(self.V): 
            if visited[node] == False: 
                if self.isCyclicUtil(node,visited,recStack) == True: 
                    return True
        return False
  
g = Graph(4) 
g.addEdge(0, 1) 
g.addEdge(0, 2) 
g.addEdge(1, 2) 
g.addEdge(2, 0) 
g.addEdge(2, 3) 
g.addEdge(3, 3) 
if g.isCyclic() == 1: 
    print("Graph has a cycle")
else: 
    print("Graph has no cycle")

(二)朴素版 Disjoint-Set(Union-Find) 实现 detect graph cycle
注:Disjoint-Set(或者叫做Union-Find)其实只是一种数据结构

# Python Program for union-find algorithm to detect cycle in a undirected graph 
# we have one egde for any two vertex i.e 1-2 is either 1-2 or 2-1 but not both 
   
from collections import defaultdict 
   
#This class represents a undirected graph using adjacency list representation 
class Graph: 
   
    def __init__(self,vertices): 
        self.V= vertices #No. of vertices 
        self.graph = defaultdict(list) # default dictionary to store graph 
   
  
    # function to add an edge to graph 
    def addEdge(self,u,v): 
        self.graph[u].append(v) 
   
    # A utility function to find the subset of an element i 
    def find_parent(self, parent,i): 
        if parent[i] == -1: 
            return i 
        if parent[i]!= -1: 
             return self.find_parent(parent,parent[i]) 
  
    # A utility function to do union of two subsets 
    def union(self,parent,x,y): 
        x_set = self.find_parent(parent, x) 
        y_set = self.find_parent(parent, y) 
        parent[x_set] = y_set 
  
   
   
    # The main function to check whether a given graph 
    # contains cycle or not 
    def isCyclic(self): 
          
        # Allocate memory for creating V subsets and 
        # Initialize all subsets as single element sets 
        parent = [-1]*(self.V) 
  
        # Iterate through all edges of graph, find subset of both 
        # vertices of every edge, if both subsets are same, then 
        # there is cycle in graph. 
        for i in self.graph: 
            for j in self.graph[i]: 
                x = self.find_parent(parent, i)  
                y = self.find_parent(parent, j) 
                if x == y: 
                    return True
                self.union(parent,x,y) 
  
  
# Create a graph given in the above diagram 
g = Graph(3) 
g.addEdge(0, 1) 
g.addEdge(1, 2) 
g.addEdge(2, 0) 
  
if g.isCyclic(): 
    print("Graph contains cycle")
else : 
    print("Graph does not contain cycle ")

(二)优化版 Disjoint-Set(Union-Find) 实现 detect graph cycle
通过union-by-rank和path compression实现优化,
union-by-rank可以解决树的构建过程中degenerate成线性的问题,
path compression则是在查找的过程中将第n层子树直接赋值给父节点,减少下次查找同样的节点其时间开销

# A union by rank and path compression based  
# program to detect cycle in a graph 
from collections import defaultdict 
  
# a structure to represent a graph 
class Graph: 
      
    def __init__(self, num_of_v): 
        self.num_of_v = num_of_v 
        self.edges = defaultdict(list) 
          
    # graph is represented as an  
    # array of edges 
    def add_edge(self, u, v): 
        self.edges[u].append(v) 
  
  
class Subset: 
    def __init__(self, parent, rank): 
        self.parent = parent 
        self.rank = rank 
  
# A utility function to find set of an element 
# node(uses path compression technique) 
def find(subsets, node): 
    if subsets[node].parent != node: 
        # 这儿赋值就是path compression,可以flatten tree
        subsets[node].parent = find(subsets, subsets[node].parent) 
    return subsets[node].parent 
  
# A function that does union of two sets  
# of u and v(uses union by rank) 
def union(subsets, u, v): 
      
    # Attach smaller rank tree under root  
    # of high rank tree(Union by Rank) 
    # union-by-rank
    if subsets[u].rank > subsets[v].rank: 
        subsets[v].parent = u 
    elif subsets[v].rank > subsets[u].rank: 
        subsets[u].parent = v 
          
    # If ranks are same, then make one as  
    # root and increment its rank by one 
    else: 
        subsets[v].parent = u 
        subsets[u].rank += 1
  
# The main function to check whether a given 
# graph contains cycle or not 
def isCycle(graph): 
      
    # Allocate memory for creating sets 
    subsets = [] 
  
    for u in range(graph.num_of_v): 
        subsets.append(Subset(u, 0)) 
  
    # Iterate through all edges of graph,  
    # find sets of both vertices of every  
    # edge, if sets are same, then there 
    # is cycle in graph. 
    for u in graph.edges: 
        u_rep = find(subsets, u) 
  
        for v in graph.edges[u]: 
            v_rep = find(subsets, v) 
  
            if u_rep == v_rep: 
                return True
            else: 
                union(subsets, u_rep, v_rep) 
  
# Driver Code 
g = Graph(3) 
  
# add edge 0-1 
g.add_edge(0, 1) 
  
# add edge 1-2 
g.add_edge(1, 2) 
  
# add edge 0-2 
g.add_edge(0, 2) 
  
if isCycle(g): 
    print('Graph contains cycle') 
else: 
    print('Graph does not contain cycle') 
  
# This code is contributed by 
# Sampath Kumar Surine 
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值