diff_generation.py
Go to the documentation of this file.
00001 # Software License Agreement (BSD License)
00002 #
00003 # Copyright (c) 2008, Willow Garage, Inc.
00004 # All rights reserved.
00005 #
00006 # Redistribution and use in source and binary forms, with or without
00007 # modification, are permitted provided that the following conditions
00008 # are met:
00009 #
00010 #  * Redistributions of source code must retain the above copyright
00011 #    notice, this list of conditions and the following disclaimer.
00012 #  * Redistributions in binary form must reproduce the above
00013 #    copyright notice, this list of conditions and the following
00014 #    disclaimer in the documentation and/or other materials provided
00015 #    with the distribution.
00016 #  * Neither the name of Willow Garage, Inc. nor the names of its
00017 #    contributors may be used to endorse or promote products derived
00018 #    from this software without specific prior written permission.
00019 #
00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 # POSSIBILITY OF SUCH DAMAGE.
00032 #
00033 # Author: Bhaskara Marthi
00034 
00035 # Generation of diffs between two world models
00036 
00037 import mongo_ros as mr
00038 import logging
00039 import semanticmodel.msg as msg
00040 import numpy as np
00041 import semanticmodel.plane_data_association as pd
00042 import semanticmodel.db as sdb
00043 import math
00044 
00045 log = logging.getLogger('world_model.diffs')
00046 TOL = 0.1
00047 
00048 def generate_diffs(run1, run2, db):
00049     """
00050     Generate diffs between run1 and run2, which must have been
00051     produced by the blob storage system.
00052 
00053     @type run1: string
00054     @type run2: string
00055     @param db: the name of the overall database
00056     """
00057     log.debug("Getting diffs between {0} and {1}".format(run1, run2))
00058     matches = []
00059     nonmatches = []
00060     for run in (run1, run2):
00061         other = run1 if run is run2 else run2
00062         log.debug("Processing {0}, and looking for matches in {1}".
00063                   format(run, other))
00064         c1 = mr.MessageCollection(db, sdb.collection_name(run, 'blobs'),
00065                                   msg.BlobMessage)
00066         c2 = mr.MessageCollection(db, sdb.collection_name(other, 'blobs'),
00067                                   msg.BlobMessage)
00068         for cluster, meta in c1.query({}):
00069             log.debug("Considering cluster {0[id]} at {0[x]}, {0[y]}".
00070                     format(meta))
00071             match = find_matching_cluster(cluster, meta, c2)
00072             if match and run is run1:
00073                 log.debug("  Found match {0[id]} at {0[x]}, {0[y]}".
00074                         format(match[1]))
00075                 matches.append((meta['id'], match[1]['id']))
00076             else:
00077                 nearby = next(nearby_clusters(meta, c2), None)
00078                 if nearby and run is run1:
00079                     nonmatches.append((meta['id'], nearby[1]['id']))
00080                 
00081     return {'matches': matches, 'nonmatches': nonmatches}
00082 
00083 def nearby_clusters(m, c2):
00084     x = m['x']
00085     y = m['y']
00086     return c2.query({'x': {'$gt': x-1.0, '$lt': x+1.0}, 
00087         'y': {'$gt': y-1.0, '$lt': y+1.0}})
00088 
00089 
00090 def find_matching_cluster(cluster, meta, c2):
00091     possible_matches = nearby_clusters(meta, c2) 
00092     hull = get_hull_polygon(cluster)
00093 
00094     # Check if hulls overlap
00095     for m in possible_matches:
00096         if pd.polygons_intersect(hull, get_hull_polygon(m[0])):
00097             return m
00098 
00099     return None
00100 
00101 
00102 def get_hull_polygon(cluster):
00103     return np.array([(p.x,p.y) for p in cluster.hull])
00104 
00105 
00106 def dist(p, q):
00107     return math.sqrt(pow(q[0]-p[0],2) + pow(q[1]-p[1],2))
00108 
00109 
00110 def nearest_nonmatch(cluster, img_coll, max_distance=2.0, max_angle=1.0):
00111     """
00112     A crude and inefficient way to find the nearest nonmatching image.  
00113     """
00114     loc = (cluster['x'], cluster['y'])
00115     for img in img_coll.query({}, True):
00116         vp = (img['x'], img['y'])
00117         if dist(vp, loc) < max_distance:
00118             disp = (loc[0]-vp[0], loc[1]-vp[1])
00119             angle = math.atan2(disp[1], disp[0])
00120             if (abs(angle-img['theta'])<max_angle):
00121                 return img


semanticmodel
Author(s): Julian ("Mac") Mason
autogenerated on Thu Dec 12 2013 12:39:10