Beispiel #1
0
 def _HasMovedFast(self, corners, prev_corners):
     min_dist = np.zeros(4, np.float32)
     for i in xrange(4):
         dist = np.min(cv_util.SqDistances(corners, prev_corners[i]))
         min_dist[i] = dist
     # 3 corners can move up to one pixel before we consider the screen to have
     # moved. TODO(mthiesse): Should this be relaxed? Resolution dependent?
     if np.sum(min_dist) < 3:
         return False
     return True
Beispiel #2
0
    def _FindCorners(self, intersections, grey_frame):
        """Finds the screen corners in the image.

    Given the set of intersections in the image, finds the intersections most
    likely to be corners.

    Args:
      intersections: The array of intersections in the image.
      grey_frame: The greyscale frame we're processing.

    Returns:
      An array of length 4 containing the positions of the corners, or nan for
      each index where a corner could not be found, and a count of the number
      of missing corners.
      The corners are ordered as follows:
        1 | 0
        -----
        2 | 3
      Ex. 3 corners are found from a square of width 2 centered at the origin,
      the output would look like:
          '[[1, 1], [np.nan, np.nan], [-1, -1], [1, -1]], 1'"""
        filtered = []
        corners = np.empty((0, 2), np.float32)
        for corner_pos, score, point, line1, line2 in \
            self._LooksLikeCorner(intersections, grey_frame):
            if self.DEBUG:
                center = (int(point[0] + 0.5), int(point[1] + 0.5))
                cv2.circle(self._frame_debug, center, 5, (0, 255, 0), 1)
            point.resize(1, 2)
            corners = np.append(corners, point, axis=0)
            point.resize(2, )
            corner_data = self.CornerData(corner_pos, point, score, line1,
                                          line2)
            filtered.append(corner_data)

        # De-duplicate corners because we may have found many false positives, or
        # near-misses.
        self._DeDupCorners(filtered, corners)

        # Strip everything but the corner location.
        filtered_corners = np.array(
            [corner_data.corner_location for corner_data in filtered])
        corner_indices = [corner_data.corner_index for corner_data in filtered]

        # If we have found a corner to replace a lost corner, we want to check
        # that the corner is not erroneous by ensuring it makes a rectangle with
        # the 3 known good corners.
        if len(filtered) == 4:
            for i in xrange(4):
                point_info = (filtered[i].corner_location, filtered[i].line1,
                              filtered[i].line2)
                if (self._lost_corners[i] and not self._PointConnectsToCorners(
                        filtered_corners, point_info)):
                    filtered_corners = np.delete(filtered_corners, i, 0)
                    corner_indices = np.delete(corner_indices, i, 0)
                    break

        # Ensure corners are sorted properly, inserting nans for missing corners.
        sorted_corners = np.empty((4, 2), np.float32)
        sorted_corners[:] = np.nan
        for i in xrange(len(filtered_corners)):
            sorted_corners[corner_indices[i]] = filtered_corners[i]

        # From this point on, our corners arrays are guaranteed to have 4
        # elements, though some may be nan.

        # Filter corners that have moved too far from the previous corner if we
        # are not resetting known corner information.
        reset_corners = (
            (self._lost_corner_frames > self.RESET_AFTER_N_BAD_FRAMES)
            and len(filtered_corners) == 4)
        if self._prev_corners is not None and not reset_corners:
            sqdists = cv_util.SqDistances(self._prev_corners, sorted_corners)
            for i in xrange(4):
                if np.isnan(sorted_corners[i][0]):
                    continue
                if sqdists[i] > self.MAX_INTERFRAME_MOTION:
                    sorted_corners[i] = np.nan

        real_corners = self._FindExactCorners(sorted_corners)
        missing_corners = np.count_nonzero(np.isnan(real_corners)) / 2
        return real_corners, missing_corners