gpt4 book ai didi

python - 如何使用图像的像素创建图形?

转载 作者:行者123 更新时间:2023-12-04 11:30:29 25 4
gpt4 key购买 nike

现在,我有一个图像。我想生成一个加权图 G=(V,E),其中 V 是顶点集,E 是边集(图像中的每个像素作为图中的一个节点)。
但我不知道该怎么做。
有没有人可以帮助我?最好是python。
非常感谢。
问题补充
很抱歉我对问题的描述不够清楚。
我的目标是用图像的像素作为节点的网络来建立网络,然后分析网络的性质来检测目标(也许)。
但是第一步,我需要建立这个网络。我的问题是如何使用图像的像素(RGB)作为网络的节点来建立这个网络来分析图像。
这些节点的边缘可能基于它们的一些特征(位置、外观等)
所以,我只想知道如何建立这个网络?
只是一些简单的例子。谢谢

最佳答案

我也在寻找很好的矢量化答案,但没有找到。最后,我自己做了这件事。我的目的也是尽可能快地加速这些计算。
让我们从这张漂亮的 28 x 27 图像开始:

import numpy as np
x, y = np.meshgrid(np.linspace(-np.pi/2, np.pi/2, 30), np.linspace(-np.pi/2, np.pi/2, 30))
image = (np.sin(x**2+y**2)[1:-1,1:-2] > 0.9).astype(int) #boolean image
image

[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0]
[0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0]
[0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0]
[0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0]
[0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0]
[0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0]
[0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0]
[0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0]
[0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1]
[0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1]
[0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1]
[0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1]
[0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1]
[0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1]
[0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1]
[0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1]
[0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0]
[0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0]
[0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0]
[0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0]
[0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0]
[0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0]
[0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]
网络x
算法的基本原理是识别在右侧和下方具有同伴的单位像素的坐标。网络图的节点应该是任何可散列的对象,以便我们可以使用元组来标记它们。这很容易实现,但效率不高,因为它需要转换 np.array 的项目。成元组:
#CONSTRUCTION OF HORIZONTAL EDGES
hx, hy = np.where(image[1:] & image[:-1]) #horizontal edge start positions
h_units = np.array([hx, hy]).T
h_starts = [tuple(n) for n in h_units]
h_ends = [tuple(n) for n in h_units + (1, 0)] #end positions = start positions shifted by vector (1,0)
horizontal_edges = zip(h_starts, h_ends)

#CONSTRUCTION OF VERTICAL EDGES
vx, vy = np.where(image[:,1:] & image[:,:-1]) #vertical edge start positions
v_units = np.array([vx, vy]).T
v_starts = [tuple(n) for n in v_units]
v_ends = [tuple(n) for n in v_units + (0, 1)] #end positions = start positions shifted by vector (0,1)
vertical_edges = zip(v_starts, v_ends)
让我们看看它的外观:
G = nx.Graph()
G.add_edges_from(horizontal_edges)
G.add_edges_from(vertical_edges)
pos = dict(zip(G.nodes(), G.nodes())) # map node names to coordinates
nx.draw_networkx(G, pos, with_labels=False, node_size=0)
labels={node: f'({node[0]},{node[1]})' for node in G.nodes()}
nx.draw_networkx_labels(G, pos, labels, font_size=6, font_family='serif', font_weight='bold', bbox = dict(fc='lightblue', ec="black", boxstyle="round", lw=1))
plt.show()
enter image description here
图形
Networkx 纯粹是用 Python 构建的,并且在处理大数据(例如具有数百万像素的图像)时执行速度很慢。另一方面,Igraph 是用 C 构建的,但它的支持较少。文档不是那么详细,而是使用内部可视化工具代替 matplotlib。所以基本上 igraph可能是一个复杂的选择,但如果你这样做了,那将是性能的巨大胜利。在实现算法之前,有一些必须知道的重要事实:
  • 节点的索引应该是从 0 开始的整数。这意味着如果你在 igraph.add_vertices() 中处理其他事情,它将被重新索引为 0, 1, 2, ... 并且所有旧的索引名称都保存在 igraph.vs['name']
  • 在使用 igraph.add_edges() 时,不允许包含不存在的顶点索引(不同于 0,1,2,...)的边

  • 考虑到这些要求,减少图像尺寸是一个不错的选择,即将像素重命名为整数 0,1,2, ... 现在我们开始:
    def create_from_edges(edgearray):
    #This function immitates behaviour nx.add_edges_from for empty graph
    g = ig.Graph()
    u, inv = np.unique(edgearray, return_inverse=True)
    e = inv.reshape(edgearray.shape)
    g.add_vertices(u) #add vertices, in any order
    g.add_edges(e) #add edges, in reindexed order
    return g #old indices are kept in g.vs['name']

    #Create array of edges with image pixels enumerated from 1 to N
    image_idx = np.arange(image.size).reshape(*image.shape) #pixels of image indexed with numbers 1 to N
    X, Y = (units.reshape(image.size) for units in np.indices(image.shape)) #X and Y coordinates of image_idx
    idx = np.array([X, Y]).T #layout of nodes

    hx, hy = np.where(image[1:] & image[:-1]) #horizontal edges as 2D indices
    h_starts_idx = image_idx[hx, hy] #image_idx where horizontal edge starts
    h_ends_idx = image_idx[hx+1, hy] #image_idx where horizontal edge starts

    vx, vy = np.where(image[:, 1:] & image[:, :-1]) #vertical edges as 2D indices
    v_starts_idx = image_idx[vx, vy] #image_idx where verical edge starts
    v_ends_idx = image_idx[vx, vy+1] #image_idx where vertical edge starts

    edgearray = np.vstack([np.array([h_starts_idx, h_ends_idx]).T,
    np.array([v_starts_idx, v_ends_idx]).T])
    g = create_from_edges(edgearray)
    还有我的草图,说明了顶点名称的新顺序:
    ig.plot(g, bbox=(450, 450), 
    layout = ig.Layout(idx[g.vs['name']].tolist()), #only lists can be passed in to layout
    vertex_color = 'lightblue', vertex_label = g.vs['name'], vertex_size=14, vertex_label_size=8)
    要求: python-igraph , pycairo (用于绘图)。
    enter image description here

    关于python - 如何使用图像的像素创建图形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63653267/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com