diff options
Diffstat (limited to 'catapult/telemetry/telemetry/internal/image_processing/cv_util.py')
-rw-r--r-- | catapult/telemetry/telemetry/internal/image_processing/cv_util.py | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/catapult/telemetry/telemetry/internal/image_processing/cv_util.py b/catapult/telemetry/telemetry/internal/image_processing/cv_util.py new file mode 100644 index 00000000..356c0d62 --- /dev/null +++ b/catapult/telemetry/telemetry/internal/image_processing/cv_util.py @@ -0,0 +1,90 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""This module provides implementations of common computer Vision operations.""" + +from __future__ import division +from telemetry.internal.util import external_modules + +np = external_modules.ImportRequiredModule('numpy') + + +def AreLinesOrthogonal(line1, line2, tolerance): + """Returns true if lines are within tolerance radians of being orthogonal.""" + # Map each line onto an angle between 0 and 180. + theta1 = np.arctan2(np.float(line1[1] - line1[3]), + np.float(line1[0] - line1[2])) + theta2 = np.arctan2(np.float(line2[1] - line2[3]), + np.float(line2[0] - line2[2])) + angle2 = abs(theta2 - theta1) + if angle2 >= np.pi: + angle2 -= np.pi + # If the difference between the angles is more than pi/2 - tolerance, the + # lines are not orthogonal. + return not abs(angle2 - (np.pi / 2.0)) > tolerance + + +def FindLineIntersection(line1, line2): + """If the line segments intersect, returns True and their intersection. + Otherwise, returns False and the intersection of the line segments if they + were to be extended.""" + # Compute g, and h, the factor by which each line must be extended to + # exactly touch the other line. If both are between 0 and 1, then the lines + # currently intersect. We use h to compute their intersection. + line1p1 = line1[:2] + line1p0 = line1[2:] + line2p1 = line2[:2] + line2p0 = line2[2:] + E = np.subtract(line1p1, line1p0) + F = np.subtract(line2p1, line2p0) + Pe = np.asfarray((-E[1], E[0])) + Pf = np.asfarray((-F[1], F[0])) + h = np.dot(np.subtract(line1p0, line2p0), Pe) + h = np.divide(h, np.dot(F, Pe)) + g = np.dot(np.subtract(line2p0, line1p0), Pf) + g = np.divide(g, np.dot(E, Pf)) + intersection = np.add(line2p0, np.dot(F, h)) + intersect = (h >= -0.000001 and h <= 1.000001 and + g >= -0.000001 and g <= 1.000001) + return intersect, intersection + + +def ExtendLines(lines, length): + """Extends lines in an array to a given length, maintaining the center + point. Does not necessarily maintain point order.""" + half_length = length / 2.0 + angles = np.arctan2(lines[:, 1] - lines[:, 3], lines[:, 0] - lines[:, 2]) + xoffsets = half_length * np.cos(angles) + yoffsets = half_length * np.sin(angles) + centerx = (lines[:, 0] + lines[:, 2]) / 2.0 + centery = (lines[:, 1] + lines[:, 3]) / 2.0 + lines[:, 0] = centerx - xoffsets + lines[:, 2] = centerx + xoffsets + lines[:, 1] = centery - yoffsets + lines[:, 3] = centery + yoffsets + return lines + + +def IsPointApproxOnLine(point, line, tolerance=1): + """Approximates distance between point and line for small distances using + the determinant and checks whether it's within the tolerance. Tolerance is + an approximate distance in pixels, precision decreases with distance.""" + xd = line[0] - line[2] + yd = line[1] - line[3] + det = ((xd) * (point[1] - line[3])) - ((yd) * (point[0] - line[2])) + tolerance = float(tolerance) * (abs(xd) + abs(yd)) + return abs(det) * 2.0 <= tolerance + + +def SqDistances(points1, points2): + """Computes the square of the distance between two sets of points, or a + set of points and a point.""" + d = np.square(points1 - points2) + return d[:, 0] + d[:, 1] + + +def SqDistance(point1, point2): + """Computes the square of the distance between two points.""" + d = np.square(point1 - point2) + return d[0] + d[1] |