import itertools
import feedparser
import urllib
import io
import pandas
import skimage.segmentation
import networkx
/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pytz/__init__.py:35: UserWarning: Module argparse was already imported from /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.pyc, but /Users/fedorbaart/.virtualenvs/main/lib/python2.7/site-packages is being added to sys.path from pkg_resources import resource_stream
FEED='http://api.flickr.com/services/feeds/photos_public.gne?tags=beach;sand;waves'
feed = feedparser.parse(FEED)
photos = []
for entry in feed.entries:
for link in entry.links:
if link['rel'] == 'enclosure':
photos.append(link['href'])
import IPython.display
IPython.display.Image(url=photos[5])
# Read the data as array
f = io.BytesIO(urllib.urlopen(photos[5]).read())
f.seek(0)
img = plt.imread(f, format='jpg')
# What do we have
plt.imshow(img)
<matplotlib.image.AxesImage at 0x100765410>
# Compute superpixels
slice=2 # Reduce because I don't have the fast version built
imgsliced = img[::slice,::slice]
superpixel = skimage.segmentation.slic(imgsliced, n_segments=200,ratio=20)
# use a trick to show a segmented img
plt.imshow(superpixel % 11, cmap='Set3')
<matplotlib.image.AxesImage at 0x107d1b190>
# Create a table of pixels
rows=[]
for (i,j), px in np.ndenumerate(superpixel):
row = [i,j,px]
row.extend(imgsliced[i,j])
rows.append(row)
df = pandas.DataFrame(data=rows, columns=["i", "j", "superpixel", "R", "G", "B"])
# Compute superpixel properties
agg = df.groupby("superpixel").mean()
meaned = np.floor(agg.ix[superpixel.ravel()][["R", "G", "B"]].as_matrix()).astype('uint8')
meaned = meaned.reshape(imgsliced.shape)
# Something went wrong with the means here...
# Triangulate to setup node connections
fig, ax = plt.subplots(figsize=(15,10))
ax.imshow(meaned)
# plot the mean location of each superpixel
ax.plot(agg.j, agg.i, 'k.')
[<matplotlib.lines.Line2D at 0x10979c450>]
# Compute triangulation, can we reduce the number of connections?
tri = matplotlib.tri.triangulation.Triangulation(agg.j, agg.i)
matplotlib.tri.triplot(ax, tri)
# show the figure
fig
# Generate a graph from the triangular network
graph = networkx.Graph()
for (i, row) in agg.iterrows():
graph.add_node(row.name, i=row['i'])
distances = np.sqrt(np.diff(tri.x[tri.edges],1)**2 + np.diff(tri.y[tri.edges],1)**2)
for (edge, distance) in zip(tri.edges, distances):
graph.add_edge(*edge, distance=distance[0])
graphoriginal = graph.copy()
# This should show up as a similar picture to the original node position
networkx.draw_spring(graph, weight="distance")
graph = graphoriginal.copy()
for node in graph.nodes():
plt.plot(agg.ix[node]['j'], agg.ix[node]['i'], 'k.')
for edge in graph.edges():
plt.plot(agg.ix[np.array(edge)]['j'], agg.ix[np.array(edge)]['i'], 'b-')
edges = sorted(graph.edges(data=True), key=lambda x:x[2]['distance'], reverse=True)
i = 0.1
for edge in edges:
# can we toss this one out?
if len(graph.edge[edge[0]]) >4 and len(graph.edge[edge[1]]) >4:
plt.plot(agg.ix[np.array(edge[:2])]['j'], agg.ix[np.array(edge[:2])]['i'], linewidth=1/float(i), color='red')
i += 0.005
graph.remove_edge(edge[0], edge[1])
for node in graph.nodes():
plt.plot(agg.ix[node]['j'], agg.ix[node]['i'], 'k.')
for edge in graph.edges():
plt.plot(agg.ix[np.array(edge)]['j'], agg.ix[np.array(edge)]['i'], 'b-')
# Compute the number of rows and columns
N = len(agg)
# pixels per superpixel
R = float(imgsliced.shape[0])/float(imgsliced.shape[1])
# average height
nrow = int(round((N/R)**0.5))
ncol = int(round((N*R)**0.5))
# Pixelsize, approximately
S = np.sqrt((imgsliced.shape[0]*imgsliced.shape[1])/float(N))
S, imgsliced.shape[0]/S, imgsliced.shape[1]/S
assert nrow*ncol == N, "{} != {}".format(nrow*ncol, N)
# oh, it's just....
rows = superpixel % nrow
cols = superpixel // nrow
(cols*nrow + rows == superpixel).all()
True
df['m'] = rows.ravel()
df['n'] = cols.ravel()
fig, ax = plt.subplots(figsize=(15,10))
ax.imshow(meaned)
# plot the mean location of each superpixel
ax.plot(agg.j, agg.i, 'k.')
for i in range(nrow):
for j in range(ncol):
node0 = j*nrow + i
node1 = j*nrow + i+1
node2 = (j+1)*nrow + i
edge1 = np.array([node0, node1])
edge2 = np.array([node0, node2])
if i<(nrow-1):
ax.plot(agg.ix[edge1]['j'], agg.ix[edge1]['i'], 'k-')
if j<(ncol-1):
ax.plot(agg.ix[edge2]['j'], agg.ix[edge2]['i'], 'k-')
N, R, nrow, ncol, (N/R)**0.5, (N*R)**0.5
(196, 1.0, 14, 14, 14.0, 14.0)