# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Import guard for OpenCV.
try:
    import cv
    import cv2
except ImportError:
    pass

import numpy as np

from camera_utils import Pad
from camera_utils import Unpad

_GRID_REGISTRATION_MAX_ITER_NUM = 5
_GRID_REGISTRATION_MIN_MATCH_RATIO = 0.20


def _ComputePairL2Sq(xy1, xy2):
    '''Compute a pair-wise L2 square distance matrix.'''
    d0 = np.subtract.outer(xy1[:, 0], xy2[:, 0])
    d1 = np.subtract.outer(xy1[:, 1], xy2[:, 1])
    return d0 ** 2 + d1 ** 2


def _MatchPoints(src, dst, match_tol):
    '''Match two points sets based on the Euclidean distance.

    Args:
        src: Point set 1.
        dst: Point set 2.
        match_tol: Maximum acceptable distance between two points.

    Returns:
        1: The indexs that each point in src matches to in dst. None if a point
           can't find any match.
    '''
    n_match = src.shape[0]

    # We will work in the squared distance space.
    match_tol **= 2

    # Compute cost matrix.
    cost_mat = _ComputePairL2Sq(src, dst)

    # Assign points to nearest neighbors and return.
    m = np.empty(n_match, dtype=np.uint32)
    m.fill(n_match)
    taken = np.zeros(n_match, dtype=np.uint8)
    for i, row in enumerate(cost_mat):
        current = match_tol
        for j, value in enumerate(row):
            if not taken[j] and value <= current:
                m[i] = j
                current = value
        if m[i] == n_match:
            return None
        taken[j] = True
    return m


def Register(tar_four_corners, tar_corners, ref_four_corners, ref_corners,
             match_tol):
    '''Register two rectangular grid point sets.

    The function try to match two point sets with a prespective transformation.
    The four corners of both point grids must be supplied. The algorithm will
    iteratively re-match two point sets and estimate the corresponding
    homography matrix. It returns failure if it can't succeed in a few
    iterations or the iteration diverged.

    Args:
        tar_four_corners: Four corners of the target point grid.
        tar_corners: The target point grid.
        ref_four_corners: Four corners of the reference point grid.
        ref_corners: The reference point grid.
        match_tol: Maximum acceptable distance between two points.

    Returns:
        1: Succeed or not.
        2: The estimated homography matrix.
        3: The indexs that each point in the target image matches to in
           reference one. None if a point can't find any match.
    '''
    # Stupid dimension extension to fit the opencv interface.
    padded_tar_corners = Pad(tar_corners)

    min_match_num = int(round(mapped.shape[0] *
                              _GRID_REGISTRATION_MIN_MATCH_RATIO))
    min_match_num = max(4, min_match_num)

    # Compute an initial homography.
    homography, _ = cv2.findHomography(tar_four_corners, ref_four_corners)

    # Iteratively register the point grid.
    for i in range(0, _GRID_REGISTRATION_MAX_ITER_NUM):
        # Map and match points.
        mapped = cv2.perspectiveTransform(padded_tar_corners, homography)
        mapped = Unpad(mapped)
        matching = _MatchPoints(mapped, ref_corners, match_tol)

        # Check if all points can find a close enough match.
        if not matching:
            return False, None, None

        # Compute a new homography.
        homography, mask = cv2.findHomography(mapped,
                                              ref_corners[matching],
                                              method=cv.CV_LMEDS)

        # Check if all points fit the found homography or return failure
        # in case the iteration diverged (too few point fitted).
        if not homography or mask.sum() < min_match_num:
            return False, None, None
        if mask.all():
            return True, homography, matching

    return False, None, None
