#!/usr/bin/python3

import cv2
import glob
import math
import numpy as np
import sys
"""
Usage:
    undistort.py [display]

Finds files in /tmp/*.yuyv to compute distortion constants for.
"""


def undist(orig, mtx, dist, newcameramtx, its=1):
    """
    This function runs a manual undistort over the entire image to compare to the
    golden as proof that the algorithm works and the generated constants are correct.
    """
    output = np.full(orig.shape, 255, dtype=np.uint8)
    for i in range(480):
        for j in range(640):
            x0 = (i - mtx[1, 2]) / mtx[1, 1]
            y0 = (j - mtx[0, 2]) / mtx[0, 0]
            x = x0
            y = y0
            for k in range(its):
                r2 = x * x + y * y
                coeff = (1 + dist[0, 0] * r2 + dist[0, 1] * math.pow(r2, 2) +
                         dist[0, 4] * math.pow(r2, 3))
                x = x0 / coeff
                y = y0 / coeff
            ip = x * newcameramtx[1, 1] + newcameramtx[1, 2]
            jp = y * newcameramtx[0, 0] + newcameramtx[0, 2]
            if ip < 0 or jp < 0 or ip >= 480 or jp >= 640:
                continue
            output[int(ip), int(jp)] = orig[i, j]
    return output


def main(argv):
    # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
    objp = np.zeros((6 * 9, 3), np.float32)
    objp[:, :2] = np.mgrid[0:9, 0:6].T.reshape(-1, 2)

    # Arrays to store object points and image points from all the images.
    objpoints = []  # 3d point in real world space
    imgpoints = []  # 2d points in image plane.

    images = glob.glob('/tmp/*.yuyv')

    cols = 640
    rows = 480

    # Iterate through all the available images
    for fname in images:
        fd = open(fname, 'rb')
        f = np.fromfile(fd, np.uint8, cols * rows * 2)
        # Convert yuyv color space to single channel grey.
        grey = f[::2]
        grey = np.reshape(grey, (rows, cols))

        ret, corners = cv2.findChessboardCorners(grey, (9, 6), None)
        if ret:
            objpoints.append(objp)
            imgpoints.append(corners)
            # Draw the chessboard with corners marked.
            if len(argv) > 1 and argv[1] == 'display':
                rgb = cv2.cvtColor(grey, cv2.COLOR_GRAY2RGB)
                cv2.drawChessboardCorners(rgb, (9, 6), corners, ret)
                cv2.imshow('', rgb)
                cv2.waitKey(0)
                cv2.destroyAllWindows()
        fd.close()

    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(
        objpoints, imgpoints, grey.shape[::-1], None, None)
    newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (rows, cols),
                                                      1, (rows, cols))

    dist[0, 2] = 0
    dist[0, 3] = 0
    print("Formatted for Game Config:")
    print("""distortion {
  f_x: %f
  c_x: %f
  f_y: %f
  c_y :%f
  f_x_prime: %f
  c_x_prime: %f
  f_y_prime: %f
  c_y_prime: %f
  k_1: %f
  k_2: %f
  k_3: %f
  distortion_iterations: 7
}""" % (
        # f_x c_x
        mtx[0][0],
        mtx[0][2],
        # f_y c_y
        mtx[1][1],
        mtx[1][2],
        # f_x c_x prime
        newcameramtx[0][0],
        newcameramtx[0][2],
        # f_y c_y prime
        newcameramtx[1][1],
        newcameramtx[1][2],
        # k_1, k_2, k_3
        dist[0, 0],
        dist[0, 1],
        dist[0, 4]))

    # Draw the original image, open-cv undistort, and our undistort in separate
    # windows for each available image.
    if len(argv) > 1 and argv[1] == 'display':
        for fname in images:
            fd = open(fname, 'rb')
            f = np.fromfile(fd, np.uint8, cols * rows * 2)
            grey_t = f[::2]
            grey_t = np.reshape(grey_t, (rows, cols))
            dst_expected = cv2.undistort(grey_t, mtx, dist, None, newcameramtx)
            dst_actual = undist(grey_t, mtx, dist, newcameramtx, 5)
            cv2.imshow('orig', grey_t)
            cv2.imshow('opencv undistort', dst_expected)
            cv2.imshow('our undistort', dst_actual)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
            fd.close()


if __name__ == '__main__':
    main(sys.argv)
