# Load and process each in turn, to create a big database of feature/class... train = [] for fn_num, fn in enumerate(lg_fn): print 'Processing %s: (%i of %i)' % (fn, fn_num + 1, len(lg_fn)) # Load line graph... print ' Loading...' f = open(fn, 'r') data = ply2.read(f) f.close() lg = LineGraph() lg.from_dict(data) lg.segment() # Extract features... print ' Extracting features...' fv = lg.features(**feat_param) # Extract labels, to match the features... segs = lg.get_segs() def seg_to_label(seg): tags = lg.get_tags(seg) if len(tags) == 0: return 0 # Its a ligament for tag in tags: if tag[0] == '_': return -1 # Ignored - to be removed from training.
# Load and process each in turn, to create a big database of feature/class... train = [] for fn_num, fn in enumerate(lg_fn): print 'Processing %s: (%i of %i)' % (fn, fn_num+1, len(lg_fn)) # Load line graph... print ' Loading...' f = open(fn, 'r') data = ply2.read(f) f.close() lg = LineGraph() lg.from_dict(data) lg.segment() # Extract features... print ' Extracting features...' fv = lg.features(**feat_param) # Extract labels, to match the features... segs = lg.get_segs() def seg_to_label(seg): tags = lg.get_tags(seg) if len(tags)==0: return 0 # Its a ligament for tag in tags: if tag[0]=='_': return -1 # Ignored - to be removed from training. code = filter(lambda c: c!='_', tag[0])
def add(self, fn): """Given the filename for a LineGraph file this loads it in and splits it into Glyphs, which it dumps into the db. Does nothing if the file is already loaded. returns the number of glyphs added.""" if fn in self.fnl: return 0 self.fnl.append(fn) # Load the LineGraph from the given filename, and get the homography... f = open(fn, 'r') data = ply2.read(f) f.close() lg = LineGraph() lg.from_dict(data) lg.segment() hg = data['element']['homography']['v'].reshape((3, 3)) texture = os.path.normpath( os.path.join(os.path.dirname(fn), data['meta']['image'])) # Create a line bias object to be used in the next step... bias = gen_bias(lg, hg) # First pass - create each glyph object... glyphs = [] for s in xrange(lg.segments): g = Glyph(lg, s, hg, bias=bias) glyphs.append(g if '_' not in map(lambda t: t[0], g.lg.get_tags()) else None) # Second pass - fill in the connectivity information supported by adjacency... link_glyphs = [] for seg, glyph in enumerate(glyphs): if glyph == None: continue if glyph.key == None: continue # Brute force search to find a left partner... if glyph.left == None: best = None for g in glyphs: # Check it satisfies the conditions... if g == None: continue if g.key == None: continue if id(g) == id(glyph): continue if g.offset_y != glyph.offset_y: continue if (g.right_x - g.offset_x) > (glyph.right_x - glyph.offset_x): continue # Check its better than the current best... if best == None or (best.right_x - best.offset_x) < ( g.right_x - g.offset_x): best = g if best != None: glyph.left = (best, []) # Brute force search to find a right partner... if glyph.right == None: best = None for g in glyphs: # Check it satisfies the conditions... if g == None: continue if g.key == None: continue if id(g) == id(glyph): continue if g.offset_y != glyph.offset_y: continue if (g.left_x - g.offset_x) < (glyph.left_x - glyph.offset_x): continue # Check its better than the current best... if best == None or (best.left_x - best.offset_x) > ( g.left_x - g.offset_x): best = g if best != None: glyph.right = (best, []) # Now we have the best matches find common glyphs to link them, and record them... for other, out in [ g for g in [glyph.left, glyph.right] if g != None ]: shared_seg = set([a[1] for a in glyph.adjacent]) & set( [a[1] for a in other.adjacent]) for seg in shared_seg: g = glyphs[seg] if g == None: continue # We have a linking glyph - extract the information... glyph_vert = [a[0] for a in glyph.adjacent if a[1] == seg] other_vert = [a[0] for a in other.adjacent if a[1] == seg] link_glyph = [ a[0] for a in g.adjacent if a[1] == glyph.seg ] link_other = [ a[0] for a in g.adjacent if a[1] == other.seg ] # Check if we have a multi-link scenario - if so choose links... if len(glyph_vert) > 1 or len(other_vert) > 1: gv_y = map(lambda v: glyph.lg.get_vertex(v)[1], glyph_vert) ov_y = map(lambda v: other.lg.get_vertex(v)[1], other_vert) if (max(gv_y) - min(ov_y)) > (max(ov_y) - min(gv_y)): glyph_vert = glyph_vert[numpy.argmax(gv_y)] other_vert = other_vert[numpy.argmin(ov_y)] else: glyph_vert = glyph_vert[numpy.argmin(gv_y)] other_vert = other_vert[numpy.argmax(ov_y)] lg_y = map(lambda v: g.lg.get_vertex(v)[1], link_glyph) lo_y = map(lambda v: g.lg.get_vertex(v)[1], link_other) if (max(lg_y) - min(lo_y)) > (max(lo_y) - min(lg_y)): link_glyph = link_glyph[numpy.argmax(lg_y)] link_other = link_other[numpy.argmin(lo_y)] else: link_glyph = link_glyph[numpy.argmin(lg_y)] link_other = link_other[numpy.argmax(lo_y)] else: # Simple scenario... glyph_vert = glyph_vert[0] other_vert = other_vert[0] link_glyph = link_glyph[0] link_other = link_other[0] # Recreate the link as a simple path - its the only way to be safe!.. try: g = g.clone() nlg = LineGraph() link_glyph, link_other = nlg.from_path( g.lg, link_glyph, link_other) g.lg = nlg link_glyphs.append(g) except: continue # Line is broken in the centre - don't use it. # Add the tuple to the storage... out.append( (g, glyph_vert, other_vert, link_glyph, link_other)) # Third pass - enforce consistancy... for glyph in glyphs: if glyph == None: continue if glyph.left != None: if glyph.left[0].right == None or id( glyph.left[0].right[0]) != id(glyph): # Inconsistancy - break it... glyph.left[0].right = None glyph.left = None if glyph.right != None: if glyph.right[0].left == None or id( glyph.right[0].left[0]) != id(glyph): # Inconsistancy - break it... glyph.right[0].left = None glyph.right = None # Forth pass - add filename tags and add to db (Count and return the glyph count)... count = 0 for glyph in (glyphs + link_glyphs): if glyph == None: continue glyph.lg.add_tag(0, 0.1, 'file:%s' % fn) glyph.lg.add_tag(0, 0.2, 'texture:%s' % texture) glyph.lg.add_tag( 0, 0.3, 'link:left:%s' % ('n' if glyph.left == None else ('g' if len(glyph.left[1]) == 0 else 'l'))) glyph.lg.add_tag( 0, 0.4, 'link:right:%s' % ('n' if glyph.right == None else ('g' if len(glyph.right[1]) == 0 else 'l'))) glyph.lg.add_tag(0, 0.5, 'source:x:%f' % glyph.source[0]) glyph.lg.add_tag(0, 0.6, 'source:y:%f' % glyph.source[1]) if glyph.key != None: count += 1 if glyph.key in self.db: self.db[glyph.key].append(glyph) else: self.db[glyph.key] = [glyph] glyph.code = len(self.by_code) glyph.lg.add_tag(0, 0.5, 'code:%i' % glyph.code) self.by_code.append(glyph) return count
def add(self, fn): """Given the filename for a LineGraph file this loads it in and splits it into Glyphs, which it dumps into the db. Does nothing if the file is already loaded. returns the number of glyphs added.""" if fn in self.fnl: return 0 self.fnl.append(fn) # Load the LineGraph from the given filename, and get the homography... f = open(fn, 'r') data = ply2.read(f) f.close() lg = LineGraph() lg.from_dict(data) lg.segment() hg = data['element']['homography']['v'].reshape((3,3)) texture = os.path.normpath(os.path.join(os.path.dirname(fn), data['meta']['image'])) # Create a line bias object to be used in the next step... bias = gen_bias(lg, hg) # First pass - create each glyph object... glyphs = [] for s in xrange(lg.segments): g = Glyph(lg, s, hg, bias = bias) glyphs.append(g if '_' not in map(lambda t: t[0], g.lg.get_tags()) else None) # Second pass - fill in the connectivity information supported by adjacency... link_glyphs = [] for seg, glyph in enumerate(glyphs): if glyph==None: continue if glyph.key==None: continue # Brute force search to find a left partner... if glyph.left==None: best = None for g in glyphs: # Check it satisfies the conditions... if g==None: continue if g.key==None: continue; if id(g)==id(glyph): continue if g.offset_y!=glyph.offset_y: continue if (g.right_x - g.offset_x) > (glyph.right_x - glyph.offset_x): continue # Check its better than the current best... if best==None or (best.right_x - best.offset_x) < (g.right_x - g.offset_x): best = g if best!=None: glyph.left = (best, []) # Brute force search to find a right partner... if glyph.right==None: best = None for g in glyphs: # Check it satisfies the conditions... if g==None: continue if g.key==None: continue; if id(g)==id(glyph): continue if g.offset_y!=glyph.offset_y: continue if (g.left_x - g.offset_x) < (glyph.left_x - glyph.offset_x): continue # Check its better than the current best... if best==None or (best.left_x - best.offset_x) > (g.left_x - g.offset_x): best = g if best!=None: glyph.right = (best, []) # Now we have the best matches find common glyphs to link them, and record them... for other, out in [g for g in [glyph.left, glyph.right] if g!=None]: shared_seg = set([a[1] for a in glyph.adjacent]) & set([a[1] for a in other.adjacent]) for seg in shared_seg: g = glyphs[seg] if g==None: continue # We have a linking glyph - extract the information... glyph_vert = [a[0] for a in glyph.adjacent if a[1]==seg] other_vert = [a[0] for a in other.adjacent if a[1]==seg] link_glyph = [a[0] for a in g.adjacent if a[1]==glyph.seg] link_other = [a[0] for a in g.adjacent if a[1]==other.seg] # Check if we have a multi-link scenario - if so choose links... if len(glyph_vert)>1 or len(other_vert)>1: gv_y = map(lambda v: glyph.lg.get_vertex(v)[1], glyph_vert) ov_y = map(lambda v: other.lg.get_vertex(v)[1], other_vert) if (max(gv_y) - min(ov_y)) > (max(ov_y) - min(gv_y)): glyph_vert = glyph_vert[numpy.argmax(gv_y)] other_vert = other_vert[numpy.argmin(ov_y)] else: glyph_vert = glyph_vert[numpy.argmin(gv_y)] other_vert = other_vert[numpy.argmax(ov_y)] lg_y = map(lambda v: g.lg.get_vertex(v)[1], link_glyph) lo_y = map(lambda v: g.lg.get_vertex(v)[1], link_other) if (max(lg_y) - min(lo_y)) > (max(lo_y) - min(lg_y)): link_glyph = link_glyph[numpy.argmax(lg_y)] link_other = link_other[numpy.argmin(lo_y)] else: link_glyph = link_glyph[numpy.argmin(lg_y)] link_other = link_other[numpy.argmax(lo_y)] else: # Simple scenario... glyph_vert = glyph_vert[0] other_vert = other_vert[0] link_glyph = link_glyph[0] link_other = link_other[0] # Recreate the link as a simple path - its the only way to be safe!.. try: g = g.clone() nlg = LineGraph() link_glyph, link_other = nlg.from_path(g.lg, link_glyph, link_other) g.lg = nlg link_glyphs.append(g) except: continue # Line is broken in the centre - don't use it. # Add the tuple to the storage... out.append((g, glyph_vert, other_vert, link_glyph, link_other)) # Third pass - enforce consistancy... for glyph in glyphs: if glyph==None: continue if glyph.left!=None: if glyph.left[0].right==None or id(glyph.left[0].right[0])!=id(glyph): # Inconsistancy - break it... glyph.left[0].right = None glyph.left = None if glyph.right!=None: if glyph.right[0].left==None or id(glyph.right[0].left[0])!=id(glyph): # Inconsistancy - break it... glyph.right[0].left = None glyph.right = None # Forth pass - add filename tags and add to db (Count and return the glyph count)... count = 0 for glyph in (glyphs+link_glyphs): if glyph==None: continue glyph.lg.add_tag(0, 0.1, 'file:%s'%fn) glyph.lg.add_tag(0, 0.2, 'texture:%s'%texture) glyph.lg.add_tag(0, 0.3, 'link:left:%s'%('n' if glyph.left==None else ('g' if len(glyph.left[1])==0 else 'l'))) glyph.lg.add_tag(0, 0.4, 'link:right:%s'%('n' if glyph.right==None else ('g' if len(glyph.right[1])==0 else 'l'))) glyph.lg.add_tag(0, 0.5, 'source:x:%f' % glyph.source[0]) glyph.lg.add_tag(0, 0.6, 'source:y:%f' % glyph.source[1]) if glyph.key!=None: count += 1 if glyph.key in self.db: self.db[glyph.key].append(glyph) else: self.db[glyph.key] = [glyph] glyph.code = len(self.by_code) glyph.lg.add_tag(0, 0.5, 'code:%i'%glyph.code) self.by_code.append(glyph) return count