简体   繁体   中英

Creating large adjacency matrix from image in python

I would like to create a large, weighted adjacency matrix from an image (so lots of vertices... in the order of > 10^5 vertices) in python. Weights between adjacent pixels are color gradients (I take care of this). Doing it by iterating through pixels is very slow... it takes over 4 minutes. :-( Are there any libraries that can do this nicely in reasonable time?

The following is my code which runs very slowly:

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)

Thank you!

Python module/library NetworkX has an adjacency matrix implementation. It returns a scipy matrix

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)

returns

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

img_to_graph will do the trick. This creates a so-called "connectivity matrix". The adjacency matrix is such a ubiquitous and important term that sklearn 's departure here is not awesome.

But this function will do the trick. I found that networkx 's function, cited above, was only useful for graphs. In order to convert an image to a networkx graph from a numpy array, you are pretty much reduced to interpreted for loop writing. This is because the networkx library does provide an optimized numpy->graph function, but that function assumes the numpy array is already an adjacency matrix .

This is a compiled -O3 --simd --omp only loop scenario for any reasonably sized images, and may even benefit from some cache optimization strategies (ruling out python3's numba Just-In-Time compiler).

That makes the networkx answer another problem. I'd go ahead and use the sklearn function there:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM