import networkx as nx from PIL import Image, ImageDraw, ImageFont from skimage import morphology import mahotas as mh import string import itertools import graph_tool.all as gt def makeLetterImage(character, size): image = Image.new("RGBA", (720,180), (255,255,255))#600,150 draw = ImageDraw.Draw(image) font = ImageFont.truetype("verdana.ttf", size) draw.text((5, 0), character, (0,0,0), font=font) img_resized = np.array(image.resize((300,75), Image.ANTIALIAS)) letter = img_resized[0:40,0:30,0]<64 r1 = mh.bbox(letter)[0] r2 = mh.bbox(letter)[1] c1 = mh.bbox(letter)[2] c2 = mh.bbox(letter)[3] letter = letter[r1-1:r2+1,c1-1:c2+1] return letter def branchedPoints(skel, showSE=False): X=[] #cross X X0 = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]) X1 = np.array([[1, 0, 1], [0, 1, 0], [1, 0, 1]]) X.append(X0) X.append(X1) #T like T=[] #T0 contains X0 T0=np.array([[2, 1, 2], [1, 1, 1], [2, 2, 2]]) T1=np.array([[1, 2, 1], [2, 1, 2], [1, 2, 2]]) # contains X1 T2=np.array([[2, 1, 2], [1, 1, 2], [2, 1, 2]]) T3=np.array([[1, 2, 2], [2, 1, 2], [1, 2, 1]]) T4=np.array([[2, 2, 2], [1, 1, 1], [2, 1, 2]]) T5=np.array([[2, 2, 1], [2, 1, 2], [1, 2, 1]]) T6=np.array([[2, 1, 2], [2, 1, 1], [2, 1, 2]]) T7=np.array([[1, 2, 1], [2, 1, 2], [2, 2, 1]]) T.append(T0) T.append(T1) T.append(T2) T.append(T3) T.append(T4) T.append(T5) T.append(T6) T.append(T7) #Y like Y=[] Y0=np.array([[1, 0, 1], [0, 1, 0], [2, 1, 2]]) Y1=np.array([[0, 1, 0], [1, 1, 2], [0, 2, 1]]) Y2=np.array([[1, 0, 2], [0, 1, 1], [1, 0, 2]]) Y3=np.array([[0, 2, 1], [1, 1, 2], [0, 1, 0]]) Y4=np.array([[2, 1, 2], [0, 1, 0], [1, 0, 1]]) Y5 = np.rot90(Y3) Y6 = np.rot90(Y4) Y7 = np.rot90(Y5) Y.append(Y0) Y.append(Y1) Y.append(Y2) Y.append(Y3) Y.append(Y4) Y.append(Y5) Y.append(Y6) Y.append(Y7) bp = np.zeros(skel.shape, dtype=int) for x in X: bp = bp + mh.morph.hitmiss(skel,x) for y in Y: bp = bp + mh.morph.hitmiss(skel,y) for t in T: bp = bp + mh.morph.hitmiss(skel,t) if showSE==True: fig = plt.figure(figsize=(4,5)) tX =['X0','X1'] tY =['Y'+str(i) for i in range(0,8)] tT =['T'+str(i) for i in range(0,8)] ti= tX+tY+tT SE=X+Y+T print len(SE), len(ti) n = 1 ti = iter(ti) for se in SE: #print next(ti) #print se mycmap = mpl.colors.ListedColormap(['black','blue','red']) ax = fig.add_subplot(4,5,n,frameon=False, xticks=[], yticks=[]) title(str(next(ti))) imshow(se, interpolation='nearest',vmin=0,vmax=2,cmap=mycmap) n = n+1 fig.subplots_adjust(hspace=0.1,wspace=0.08) #ax_cb = fig.add_axes([.9,.25,.1,.3])# color_vals=[0,1,2] #cb = mpl.colorbar.ColorbarBase(ax_cb,cmap=mycmap, ticks=color_vals) #cb.set_ticklabels(['back', 'hit', 'don\'t care']) plt.show() return bp > 0 def endPoints(skel): endpoint1=np.array([[0, 0, 0], [0, 1, 0], [2, 1, 2]]) endpoint2=np.array([[0, 0, 0], [0, 1, 2], [0, 2, 1]]) endpoint3=np.array([[0, 0, 2], [0, 1, 1], [0, 0, 2]]) endpoint4=np.array([[0, 2, 1], [0, 1, 2], [0, 0, 0]]) endpoint5=np.array([[2, 1, 2], [0, 1, 0], [0, 0, 0]]) endpoint6=np.array([[1, 2, 0], [2, 1, 0], [0, 0, 0]]) endpoint7=np.array([[2, 0, 0], [1, 1, 0], [2, 0, 0]]) endpoint8=np.array([[0, 0, 0], [2, 1, 0], [1, 2, 0]]) ep1=mh.morph.hitmiss(skel,endpoint1) ep2=mh.morph.hitmiss(skel,endpoint2) ep3=mh.morph.hitmiss(skel,endpoint3) ep4=mh.morph.hitmiss(skel,endpoint4) ep5=mh.morph.hitmiss(skel,endpoint5) ep6=mh.morph.hitmiss(skel,endpoint6) ep7=mh.morph.hitmiss(skel,endpoint7) ep8=mh.morph.hitmiss(skel,endpoint8) ep = ep1+ep2+ep3+ep4+ep5+ep6+ep7+ep8 return ep > 0 def pruning(skeleton, size): '''remove iteratively end points "size" times from the skeleton ''' for i in range(0, size): endpoints = endPoints(skeleton) endpoints = np.logical_not(endpoints) skeleton = np.logical_and(skeleton,endpoints) return skeleton def edges_from_C8skel(c8skeleton): '''given a skeleton defined on c8 neighborhood (use mahotas), \ returns labeled edges ''' branchedP = branchedPoints(c8skeleton, showSE = False) > 0 endP = endPoints(c8skeleton) > 0 edges = np.logical_not(branchedP)*c8skeleton label_edges,ne = mh.label(edges) return label_edges def labels_in_labeledImage(labImage): return np.where(mh.histogram.fullhistogram(np.uint16(labImage))[:]>0)[0][1:] def SkeletonDecomposition(skeletonC8):#images processing: extraction of branchedpoints, end-points, edges ep = endPoints(skeletonC8) bp = branchedPoints(skeletonC8, showSE = False) ## Label branched-points l_bp,_ = mh.label(bp) #mh.labeled.relabel(l_bp, inplace=True) ## Label the edges l_edges = edges_from_C8skel(skeletonC8) ##Make end-points with the same label than their edge l_ep = ep*l_edges #mh.labeled.relabel(l_ep, inplace=True) ##edges between branched-points endpoints_labels = np.where(mh.histogram.fullhistogram(np.uint16(l_ep))[:]==1)[0] edges_bp = np.copy(l_edges) for l in endpoints_labels: edges_bp[np.where(edges_bp == l)]=0 mh.labeled.relabel(edges_bp, inplace=True) #edges between end-points and branched points edges_ep_to_bp = l_edges * np.logical_not(edges_bp > 0) mh.labeled.relabel(edges_ep_to_bp, inplace=True) Ep_Bp, _ = mh.labeled.relabel(edges_ep_to_bp) Bp_Bp, _ = mh.labeled.relabel(edges_bp) Bp, _ = mh.labeled.relabel(l_bp,inplace=True) Ep, _ = mh.labeled.relabel(l_ep,inplace=True) return Ep_Bp, Bp_Bp , Bp, Ep def labels_in_the_neighbourhood(label, domainimage, edgesImage): ''' gives the values of the labels (edgesImages) in the neighbourhood of a domain of label=l in domainimage. label (int) label value of the domain in domainimage. domainimage : array of domains (typically branched points of a skeleton of one pixel or more) of label l. edgesImage : array of labelled edges defining neighbourhood of domains. ''' se = np.zeros((3,3)) se[:,:]=1 nei = mh.dilate(domainimage==label, Bc=se) nei = np.logical_not(domainimage==1)*nei edges_label = mh.histogram.fullhistogram(np.uint16(edgesImage[nei>0])) #np.where() return np.where(edges_label>0)[0][1:] #Now try to link thedifferent kind of domain (ep or bp) ## we need to know the labels in the neighbourhood of a domain def neighbourhood_of_domain(domainIm, targetIm): neighbourhood_of_domain_in_targetIm = {} ##Labels of bp domains #since labels were relabeled to 1:n, it would be possible to use #domains_labels = np.arange(1,domainIm.max()) domains_labels = np.where(mh.histogram.fullhistogram(np.uint16(domainIm))[:]>0)[0][1:]#tricky, another way? for lab in domains_labels: neighbourhood_of_domain_in_targetIm[lab]=labels_in_the_neighbourhood(lab, domainIm, targetIm)#.tolist() return neighbourhood_of_domain_in_targetIm def inverse_dict_non_unique_mappings(domNeighbourhood_dict): edges_dict = {item: [key for key in domNeighbourhood_dict if item in domNeighbourhood_dict[key]] for value in domNeighbourhood_dict.values() for item in value} return edges_dict def add_bp_to_graph(Graph, Bp): labels_BP = labels_in_labeledImage(Bp) #print labels_BP #add_bp_to_graph(Graph, labels_BP) nodesN = Graph.order() translate_Bplabel_to_Node_index={} for lab in labels_BP: pos = np.where(Bp == lab) #print pos translate_Bplabel_to_Node_index[lab] = nodesN+lab Graph.add_node(nodesN+lab,kind="BP",label=lab, position=pos) return translate_Bplabel_to_Node_index def add_ep_to_graph(Graph, Ep): '''Adds end-points from labelled Ep image to a graph and returns a dictionnary mapping Ep labels into Node index (necessary when adding edges into the graph) ''' translate_Eplabel_to_Node_index={} labels_EP = labels_in_labeledImage(Ep) #print labels_EP nodesN = Graph.order() for lab in labels_EP: pos = np.where(Ep == lab) #print pos translate_Eplabel_to_Node_index[lab] = nodesN+lab Graph.add_node(nodesN+lab,kind="EP",label=lab, position=pos) return translate_Eplabel_to_Node_index se8 = np.array([[True,True,True], [True,True,True], [True,True,True]]) se4 = np.array([[False,True,False], [True,True,True], [False,True,False]]) imK = makeLetterImage('k', 70) skel = mh.thin(imK) skel0 = morphology.medial_axis(imK,mask=se8) skel1= morphology.medial_axis(imK,mask=se4) skel2 = morphology.skeletonize(imK) Ep_Bp, Bp_Bp, Bp, Ep = SkeletonDecomposition(skel) BP1 = branchedPoints(skel1) BP2 = branchedPoints(skel2) figsize(15,5) subplot(241,xticks=[],yticks=[]) title('mahotas thin') imshow(skel+1*imK, interpolation='nearest') subplot(242,xticks=[],yticks=[]) title('skimage medial axis se8') imshow(skel0+1*imK, interpolation='nearest') subplot(243,xticks=[],yticks=[]) title('skimage medial axis se4') imshow(skel1+1*imK, interpolation='nearest') subplot(244,xticks=[],yticks=[]) title('skimage skeletonize') imshow(skel2+1*imK, interpolation='nearest') subplot(245,xticks=[],yticks=[]) title('maho thin()+branched-points') imshow(skel+1*Bp+2*Ep, interpolation='nearest') subplot(246,xticks=[],yticks=[]) title('sk medial axis+branched-points') imshow(skel1+1*BP1, interpolation='nearest') subplot(248,xticks=[],yticks=[]) title('skeletonize+branched-points') imshow(1*skel2+2.0*BP2, interpolation='nearest') figsize(15,20) subplot(151,xticks=[],yticks=[]) imshow(skel, interpolation='nearest') subplot(154,xticks=[],yticks=[]) imshow(Ep_Bp, interpolation='nearest') title('Lab='+str(labels_in_labeledImage(Ep_Bp))) subplot(155,xticks=[],yticks=[]) title('Lab='+str(labels_in_labeledImage(Bp_Bp))) imshow(Bp_Bp, interpolation='nearest') subplot(153,xticks=[],yticks=[]) title('Lab='+str(labels_in_labeledImage(Ep))) imshow(Ep, interpolation='nearest') subplot(152,xticks=[],yticks=[]) title('Lab='+str(labels_in_labeledImage(Bp))) imshow(Bp, interpolation='nearest') figsize(10,20) subplot(151,xticks=[],yticks=[]) title('1') imshow(Bp_Bp==1, interpolation='nearest') subplot(152,xticks=[],yticks=[]) title('2') imshow(Bp_Bp==2, interpolation='nearest') subplot(153,xticks=[],yticks=[]) title('3') imshow(Bp_Bp==3, interpolation='nearest') subplot(154,xticks=[],yticks=[]) title('4') imshow(Bp_Bp==4, interpolation='nearest') subplot(155,xticks=[],yticks=[]) title('5') imshow(Bp_Bp==5, interpolation='nearest') ND_Bp_in_BPBP = neighbourhood_of_domain(Bp,Bp_Bp) ND_Bp_in_EPBP = neighbourhood_of_domain(Bp,Ep_Bp) ND_Ep_in_EPBP = neighbourhood_of_domain(Ep,Ep_Bp) print ND_Bp_in_BPBP print ND_Bp_in_EPBP print ND_Ep_in_EPBP for bp in ND_Bp_in_EPBP.keys(): for edge in itertools.product([bp],ND_Bp_in_EPBP[bp]): print 'edge', edge print inverse_dict_non_unique_mappings(ND_Bp_in_BPBP) print inverse_dict_non_unique_mappings(ND_Bp_in_EPBP) print inverse_dict_non_unique_mappings(ND_Ep_in_EPBP) def C8_Skeleton_To_Graph_01(Graph, C8Skeleton): Ep_Bp, Bp_Bp, Bp, Ep = SkeletonDecomposition(C8Skeleton) print "condition Ep seuls", Bp.max()==0 and Ep.max()>0 print "condition Bp ",Bp.max()>0 #print Graph.order() ## try to add branched points first: check if they exist if Bp.max()>0:# At least one bp map_Bp_nodes = add_bp_to_graph(Graph, Bp)#map label of Bp-image into node index # ex: # map Bp |-> node {1: 1, 2: 2, 3: 3} the labels in the image are equal to th nodes index in the graph map_Ep_nodes = add_ep_to_graph(Graph, Ep) #ex: # map Ep |-> node {1: 4, 2: 5, 3: 6, 4: 7, 5: 8} : the endpoint of label 1 (image) is the node of index 4 in the graph print 'map Bp |-> node',map_Bp_nodes print 'map Ep |-> node',map_Ep_nodes # link End-points and Branched-points #Search label(s) of edges in image containing edges between ep and bp ## first get the neighborhood of all branched domains (one or more pixels) in Ep_Bp image ND_Bp_in_EPBP = neighbourhood_of_domain(Bp,Ep_Bp) ND_Ep_in_EPBP = neighbourhood_of_domain(Ep,Ep_Bp) print ND_Bp_in_EPBP print 'inv:',inverse_dict_non_unique_mappings(ND_Bp_in_EPBP) #Neighbourhood Domain 1 (label=1 in Bp image) has two neighbors of label 1 or 2 in image of edges linking Ep to Bp # {1: array([1, 2]), 2: array([3, 4]), 3: array([5])} #Inverting the dict yields: # {1: [1], 2: [1], 3: [2], 4: [2], 5: [3]} # edge of label 1 (in Ep_Bp) is close to Branched-point of lab=1 in Bp, edge of lab=2 is close to branched point of lab=1 print ND_Ep_in_EPBP print 'inv',inverse_dict_non_unique_mappings(ND_Ep_in_EPBP) map_edges_to_bp = inverse_dict_non_unique_mappings(ND_Bp_in_EPBP) map_edges_to_ep = inverse_dict_non_unique_mappings(ND_Ep_in_EPBP) # ### link Bp to Ep # get a bp for bp in ND_Bp_in_EPBP.keys(): #search edges lab in bp neighbourhood in EPBP edges for ep in ND_Bp_in_EPBP[bp]: vertexbp = map_Bp_nodes[bp]# should be here id to bp vertexep = map_Ep_nodes[ep] w = np.sum(Ep_Bp==ep) # edge weight print ep, vertexbp, vertexep Graph.add_edge(vertexbp,vertexep,weight=w) # # try to link branched-points between them ## get the neighbourhood of branched points in image of edges between bp ND_Bp_in_BPBP = neighbourhood_of_domain(Bp,Bp_Bp) map_edges_to_bp_in_Bp = inverse_dict_non_unique_mappings(ND_Bp_in_BPBP) #### This loop links branched points between them print 'LINKING BP to BP'# TODO FIX IT this yield a wrong graph !! print 'inv EDGES : BP',inverse_dict_non_unique_mappings(ND_Bp_in_BPBP) print len(map_edges_to_bp_in_Bp.keys()) for edge in map_edges_to_bp_in_Bp.keys(): Nb_of_BP = map_edges_to_bp_in_Bp[edge] # Link between two different BP if Nb_of_BP >= 2: current_bp1 = map_edges_to_bp_in_Bp[edge][0] current_bp2 = map_edges_to_bp_in_Bp[edge][1] vertex1 = map_Bp_nodes[current_bp1] vertex2 = map_Bp_nodes[current_bp2] w = np.sum(Bp_Bp==edge) print edge, map_edges_to_bp_in_Bp[edge], current_bp1, current_bp2, w Graph.add_edge(vertex1,vertex2,weight=w) # Self link on one BP if Nb_of_BP == 1: current_bp1 = map_edges_to_bp_in_Bp[edge][0] vertex1 = map_Bp_nodes[current_bp1] w = np.sum(Bp_Bp==edge) print "loop:",edge, map_edges_to_bp_in_Bp[edge], current_bp1, w Graph.add_edge(vertex1,vertex1,weight=w) if Bp.max()==0 and Ep.max()>0: # add Ep first Ep_Ep, edge_number = mh.label(np.logical_and(C8Skeleton,np.logical_not(Ep))) labeled_Ep, Ep_number= mh.label(Ep) map_Ep_nodes = add_ep_to_graph(Graph, labeled_Ep) print 'number of Ep:', Ep_number print 'map Ep |-> node',map_Ep_nodes #link end-points between them, should be only two EP... ND_Ep_in_EPEP = neighbourhood_of_domain(labeled_Ep,Ep_Ep) print "Neighbor of Ep in EpEp",ND_Ep_in_EPEP print 'inv',inverse_dict_non_unique_mappings(ND_Ep_in_EPEP) map_edges_to_ep_in_Ep = inverse_dict_non_unique_mappings(ND_Ep_in_EPEP) for edge in map_edges_to_ep_in_Ep.keys(): print "map edge|-> ep in edge", map_edges_to_ep_in_Ep[edge] print "nb of EP", Ep_number # Link between two different EP if Ep_number == 2: current_ep1 = map_edges_to_ep_in_Ep[edge][0] current_ep2 = map_edges_to_ep_in_Ep[edge][1] vertex1 = map_Ep_nodes[current_ep1] vertex2 = map_Ep_nodes[current_ep2] w = np.sum(Ep_Ep==edge) print "EpEp",edge, map_edges_to_ep_in_Ep[edge], current_ep1, current_ep2, w Graph.add_edge(vertex1,vertex2,weight=w) image_test= makeLetterImage('a', 75) skeleton_test = mh.thin(image_test) _,_,Bp_test,Ep= SkeletonDecomposition(skeleton_test) Ep_Ep = skeleton_test*np.logical_not(Ep) Ep_Ep,_ = mh.label(Ep,Ep) l_Ep, _ = mh.label(Ep) #Ep_Bp, Bp_Bp, Bp, Ep = SkeletonDecomposition(skel) Graph_test = nx.MultiGraph() C8_Skeleton_To_Graph_01(Graph_test, skeleton_test) print Graph_test.edges(data=True) figsize(16,8) subplot(131) imshow(skeleton_test+l_Ep+3*Bp_test,interpolation='nearest') subplot(132, xticks=[],yticks=[]) nx.write_dot(Graph_test,'multi.dot') !neato -T png multi.dot > multi.png imshow(mh.imread('multi.png'), interpolation='nearest') subplot(133) nx.draw_graphviz(Graph_test, prog='neato') imTest = makeLetterImage('b', 75) skelTest = mh.thin(imTest) Ep_Bp, Bp_Bp, Bp, Ep = SkeletonDecomposition(skelTest) GraphTest = nx.Graph() C8_Skeleton_To_Graph_01(GraphTest, skelTest) figsize(20,15) subplot(161,xticks=[],yticks=[]) imshow(2*imTest+1.0*skelTest, interpolation='nearest') subplot(162,xticks=[],yticks=[]) nx.draw(GraphTest) subplot(163,xticks=[],yticks=[]) imshow(Ep_Bp, interpolation='nearest') title('Lab='+str(labels_in_labeledImage(Ep_Bp))) subplot(166,xticks=[],yticks=[]) title('Lab='+str(labels_in_labeledImage(Bp_Bp))) imshow(Bp_Bp, interpolation='nearest') subplot(165,xticks=[],yticks=[]) title('Lab='+str(labels_in_labeledImage(Ep))) imshow(Ep, interpolation='nearest') subplot(164,xticks=[],yticks=[]) title('Lab='+str(labels_in_labeledImage(Bp))) imshow(Bp, interpolation='nearest') Bp0Ep0_a = np.array([[0,0,0,0,0], [0,1,1,1,0], [0,1,0,1,0], [0,1,1,1,0], [0,0,0,0,0]],dtype=int) Bp0Ep0_b = np.array([[0,0,0,0,0], [0,0,1,0,0], [0,1,0,1,0], [0,0,1,0,0], [0,0,0,0,0]],dtype=int) Bp0Ep0_c = np.array([[0,0,0,0,0], [0,0,1,0,0], [0,1,0,1,0], [0,0,1,1,0], [0,0,0,0,0]],dtype=int) Bp0Ep0_d = np.array([[0,0,0], [0,1,0], [0,0,0], ],dtype=int) figsize(5,5) subplot(131,xticks=[],yticks=[]) imshow(Bp0Ep0_a, interpolation='nearest') subplot(132,xticks=[],yticks=[]) imshow(Bp0Ep0_b, interpolation='nearest') subplot(133,xticks=[],yticks=[]) imshow(Bp0Ep0_c, interpolation='nearest') Bp0Ep2_a = np.array([[0,0,0,0,0], [0,1,1,0,0], [0,0,0,0,0]],dtype=int) Bp0Ep2_b = np.array([[0,0,0,0,0], [0,1,1,1,0], [0,0,0,0,0]],dtype=int) Bp0Ep2_c = np.array([[0,0,0,0,0], [0,1,1,1,0], [0,0,0,1,0], [0,0,0,0,0]],dtype=int) Bp0Ep2_d = np.array([[0,0,0,0,0], [0,1,1,0,0], [0,0,0,1,0], [0,0,0,0,0]],dtype=int) Bp0Ep2_e = np.array([[0,0,0,0,0], [0,1,1,0,0], [0,0,1,1,0], [0,0,0,0,0]],dtype=int) Bp0Ep2_f = np.array([[0,0,0,0,0,0], [0,1,1,1,1,0], [0,0,0,0,0,0], [0,0,0,0,0,0]],dtype=int) Bp1Ep1_a = np.array([[0,0,0,0,0], [0,0,1,0,0], [0,1,1,1,0], [0,1,0,1,0], [0,1,1,1,0], [0,0,0,0,0]],dtype=int) Bp1Ep1_b = np.array([[0,0,0,0,0], [0,0,0,1,0], [0,1,1,1,0], [0,1,0,1,0], [0,1,1,1,0], [0,0,0,0,0]],dtype=int) Bp1Ep1_c = np.array([[0,0,0,0,0], [0,0,0,1,0], [0,1,1,1,0], [0,1,0,1,0], [0,1,1,1,0], [0,0,0,0,0]],dtype=int) Bp1Ep1_c = np.array([[0,0,0,0,0,0], [0,0,0,0,1,0], [0,1,1,1,0,0], [0,1,0,1,0,0], [0,1,1,1,0,0], [0,0,0,0,0,0]],dtype=int) alphabet = list(string.ascii_lowercase) ilphabet = [] for l in alphabet: imLetter = makeLetterImage(l, 75) skeletter = mh.thin(imLetter) BP = branchedPoints(skeletter, showSE=False) EP = endPoints(skeletter) ilphabet.append(1*skeletter+2*BP+3*EP) figsize(20,20) for im,n in zip(ilphabet, range(1,27)): subplot(6,5,n,xticks=[],yticks=[]) imshow(im,interpolation='nearest') gralphabet=[] imgraph=[] for l in ilphabet: graph_ = nx.MultiGraph() gralphabet.append(C8_Skeleton_To_Graph_01(graph_, l)) nx.write_dot(graph_,'multi.dot') !neato -T png multi.dot > multi.png imgraph.append(mh.imread('multi.png')) figsize(20,20) for imG,n in zip(imgraph, range(1,26+1)): subplot(6,5,n,xticks=[],yticks=[]) imshow(imG, interpolation='nearest') imphabet = [] for size in [40,50,60,65,90]: imLetter = makeLetterImage('a', size) skeletter = mh.thin(imLetter) BP = branchedPoints(skeletter, showSE=False) EP = endPoints(skeletter) imphabet.append(imLetter+1.0*skeletter+2.0*BP+3.0*EP) graphs = [] for l in imphabet: graph_size = nx.MultiGraph() graphs.append(C8_Skeleton_To_Graph_01(graph_size, l)) nx.write_dot(graph_,'multi.dot') !neato -T png multi.dot > multi.png imgraph.append(mh.imread('multi.png')) figsize(12,12) for im,n in zip(imphabet, [1,2,3,4,5]): subplot(1,5,n,xticks=[],yticks=[]) imshow(im,interpolation='nearest') import graph_tool.all as gt mG = gt.Graph(directed = False) edgeP_image = mG.new_edge_property("object") vertexP_image= mG.new_edge_property("object") mG.edge_properties["image"] = edgeP_image v1 = mG.add_vertex() v2 = mG.add_vertex() v3 = mG.add_vertex() mG.add_edge(v1,v1) mG.add_edge(v1,v2) mG.add_edge(v1,v2) mG.add_edge(v2,v3) mG.add_edge(v1,v3) print mG.list_properties() gt.graph_draw(mG, output_size=(260, 260)) for e in mG.edges(): print e