基于图的图像分割源码解析

计算边的代码如下:

def create_edge(img, width, x, y, x1, y1, diff):
    vertex_id = lambda x, y: y * width + x
    w = diff(img, x, y, x1, y1)
    return (vertex_id(x, y), vertex_id(x1, y1), w)

def build_graph(img, width, height, diff, neighborhood_8=False):
# 列表里存放两个节点的id以及距离,例如:(0,1,2.5)
    graph_edges = []
    # y的取值范围为0~height-1
    for y in range(height):
        for x in range(width):
            # 当y=0时,也就是像素矩阵的第一行,此时计算的是第一行两两像素之间的diff
            if x > 0:
                graph_edges.append(create_edge(img, width, x, y, x-1, y, diff))
            if y > 0:
                graph_edges.append(create_edge(img, width, x, y, x, y-1, diff))
            if neighborhood_8:
               	if x > 0 and y > 0:
                   graph_edges.append(create_edge(img, width, x, y, x-1, y-1, diff))
                if x > 0 and y < height-1:
                   graph_edges.append(create_edge(img, width, x, y, x-1, y+1, diff))
   return graph_edges

这段代码主要是用于求图中每个节点之间的距离,x的取值是从0~width-1,y同理。
当y=0,也就是对应于图像像素的第一行,此时计算的是第一行两两像素之间的距离,这里要注意一点,当x和y的值都取0,就是图形矩阵的第一个位置(0,0)时,循环体是不执行任何操作的,也就是计算从(0,1)位置的像素开始,计算(0,1)和(0,0)的距离,(0,2)和(0,1)之间的距离,直到最后一个像素和前一个像素的距离。
当y>0,也就是从图像像素矩阵的第二行开始,计算每个像素和它上方还有左方像素的距离,注意,对于(1,0)来说,左边是没有像素的,此时只计算(1,0)和它上方的像素(0,0)的距离,(1,1)就计算和(0,1)、(1,0)的距离。
如下图:
在这里插入图片描述

# const=K
def segment_graph(graph_edges, num_nodes, const, min_size, threshold_func):
    # Step 1: initialization
    # 初始化一个节点列表,列表存放节点对象
    forest = Forest(num_nodes)
    # edge[2]为之前的graph_edge列表中的元素(0,1,2.5)的第三个值,也就是距离
    weight = lambda edge: edge[2]
    # 用像素之间的距离值进行排序
    sorted_graph = sorted(graph_edges, key=weight)
    # threshold用于调整某个区域内的差异值
    threshold = [ threshold_func(1, const) for _ in range(num_nodes) ]
    # Step 2: merging
    # edge=(0,1,2.5),也就是id为0的节点与id为1的节点之间的距离为2.5
    for edge in sorted_graph:
        # 寻找id_0的母节点(一开始为它本身)
        parent_a = forest.find(edge[0])
        parent_b = forest.find(edge[1])
        #如果两节点的差距小于它们区域内的差距阈值
        a_condition = weight(edge) <= threshold[parent_a]
        b_condition = weight(edge) <= threshold[parent_b]
        if parent_a != parent_b and a_condition and b_condition:
            forest.merge(parent_a, parent_b)
            a = forest.find(parent_a)
            threshold[a] = weight(edge) + threshold_func(forest.nodes[a].size, const)
    return remove_small_components(forest, sorted_graph, min_size)

在这里插入图片描述

def remove_small_components(forest, graph, min_size):
    for edge in graph:
        a = forest.find(edge[0])
        b = forest.find(edge[1])
        if a != b and (forest.size_of(a) < min_size or forest.size_of(b) < min_size):
            forest.merge(a, b)
    return  forest

在这里插入图片描述

# random()返回一个0~1之间的数
def generate_image(forest, width, height):
    # 返回一个RGB像素列表,每个像素的RGB值随机
    random_color = lambda: (int(random()*255), int(random()*255), int(random()*255))
    colors = [random_color() for i in range(width*height)]    
    # 创建一个宽度为width,高度为height的黑色图像
    img = Image.new('RGB', (width, height))
    #返回img的每个像素值,可以用来修改img的像素值
    im = img.load()
    # 过程为,比如x=y=0时,对应id为0的像素,先给它随机赋予一个RGB值
    # 当y=0,x=1时,对应id为1的像素,假设它父母为0(两者一个区域),则im(1,0)=im(0,0),也就时赋予它和0号相同的RGB值
    for y in range(height):
        for x in range(width):
            comp = forest.find(y * width + x)
            im[x, y] = colors[comp]
    return img.transpose(Image.ROTATE_270).transpose(Image.FLIP_LEFT_RIGHT)

基于图的图像分割原理参考的文章:
https://blog.csdn.net/surgewong/article/details/39008861

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值