chromium / catapult / 9cf09f1e1b01f81e70289b56c66419c9ef7637d8 / . / telemetry / telemetry / internal / image_processing / cv_util.py

# 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] |