# Buggy code
def _find_homographies(points_A, points_B):
    points_A = points_A.reshape((-1, 1, 2))
    points_B = points_B.reshape((-1, 1, 2))

    B_to_A, mask = cv2.findHomography(points_A, points_B)
    # NOTE: cv2.findHomography(A, B) will not produce the inverse of
    # cv2.findHomography(B, A)! The errors can actually be quite large, resulting in
    # on-screen discrepancies of up to 50 pixels. We try to find the inverse
    # analytically instead with fallbacks.

    try:
        A_to_B = np.linalg.inv(B_to_A)
        return A_to_B, B_to_A
    except np.linalg.LinAlgError as e:
        logger.debug(
            "Failed to calculate inverse homography with np.inv()! "
            "Trying with np.pinv() instead."
        )

    try:
        A_to_B = np.linalg.pinv(B_to_A)
        return A_to_B, B_to_A
    except np.linalg.LinAlgError as e:
        logger.warning(
            "Failed to calculate inverse homography with np.pinv()! "
            "Falling back to inaccurate manual computation!"
        )

    A_to_B, mask = cv2.findHomography(points_B, points_A)
    return A_to_B, B_to_A


# Traceback (TypeError)
2020-05-13 15:27:43,610 - player - [DEBUG] root: Recalculate Surface Cache!
2020-05-13 15:27:43,656 - Background Data Processor - [DEBUG] background_helper: Entering _wrapper
2020-05-13 15:27:43,661 - Background Data Processor - [DEBUG] surface_tracker.surface: Failed to calculate inverse homography with np.inv()! Trying with np.pinv() instead.
2020-05-13 15:27:43,663 - Background Data Processor - [INFO] background_helper: AttributeError: 'NoneType' object has no attribute 'conjugate'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "shared_modules\background_helper.py", line 73, in _wrapper
File "shared_modules\surface_tracker\background_tasks.py", line 189, in data_processing_generator
File "shared_modules\surface_tracker\background_tasks.py", line 176, in handle_sample
File "shared_modules\surface_tracker\offline_utils.py", line 35, in __call__
File "shared_modules\surface_tracker\surface.py", line 323, in locate
File "shared_modules\surface_tracker\surface.py", line 363, in _find_homographies
File "<__array_function__ internals>", line 6, in pinv
File "site-packages\numpy\linalg\linalg.py", line 1969, in pinv
TypeError: loop of ufunc does not support argument 0 of type NoneType which has no callable conjugate method

# Fixed code
def _find_homographies(points_A, points_B):
    points_A = points_A.reshape((-1, 1, 2))
    points_B = points_B.reshape((-1, 1, 2))

    B_to_A, mask = cv2.findHomography(points_A, points_B)
    # NOTE: cv2.findHomography(A, B) will not produce the inverse of
    # cv2.findHomography(B, A)! The errors can actually be quite large, resulting in
    # on-screen discrepancies of up to 50 pixels. We try to find the inverse
    # analytically instead with fallbacks.

    try:
        A_to_B = np.linalg.inv(B_to_A)
        return A_to_B, B_to_A
    except np.linalg.LinAlgError as e:
        pass
    except Exception as e:
        import traceback

        exception_msg = traceback.format_exc()
        logger.error(exception_msg)

    logger.debug(
        "Failed to calculate inverse homography with np.inv()! "
        "Trying with np.pinv() instead."
    )

    try:
        A_to_B = np.linalg.pinv(B_to_A)
        return A_to_B, B_to_A
    except np.linalg.LinAlgError as e:
        pass
    except Exception as e:
        import traceback

        exception_msg = traceback.format_exc()
        logger.error(exception_msg)

    logger.warning(
        "Failed to calculate inverse homography with np.pinv()! "
        "Falling back to inaccurate manual computation!"
    )

    A_to_B, mask = cv2.findHomography(points_B, points_A)
    return A_to_B, B_to_A