【问题标题】:Creating large adjacency matrix from image in python从python中的图像创建大型邻接矩阵
【发布时间】:2014-12-21 04:24:10
【问题描述】:

我想在 python 中从图像(这么多顶点......按 > 10^5 个顶点的顺序)创建一个大的加权邻接矩阵。相邻像素之间的权重是颜色渐变(我负责这个)。通过迭代像素来完成它非常慢......它需要超过 4 分钟。 :-( 有没有图书馆可以在合理的时间内很好地做到这一点?

以下是我运行速度非常慢的代码:

def indToCoord(ind, w, h):
    x = ind % w
    y = (ind - x)/h
    return (x,y)

def isAdj(p1, p2, im):
    adj = []
    w, h = im.size
    x1, y1 = p1
    x2, y2 = p2
    if (x1, y1) == (x2, y2):
        return 0
    elif abs(x1 - x2) > 1:
        return 0
    elif abs(y1 - y2) > 1:
        return 0
    elif abs(x1 - x2) + abs(y1 - y2) >= 2:
        return 0

    return util.colorGradient(im, p1, p2)

def adjForPixel(pixels, p1, im):
    return [isAdj(p1,p2,im) for p2 in pixels]

# The following is the function I use to create an Adjacency Matrix from an image
def getAdjMatrix(im):
    width, height = im.size 
    pixels = [(x,y) for x in xrange(width) for y in xrange(height)]

    pixelAdjMatr = [adjForPixel(pixels, p, im) for p in pixels]
    return pixelAdjMatr

adj_matrix = getAdjMatrix(im)

谢谢!

【问题讨论】:

  • 请发布您当前的代码(迭代)以及您的输出示例
  • 谢谢,我已经添加了。
  • 一个像素可以有 2、3 或 4 个相邻像素,并且每个像素对于它的每个 邻居 都有一个颜色渐变值? p1,p2 的颜色渐变值是否与 p2,p1 不同?
  • 没错,它们可以有 2、3 或 4 个相邻像素。 p1, p2 的颜色梯度值与 p2, p1 没有什么不同,尽管计算颜色梯度的计算量并不大。
  • 你的实现非常低效。当您执行“[isAdj(p1,p2,im) for p2 in pixels]”时,您将遍历图像中的每个像素并检查它是否与 p1 相邻。但是你不需要这样做——最多有 4 个像素与 p1 相邻,你可以很容易地直接创建它们的列表。我猜如果您这样做,您的例程将在合理的时间内运行,而无需使用外部库。

标签: python image graph


【解决方案1】:

Python 模块/库 NetworkX 具有邻接矩阵实现。它返回一个 scipy 矩阵

https://networkx.github.io/documentation/latest/reference/generated/networkx.linalg.graphmatrix.adjacency_matrix.html

import networkx as nx
import scipy as sp
g = nx.Graph([(1,1)])
a = nx.adjacency_matrix(g)
print a, type(a)

返回

(0, 0)  1 <class 'scipy.sparse.csr.csr_matrix'>

【讨论】:

  • 很高兴听到。祝你好运!
【解决方案2】:

img_to_graph 可以解决问题。这创建了一个所谓的“连接矩阵”。邻接矩阵是一个如此普遍且重要的术语,以至于sklearn 离开这里并不可怕。

但是这个函数可以解决问题。我发现上面引用的networkx 的函数只对图表有用。为了将图像从numpy 数组转换为networkx 图形,您几乎只能被解释为循环写入。这是因为networkx 库确实提供了优化的numpy-&gt;graph 函数,但该函数假定numpy 数组已经是一个邻接矩阵

这是一个编译后的 -O3 --simd --omp 唯一循环场景,适用于任何合理大小的图像,甚至可能受益于一些缓存优化策略(排除 python3 的 numba Just-In-Time 编译器)。

这使得networkx 回答了另一个问题。我会继续在那里使用sklearn 函数:

sklearn.feature_extraction.image.img_to_graph(your_img)  
# returns scipy.sparse.coo.coo_matrix

【讨论】:

    猜你喜欢
    • 2017-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多