Advertisement
Guest User

Untitled

a guest
Dec 18th, 2017
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.45 KB | None | 0 0
  1. import psycopg2
  2. import bb_utils.ids
  3. import math
  4. import numba
  5.  
  6. def get_neighbour_frames(frame_id, n_frames=None, seconds=None):
  7.     seconds = seconds or (n_frames / 3 if n_frames else 5.0)
  8.    
  9.     with psycopg2.connect("dbname='beesbook' user='reader' host='localhost' password='reader'",
  10.                           application_name="get_neighbour_frames") as db:
  11.         cursor = db.cursor()
  12.         cursor.execute("SELECT index, fc_id, timestamp FROM plotter_frame WHERE frame_id = %s LIMIT 1", (frame_id,))
  13.         f_index, fc_id, timestamp = cursor.fetchone()
  14.        
  15.         #print(f"Frame index: {f_index}, timestamp: {timestamp}, container ID: {fc_id}")
  16.        
  17.         cursor.execute("SELECT timestamp, frame_id, fc_id FROM plotter_frame WHERE timestamp >= %s AND timestamp <= %s", (timestamp - seconds, timestamp + seconds))
  18.         results = list(cursor)
  19.         containers = {fc_id for (_, _, fc_id) in results}
  20.        
  21.        
  22.         cursor.execute("PREPARE fetch_container AS "
  23.                    "SELECT CAST(SUBSTR(video_name, 5, 1) AS INT) FROM plotter_framecontainer "
  24.                    "WHERE id = $1")
  25.         cursor.execute("EXECUTE fetch_container (%s)", (fc_id,))
  26.         target_cam = cursor.fetchone()[0]
  27.         #print (f"Target cam: {target_cam}")
  28.         matching_cam = set()
  29.         for container in containers:
  30.             cursor.execute("EXECUTE fetch_container (%s)", (container,))
  31.             cam = cursor.fetchone()[0]
  32.             #print (f"\tChecking cam: {cam}...")
  33.             if cam == target_cam:
  34.                 matching_cam.add(container)
  35.         results = [(timestamp, frame_id, target_cam) for (timestamp, frame_id, fc_id) in results if fc_id in matching_cam]
  36.         return sorted(results)
  37.    
  38. def get_neighbour_detections(frame_id, bee_id, verbose=False, **kwargs):
  39.     if type(bee_id) != int:
  40.         bee_id = bee_id.as_ferwar()
  41.     neighbour_frames = get_neighbour_frames(frame_id, **kwargs)
  42.     frame_ids = tuple([f[1] for f in neighbour_frames])
  43.    
  44.     with psycopg2.connect("dbname='beesbook' user='reader' host='localhost' password='reader'",
  45.                           application_name="get_neighbour_detections") as db:
  46.         cursor = db.cursor()
  47.         cursor.execute("SELECT timestamp, frame_id, x_pos, y_pos, orientation, track_id FROM bb_detections WHERE frame_id IN %s AND bee_id = %s ORDER BY timestamp ASC",
  48.                        (frame_ids, bee_id))
  49.         detections = cursor.fetchall()
  50.    
  51.     results = []
  52.     for n_idx, (timestamp, frame_id, _) in enumerate(neighbour_frames):
  53.         if len(detections) == 0:
  54.             results.append(None)
  55.             continue
  56.         if frame_id == detections[0][1]:
  57.             if len(detections) == 1 or frame_id != detections[1][1]:
  58.                 results.append(detections[0])
  59.                 detections.pop(0)
  60.             else:
  61.                 candidates = [d for d in detections if d[1] == frame_id]
  62.                 if verbose:
  63.                     print(f"Warning: more than one candidate! ({len(candidates)})")
  64.                 closest_candidate = None
  65.                 for i, r in reversed(list(enumerate(results))):
  66.                     if r is None:
  67.                         continue
  68.                     closest_candidate = r
  69.                     break
  70.                 candidate = None
  71.                 if closest_candidate is not None:
  72.                     for c in candidates:
  73.                         if c[-1] == closest_candidate[-1]: # track_id
  74.                             candidate = c
  75.                             break
  76.                 if verbose and candidate is not None:
  77.                     print("\t..resolved via track ID.")
  78.                 else:
  79.                     distances = np.array([[x, y] for (_, _, x, y, _, _) in candidates])
  80.                     if closest_candidate:
  81.                         distances -= np.array([closest_candidate[2], closest_candidate[3]])
  82.                         distances = np.linalg.norm(distances, axis=1)
  83.                         min_d = np.argmin(distances)
  84.                         candidate = candidates[min_d]
  85.                         if verbose:
  86.                             print("\t..resolved via distance.")
  87.                    
  88.                 results.append(candidate)#candidates[0])
  89.                 for i in range(len(candidates)):
  90.                     detections.pop(0)
  91.         else:
  92.             results.append(None)
  93.     return results
  94.  
  95. @numba.njit
  96. def short_angle_dist(a0,a1):
  97.     max = math.pi*2
  98.     da = (a1 - a0) % max
  99.     return 2*da % max - da
  100. @numba.njit
  101. def angle_lerp(a0,a1,t):
  102.     return a0 + short_angle_dist(a0,a1)*t
  103.  
  104. def get_trajectory_around(frame_id, bee_id, **kwargs):
  105.     detections = get_neighbour_detections(frame_id, bee_id, **kwargs)
  106.     # (dt, frame_id, x, y, alpha)
  107.     def unpack(d):
  108.         if d is None:
  109.             return [np.nan, np.nan, np.nan]
  110.         (dt, frame_id, x, y, alpha, track_id) = d
  111.         return [x, y, alpha]
  112.     trajectory = np.array([unpack(d) for d in detections], dtype=np.float32)
  113.     return trajectory
  114.        
  115. @numba.njit(numba.float32[:](numba.float32[:, :]))
  116. def interpolate_trajectory(trajectory):
  117.    
  118.     nans = np.isnan(trajectory[:,0])
  119.     not_nans = ~nans
  120.    
  121.     nans_idx = np.where(nans)[0]
  122.     valid_idx = np.where(not_nans)[0]
  123.     if len(valid_idx) < 2:
  124.         return np.zeros(shape=(trajectory.shape[0]), dtype=np.float32)
  125.    
  126.     # Interpolate gaps.
  127.     for i in nans_idx:
  128.         # Find closest two points to use for interpolation.
  129.         begin_t = np.searchsorted(valid_idx, i) - 1
  130.         if begin_t == len(valid_idx) - 1:
  131.             begin_t -= 1 # extrapolate right
  132.         elif begin_t == -1:
  133.             begin_t = 0 # extrapolate left
  134.        
  135.         begin_t_idx = valid_idx[begin_t]
  136.         end_t_idx = valid_idx[begin_t + 1]
  137.        
  138.         last_t = trajectory[begin_t_idx]
  139.         next_t = trajectory[end_t_idx]
  140.         dx = (end_t_idx - begin_t_idx) / 3.0
  141.         m = [(next_t[0] - last_t[0]) / dx,
  142.              (next_t[1] - last_t[1]) / dx,
  143.              short_angle_dist(last_t[0], next_t[0]) / dx]
  144.  
  145.         dt = (i - begin_t_idx) / 3.0
  146.         e = [m[i] * dt + last_t[i] for i in range(3)]
  147.         trajectory[i] = e
  148.        
  149.     return not_nans.astype(np.float32)
  150.  
  151. def get_interpolated_trajectory(frame_id, bee_id, interpolate=True, **kwargs):
  152.     trajectory = get_trajectory_around(frame_id, bee_id, **kwargs)
  153.     if interpolate:
  154.         interpolate_trajectory(trajectory)
  155.     return trajectory
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement