Reputation: 643
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!
Upvotes: 2
Views: 4254
Reputation: 31256
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
Upvotes: 1
Reputation: 8493
Python module/library NetworkX has an adjacency matrix implementation. It returns a scipy matrix
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'>
Upvotes: 0