def copy_top_match(querydir, query, ranked_matches, match): topentry = ranked_matches[0] matchedimg = topentry[0] score = topentry[1] dup = "dup" + str(len(ranked_matches) == 1 or score == ranked_matches[1][1]) qlat = float(query.split(',')[1]) qlon = float(query.split(',')[2]) clat = float(matchedimg.split(",")[0]) clon = float(matchedimg.split(",")[1][0:-5]) distance = info.distance(qlat, qlon, clat, clon) queryimgpath = os.path.join(querydir, query + '.pgm') queryoutpath = os.path.join(resultsdir, query + ';query;gt' + str(match) + ';' + dup + ';' + matchedimg + ';' + str(score) + ';' + str(distance) + '.pgm') shutil.copyfile(queryimgpath, queryoutpath) for matchedimg, score in ranked_matches: if score != topentry[1]: break clat = float(matchedimg.split(",")[0]) clon = float(matchedimg.split(",")[1][0:-5]) distance = info.distance(qlat, qlon, clat, clon) matchimgpath = os.path.join(dbdump, '%s.jpg' % matchedimg) matchoutpath = os.path.join(resultsdir, query + ';match;gt' + str(match) + ';' + dup + ';' + matchedimg + ';' + str(score) + ';' + str(distance) + '.jpg') shutil.copy(matchimgpath, matchoutpath)
def copy_top_match(querydir, query, ranked_matches, match): topentry = ranked_matches[0] matchedimg = topentry[0] score = topentry[1] dup = "dup" + str( len(ranked_matches) == 1 or score == ranked_matches[1][1]) qlat = float(query.split(',')[1]) qlon = float(query.split(',')[2]) clat = float(matchedimg.split(",")[0]) clon = float(matchedimg.split(",")[1][0:-5]) distance = info.distance(qlat, qlon, clat, clon) queryimgpath = os.path.join(querydir, query + '.pgm') queryoutpath = os.path.join( resultsdir, query + ';query;gt' + str(match) + ';' + dup + ';' + matchedimg + ';' + str(score) + ';' + str(distance) + '.pgm') shutil.copyfile(queryimgpath, queryoutpath) for matchedimg, score in ranked_matches: if score != topentry[1]: break clat = float(matchedimg.split(",")[0]) clon = float(matchedimg.split(",")[1][0:-5]) distance = info.distance(qlat, qlon, clat, clon) matchimgpath = os.path.join(dbdump, '%s.jpg' % matchedimg) matchoutpath = os.path.join( resultsdir, query + ';match;gt' + str(match) + ';' + dup + ';' + matchedimg + ';' + str(score) + ';' + str(distance) + '.jpg') shutil.copy(matchimgpath, matchoutpath)
def lltom(lat1, lon1, lat2, lon2): """Returns lat2,lon2 relative to lat1,lon1 in meters. Does not handle wraparound at 360.""" if lat1 == lat2 and lon1 == lon2: return [0, 0] dx = distance(lat1, lon1, lat2, lon1) * (-1 if lat2 < lat1 else 1) dy = distance(lat1, lon1, lat1, lon2) * (-1 if lon2 < lon1 else 1) return [dx, dy]
def generateCellCoords(lat, lon, len, distance): #takes lat long as upper left corner and length as distance to go right and down 210 degrees #distance is distance between cells coords = [] candlat1 = lat candlon1 = lon while(info.distance(lat, lon, candlat1, candlon1) < len): candlat2, candlon2 = candlat1, candlon1 while(info.distance(candlat1, candlon1, candlat2, candlon2) < len): coords.append((candlat2, candlon2)) candlat2, candlon2 = em.moveLocation4(candlat2, candlon2, distance, 90) candlat1, candlon1 = em.moveLocation4(candlat1, candlon1, distance, 210) return coords
def hasView(self, C, lat, lon, qlat, qlon, qyaw, thresh): dist = distance(lat, lon, qlat, qlon) rad = min(20, max(3, int(dist/10))) def similar(view): return distance(view.lat, view.lon, qlat, qlon) < thresh def yawof(view): return view.yaw views = list(self.getViews(C, lat, lon, rad)) # print "dist is %d, rad is %d, nviews is %d" % (dist, rad, len(views)) closeyaws = map(lambda (k,v): v, sorted([(distance(v.lat, v.lon, qlat, qlon), yawof(v)) for v in views]))[:10] norm = geom.compute_norm(closeyaws) return any([similar(v) for v in views]), norm
def taggedcopy(self, points, image, correction=False): MIN_SIZE = 1 draw = ImageDraw.Draw(image) def dist(p): return info.distance(p[0].lat, p[0].lon, self.lat, self.lon) points.sort(key=dist, reverse=True) # draw distant first if not correction: points = [(t,(d,p),1) for (t,(d,p)) in points] for tag, (dist, point), correction in points: color = self.colordist(dist, 30.0) size = int(300.0*correction/info.distance(tag.lat, tag.lon, self.lat, self.lon)) fontPath = "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf" font = ImageFont.truetype(fontPath, max(size, MIN_SIZE)) off_x = -size*2 off_y = -size*(len(tag)+1) # start black container top_left = (point[0] + off_x - 3, point[1] + off_y - 1) w = 10 for line in tag: w = max(w, draw.textsize(line, font)[0]) bottom_right = (point[0] + off_x + w + 3, point[1] + off_y + max(size, MIN_SIZE)*len(tag) + 3) img = image.copy() draw2 = ImageDraw.Draw(img) draw2.rectangle([top_left, bottom_right], fill='#000') image = Image.blend(image, img, 0.75) draw = ImageDraw.Draw(image) # end black container draw.ellipse((point[0]-size/2,point[1]-size/2,point[0]+size/2,point[1]+size/2), fill=color) for line in tag: draw.text((point[0] + off_x, point[1] + off_y), line, fill=color, font=font) off_y += max(size, MIN_SIZE) # if dist: # INFO('mapping tag at %f meters error' % dist) return image
def admit(match): line = match[0][:-8] lat, lon = getlatlonfromdbimagename(C, line) dist = info.distance(lat, lon, Q.query_lat, Q.query_lon) if dist < C.amb_cutoff + C.amb_padding: return True return False
def query2(querydir, querysurf, dbdir, mainOutputDir, nClosestCells, copytopmatch, params, copy_top_n_percell=0): lat, lon = info.getQuerySURFCoord(querysurf) closest_cells = util.getclosestcells(lat, lon, dbdir) assert dict(closest_cells)['37.8732916331,-122.268346029'] < 236 or dict(closest_cells)['37.8714489427,-122.272389514'] < 236 or dict(closest_cells)['37.8696062215,-122.273737308'] < 236 built = [ '37.8732916331,-122.268346029', '37.8714489427,-122.272389514', '37.8696062215,-122.273737308', ] closest_cells = filter(lambda c: c[0] in built, closest_cells) outputFilePaths = [] cells_in_range = [(cell, dist) for cell, dist in closest_cells[0:nClosestCells] if dist < cellradius + ambiguity+matchdistance] latquery, lonquery = info.getQuerySURFCoord(querysurf) if verbosity > 0: print "checking query: {0} \t against {1} \t cells".format(querysurf, len(cells_in_range)) for cell, dist in cells_in_range: latcell, loncell = cell.split(',') latcell = float(latcell) loncell = float(loncell) actualdist = info.distance(latquery, lonquery, latcell, loncell) if verbosity > 1: print "querying cell: {0}, distance: {1} with:{2}".format(cell, actualdist, querysurf) outputFilePath = os.path.join(mainOutputDir, querysurf + ',' + cell + ',' + str(actualdist) + ".res") outputFilePaths.append(outputFilePath) # start query query.run_parallel(dbdir, [c for c,d in cells_in_range], querydir, querysurf, outputFilePaths, params) # end query for cell, dist in cells_in_range: latcell, loncell = cell.split(',') latcell = float(latcell) loncell = float(loncell) actualdist = info.distance(latquery, lonquery, latcell, loncell) outputFilePath = os.path.join(mainOutputDir, querysurf + ',' + cell + ',' + str(actualdist) + ".res") if copy_top_n_percell > 0: outputDir = os.path.join(mainOutputDir, querysurf + ',' + cell + ',' + str(actualdist)) copy_topn_results(os.path.join(dbdir, cell), outputDir, outputFilePath, 4) # combined = combine_until_dup(outputFilePaths, 1000) combined = combine_topn_votes(outputFilePaths, float('inf')) # combined = filter_in_range(combined, querysurf) # write_scores(querysurf, combined, "/media/data/combined") [g, y, r, b, o] = check_topn_img(querysurf, combined, topnresults) if copytopmatch: match = g or y or r or b or o copy_top_match(querydir, querysurf.split('surf.npy')[0], combined, match) return [g, y, r, b, o]
def hasView(self, C, lat, lon, qlat, qlon, qyaw, thresh): dist = distance(lat, lon, qlat, qlon) rad = min(20, max(3, int(dist / 10))) def similar(view): return distance(view.lat, view.lon, qlat, qlon) < thresh def yawof(view): return view.yaw views = list(self.getViews(C, lat, lon, rad)) # print "dist is %d, rad is %d, nviews is %d" % (dist, rad, len(views)) closeyaws = map( lambda (k, v): v, sorted([(distance(v.lat, v.lon, qlat, qlon), yawof(v)) for v in views]))[:10] norm = geom.compute_norm(closeyaws) return any([similar(v) for v in views]), norm
def visualize_point_cloud(self, cloudfile, output): cloud = np.load(cloudfile).item() img = self.image.copy() pixels = img.load() for x,y in cloud: d = cloud[x,y] lat, lon = d['lat'], d['lon'] pixels[x,y] = self.colordist(info.distance(lat, lon, self.lat, self.lon)) img = Image.blend(img, self.image, 0.5) img.save(output, 'png')
def skew_location(C, Q): length = 2*C.ambiguity points = [] corner = info.moveLocation(Q.sensor_lat, Q.sensor_lon, (2**.5)*C.ambiguity, -45) for i in range(length+1): row = info.moveLocation(corner[0], corner[1], i, 180) for j in range(length+1): point = info.moveLocation(row[0], row[1], j, 90) if info.distance(Q.sensor_lat, Q.sensor_lon, point[0], point[1]) <= C.ambiguity: points.append(point) return points
def filter_in_range(ranked_matches, querysurf): qlat, qlon = info.getQuerySURFCoord(querysurf) weighted_matches = [] for matchedimg, score in ranked_matches: clat = float(matchedimg.split(",")[0]) clon = float(matchedimg.split(",")[1][0:-5]) distance = info.distance(qlat, qlon, clat, clon) if distance < ambiguity + matchdistance: weighted_matches.append((matchedimg, 2 * score)) weighted_matches.sort(key=lambda x: x[1], reverse=True) return weighted_matches
def filter_in_range(ranked_matches, querysurf): qlat, qlon = info.getQuerySURFCoord(querysurf) weighted_matches = [] for matchedimg, score in ranked_matches: clat = float(matchedimg.split(",")[0]) clon = float(matchedimg.split(",")[1][0:-5]) distance = info.distance(qlat, qlon, clat, clon) if distance < ambiguity+matchdistance: weighted_matches.append((matchedimg, 2 * score)) weighted_matches.sort(key=lambda x: x[1], reverse=True) return weighted_matches
def getNumJPGInRange(lat, lon, inputDir, radius, files): """counts all images in inputDir within radius of given coordinate makes assumption about format of filename""" if os.path.exists(inputDir): count = 0 for file in files: lat2, lon2 = info.getImgCoord(str(file)) dist = info.distance(lat, lon, lat2, lon2) if(dist < radius): count+=1 return count else: raise OSError("{p} does not exist.".format(p=inputDir))
def skew_location(querysift, radius): center = info.getQuerySIFTCoord(querysift) length = 2*radius points = [] corner = info.moveLocation(center[0], center[1], (2**.5)*radius, -45) for i in range(length+1): row = info.moveLocation(corner[0], corner[1], i, 180) for j in range(length+1): point = info.moveLocation(row[0],row[1], j, 90) if info.distance(center[0],center[1], point[0], point[1]) <= radius: points.append(point) return points
def select_frustum(self, lat, lon, yaw, fov=270, radius=100): contained = [] for tag in self.tags: dist = info.distance(lat, lon, tag.lat, tag.lon) if dist > radius: continue v1 = (math.sin(math.radians(yaw)), math.cos(math.radians(yaw))) v2 = (tag.lon-lon, tag.lat-lat)/linalg.norm((tag.lon-lon, tag.lat-lat)) degrees = math.acos(np.dot(v1,v2))*180/math.pi assert degrees > 0 if degrees > fov/2: continue contained.append(tag) return contained
def copySIFTInRange(lat, lon, inputDir, outputDir, radius, files): """puts all sift files in inputDir within radius of given coordinate into outputDir. makes assumption about format of filename""" if not os.path.exists(outputDir): try: os.makedirs(outputDir) except Exception: print "Error making directory...quitting..." return for file in files: lat2, lon2 = info.getSIFTCoord(str(file)) dist = info.distance(lat, lon, lat2, lon2) if(dist < radius): os.symlink(os.path.join(os.path.abspath(inputDir + '/'), file), os.path.join(outputDir + '/', file))
def select_frustum(self, lat, lon, yaw, fov=270, radius=100): contained = [] for tag in self.tags: dist = info.distance(lat, lon, tag.lat, tag.lon) if dist > radius: continue v1 = (math.sin(math.radians(yaw)), math.cos(math.radians(yaw))) v2 = (tag.lon - lon, tag.lat - lat) / linalg.norm( (tag.lon - lon, tag.lat - lat)) degrees = math.acos(np.dot(v1, v2)) * 180 / math.pi assert degrees > 0 if degrees > fov / 2: continue contained.append(tag) return contained
def getclosestcell(lat, lon, celldir): if not os.path.exists(celldir): return dirs = getdirs(celldir) closest_dist = float('inf') closest_cell = '' for dir in dirs: lat2, lon2 = dir.split(',') lat2 = float(lat2) lon2 = float(lon2) dist = info.distance(lat, lon, lat2, lon2) if dist < closest_dist: closest_dist = dist closest_cell = dir return closest_cell, closest_dist
def getclosestcells(lat, lon, celldir): if celldir in dircache: dirs = dircache[celldir] else: if not os.path.exists(celldir): print "ERR: celldir does not exist: {0}".format(celldir) return [] dirs = dircache[celldir] = getdirs(celldir) closest_cells = [] for dir in dirs: lat2, lon2 = dir.split(',') lat2 = float(lat2) lon2 = float(lon2) dist = info.distance(lat, lon, lat2, lon2) closest_cells.append((dir, dist)) closest_cells.sort(key=lambda x: x[1]) return closest_cells
def norm_compatible(pt, viewpt, verbose=False): # no bearing: corner, middle of street, etc if pt.bearing is None: return True # really close up! if distance(pt.lat, pt.lon, viewpt.lat, viewpt.lon) < 20: return True yaw = getbearing(pt.lat, pt.lon, viewpt.lat, viewpt.lon) diff = anglediff(pt.bearing * pi / 180, yaw * pi / 180) * 180 / math.pi if verbose: print "Point", pt print "pt bearing", pt.bearing print "view bearing", yaw print "diff", diff print return diff < 85
def filter_locally_significant(self, fgen, d0, m0, q, rev=False): T = 70000 # pts ABOVE threshold allowed R = 25.0 # max visibility distance NN = 10 # neighbors to consider flann = pyflann.FLANN() INFO("building flann index") q.flann_setup_index(flann, d0, m0, None) INFO("building 3d map") map3d = self.load_3dmap_for_cell(q.cellpath, d0, m0, q.infodir) INFO("begin filtering features") params = q.params.copy() params['num_neighbors'] = NN for offset, fchunk in fgen: fchunk_filtered = [] arr = np.ndarray(len(fchunk), self.dtype) arr[:] = fchunk results, dists = flann.nn_index(arr['vec'], **params) # for each feature for _, (index_arr, dist_arr) in enumerate(zip(results, dists)): refpt = map3d[offset + _] # for each match of feature has_r = False ok = False for i, d in zip(index_arr, dist_arr): pt = map3d[i] r = distance(pt['lat'], pt['lon'], refpt['lat'], refpt['lon']) if r > R: has_r = True if (not rev and d > T) or (rev and d < T): ok = True break if ok or not has_r: fchunk_filtered.append(fchunk[_]) print 'filter chunk %d/%d' % (len(fchunk_filtered), len(fchunk)) yield fchunk_filtered
def distance_f(oloc): return info.distance(source.lat, source.lon, oloc['lat'], oloc['lon'])
def similar(view): return distance(view.lat, view.lon, qlat, qlon) < thresh
def xydistance(self, d2): x1, y1, z1 = self.lat, self.lon, self.alt x2, y2, z2 = d2['lat'], d2['lon'], d2['alt'] xydist = info.distance(x1, y1, x2, y2) return xydist
def dist(p): return info.distance(p[0].lat, p[0].lon, self.lat, self.lon)
def query2(querydir, querysurf, dbdir, mainOutputDir, nClosestCells, copytopmatch, params, copy_top_n_percell=0): lat, lon = info.getQuerySURFCoord(querysurf) closest_cells = util.getclosestcells(lat, lon, dbdir) assert dict(closest_cells)['37.8732916331,-122.268346029'] < 236 or dict( closest_cells)['37.8714489427,-122.272389514'] < 236 or dict( closest_cells)['37.8696062215,-122.273737308'] < 236 built = [ '37.8732916331,-122.268346029', '37.8714489427,-122.272389514', '37.8696062215,-122.273737308', ] closest_cells = filter(lambda c: c[0] in built, closest_cells) outputFilePaths = [] cells_in_range = [(cell, dist) for cell, dist in closest_cells[0:nClosestCells] if dist < cellradius + ambiguity + matchdistance] latquery, lonquery = info.getQuerySURFCoord(querysurf) if verbosity > 0: print "checking query: {0} \t against {1} \t cells".format( querysurf, len(cells_in_range)) for cell, dist in cells_in_range: latcell, loncell = cell.split(',') latcell = float(latcell) loncell = float(loncell) actualdist = info.distance(latquery, lonquery, latcell, loncell) if verbosity > 1: print "querying cell: {0}, distance: {1} with:{2}".format( cell, actualdist, querysurf) outputFilePath = os.path.join( mainOutputDir, querysurf + ',' + cell + ',' + str(actualdist) + ".res") outputFilePaths.append(outputFilePath) # start query query.run_parallel(dbdir, [c for c, d in cells_in_range], querydir, querysurf, outputFilePaths, params) # end query for cell, dist in cells_in_range: latcell, loncell = cell.split(',') latcell = float(latcell) loncell = float(loncell) actualdist = info.distance(latquery, lonquery, latcell, loncell) outputFilePath = os.path.join( mainOutputDir, querysurf + ',' + cell + ',' + str(actualdist) + ".res") if copy_top_n_percell > 0: outputDir = os.path.join( mainOutputDir, querysurf + ',' + cell + ',' + str(actualdist)) copy_topn_results(os.path.join(dbdir, cell), outputDir, outputFilePath, 4) # combined = combine_until_dup(outputFilePaths, 1000) combined = combine_topn_votes(outputFilePaths, float('inf')) # combined = filter_in_range(combined, querysurf) # write_scores(querysurf, combined, "/media/data/combined") [g, y, r, b, o] = check_topn_img(querysurf, combined, topnresults) if copytopmatch: match = g or y or r or b or o copy_top_match(querydir, querysurf.split('surf.npy')[0], combined, match) return [g, y, r, b, o]
from android import AndroidReader import numpy as np from info import distance f = open('/media/DATAPART2/query5horizontal/gtLatLonNormYaw.txt') m = {} for line in f: data = line.split() name = data[0] lat, lon = float(data[1]), float(data[2]) m[name] = (lat, lon) dss = [] for a in AndroidReader('/media/DATAPART2/query5horizontal'): if a.name in m: d = m[a.name] ds = distance(a.lat, a.lon, d[0], d[1]) ds = float(ds) dss.append(ds) dss.append(-ds) print ds else: print 'skipped', a.name, a.lat, a.lon print 'mean', np.mean(dss) print 'var', np.var(dss)
def match(C, Q): if C.shuffle_cells: C._dbdir = None if C.override_cells: INFO('override cells') cells_in_range = [(c,0) for c in C.override_cells] else: # compute closest cells closest_cells = util.getclosestcells(Q.query_lat, Q.query_lon, C.dbdir) if C.restrict_cells: closest_cells = filter(lambda c: c[0] in C.restrict_cells, closest_cells) cells_in_range = [(cell, dist) for cell, dist in closest_cells[0:C.ncells] if dist < C.cellradius + C.ambiguity + C.matchdistance] INFO('Using %d cells' % len(cells_in_range)) if C.shuffle_cells: import reader sr = reader.get_reader('sift') supercell = sr.get_supercelldir( C.dbdir, [c for (c,d) in cells_in_range], C.overlap_method) C._dbdir = supercell if not cells_in_range: raise LocationOutOfRangeError # cache for fuzz runs if C.cacheEnable: key = derive_key(C, cells_in_range, Q.siftname) if key in cache: print 'cache hit' return cache[key] else: print 'cache miss' # compute output file paths for the cells cellpath = [c for c,d in cells_in_range] listofimages = [] if C.one_big_cell: INFO('Using 1 big cell (%d union)' % len(cells_in_range)) outputFilePaths = [os.path.join(C.matchdir, Q.siftname + ',' + getcellid(cellpath) + ".res")] #listofimages = lexiconrank.addImagetoList(listofimages, C.dbdir + cellpath) cellpath = [cellpath] else: outputFilePaths = [] for cell, dist in cells_in_range: if ',' in cell: latcell, loncell = cell.split(',') latcell = float(latcell) loncell = float(loncell) else: latcell, loncell = 0,0 actualdist = info.distance(Q.query_lat, Q.query_lon, latcell, loncell) outputFilePath = os.path.join(C.matchdir, Q.siftname + ',' + cell + ',' + str(actualdist) + ".res") outputFilePaths.append(outputFilePath) #listofimages = lexiconrank.addImagetoList(listofimages, C.dbdir + cell) # start query query.run_parallel(C, Q, cellpath, outputFilePaths, estimate_threads_avail()) #d, lexiconmatchedimg = lexiconrank.returnTopMatch_random(C.dbdump, listofimages, Q.jpgpath) # combine results if C.spatial_comb: comb_matches = corr.combine_spatial(outputFilePaths) else: print outputFilePaths comb_matches = corr.combine_matches(outputFilePaths) #geometric consistency reranking if C.disable_filter_step: imm = condense2(sorted(comb_matches.iteritems(), key=lambda x: len(x[1]), reverse=True)) rsc_ok = True else: imm, rsc_ok = rerank_ransac(comb_matches, C, Q) if C.weight_by_coverage: #print 1 ranked = weight_by_coverage(C, Q, imm) elif C.weight_by_distance: #print 2 ranked = weight_by_distance(C, Q, imm) else: #print 3 ranked = distance_sort(C, Q, imm) # top 1 stats = check_topn_img(C, Q, ranked, 1) # return statistics and top result matchedimg = ranked[0][0] matches = comb_matches[matchedimg + 'sift.txt'] if C.cacheEnable: cache[key] = (stats, matchedimg, matches, ranked) if C.match_callback: C.match_callback(C, Q, stats, matchedimg, ranked, cells_in_range, rsc_ok) # compute homography and draw images maybe if MultiprocessExecution.pool: MultiprocessExecution.pool.apply_async(compute_hom, [C.pickleable(), Q, ranked, comb_matches]) else: compute_hom(C, Q, ranked, comb_matches) ### Query Pose Estimation ### match = any(check_img(C, Q, ranked[0])) if (C.solve_pose and match and Q.name not in C.pose_remove) or C.pose_param['solve_bad']: #computePose.draw_dbimage(C, Q, matchedimg, match) if MultiprocessExecution.pool: MultiprocessExecution.pool.apply_async(computePose.estimate_pose, [C.pickleable(), Q, matchedimg, match]) else: computePose.estimate_pose(C, Q, matchedimg, match) # done return stats, matchedimg, matches, ranked
def extract_key(match): line = match[0] lat, lon = getlatlonfromdbimagename(C, line) return (match[1], -info.distance(lat, lon, Q.query_lat, Q.query_lon))
def distance3d6(x1, y1, z1, x2, y2, z2): xydist = distance(x1, y1, x2, y2) vert = abs(z1 - z2) return sqrt(xydist**2 + vert**2)
def contribution(target, contributer): lat, lon = getlatlonfromdbimagename(C, target[0]) lat2, lon2 = getlatlonfromdbimagename(C, contributer[0]) dist = info.distance(lat, lon, lat2, lon2) return contrib_function(contributer) * weighting_function(dist)