print 'Found %i line graphs' % len(lg_fn) # 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] == '_':
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 a filename for a linegraph file this loads it, extracts all chunks and stores them in the db.""" if fn in self.fnl: return 0 self.fnl.append(fn) self.kdtree = None # Load the LineGraph from the given filename... data = ply2.read(fn) lg = LineGraph() lg.from_dict(data) texture = os.path.normpath(os.path.join(os.path.dirname(fn), data['meta']['image'])) # Calculate the radius scaler and distance for this line graph, by calculating the median radius... rads = map(lambda i: lg.get_vertex(i)[5], xrange(lg.vertex_count)) rads.sort() median_radius = rads[len(rads)//2] radius_mult = 1.0 / median_radius dist = self.dist * median_radius # Chop it up into chains, extract chunks and store them in the database... ret = 0 for raw_chain in lg.chains(): for chain in filter(lambda c: len(c)>1, [raw_chain, raw_chain[::-1]]): head = 0 tail = 0 length = 0.0 while True: # Move tail so its long enough, or has reached the end... while length<dist and tail+1<len(chain): tail += 1 v1 = lg.get_vertex(chain[tail-1]) v2 = lg.get_vertex(chain[tail]) length += numpy.sqrt((v1[0]-v2[0])**2 + (v1[1]-v2[1])**2) # Create the chunk... chunk = LineGraph() chunk.from_vertices(lg, chain[head:tail+1]) # Tag it... chunk.add_tag(0, 0.1, 'file:%s'%fn) chunk.add_tag(0, 0.2, 'texture:%s'%texture) # Store it... self.chunks.append((chunk, median_radius)) ret += 1 # If tail is at the end exit the loop... if tail+1 >= len(chain): break # Move head along for the next chunk... to_move = dist * self.factor while to_move>0.0 and head+2<len(chain): head += 1 v1 = lg.get_vertex(chain[head-1]) v2 = lg.get_vertex(chain[head]) offset = numpy.sqrt((v1[0]-v2[0])**2 + (v1[1]-v2[1])**2) length -= offset to_move -= offset return ret
def add(self, fn): """Given a filename for a linegraph file this loads it, extracts all chunks and stores them in the db.""" if fn in self.fnl: return 0 self.fnl.append(fn) self.kdtree = None # Load the LineGraph from the given filename... data = ply2.read(fn) lg = LineGraph() lg.from_dict(data) texture = os.path.normpath( os.path.join(os.path.dirname(fn), data['meta']['image'])) # Calculate the radius scaler and distance for this line graph, by calculating the median radius... rads = map(lambda i: lg.get_vertex(i)[5], xrange(lg.vertex_count)) rads.sort() median_radius = rads[len(rads) // 2] radius_mult = 1.0 / median_radius dist = self.dist * median_radius # Chop it up into chains, extract chunks and store them in the database... ret = 0 for raw_chain in lg.chains(): for chain in filter(lambda c: len(c) > 1, [raw_chain, raw_chain[::-1]]): head = 0 tail = 0 length = 0.0 while True: # Move tail so its long enough, or has reached the end... while length < dist and tail + 1 < len(chain): tail += 1 v1 = lg.get_vertex(chain[tail - 1]) v2 = lg.get_vertex(chain[tail]) length += numpy.sqrt((v1[0] - v2[0])**2 + (v1[1] - v2[1])**2) # Create the chunk... chunk = LineGraph() chunk.from_vertices(lg, chain[head:tail + 1]) # Tag it... chunk.add_tag(0, 0.1, 'file:%s' % fn) chunk.add_tag(0, 0.2, 'texture:%s' % texture) # Store it... self.chunks.append((chunk, median_radius)) ret += 1 # If tail is at the end exit the loop... if tail + 1 >= len(chain): break # Move head along for the next chunk... to_move = dist * self.factor while to_move > 0.0 and head + 2 < len(chain): head += 1 v1 = lg.get_vertex(chain[head - 1]) v2 = lg.get_vertex(chain[head]) offset = numpy.sqrt((v1[0] - v2[0])**2 + (v1[1] - v2[1])**2) length -= offset to_move -= offset return ret
# 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.
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