'Opencv 3D recostracion with image at 90°

I want to do the same think that Matt Parker did in is video "I wired my tree with 500 LED lights and calculated their 3D coordinates" I tried to use opencv, but I'm unable to solve this problem.

The idea is to have one camera in a dark room, taking picture of every single LED and then rotate the tree 90° and repeat the same thing at the end I should be able to use some false coordinate manually rotating / telling the software that the camera moved even if it stayed the same.

The main problem is that I can't understand what parameters I should put in the projection matrix. If you have some good material to read that is not to mathematical intensive (I'm only in my second year of computer science) please send me everything.

import cv2 as cv
import numpy as np

camera_matrix = np.array([[120, 0., 1920 / 2], [0., 120, 1080 / 2], [0., 0., 1.]], dtype=np.float32)

def point_3d(fp1, fp2, tpos1, tpos2):
    pos1 = [[1, 0, 0, tpos1[0]],
            [0, 1, 0, tpos1[1]],
            [0, 0, 1, tpos1[2]]]
    pos1 = np.asarray(pos1, np.double)

    pos2 = [[0, 1, 0, tpos2[0]],
            [-1, 0, 0, tpos2[1]],
            [0, 0, 1, tpos2[2]]]
    pos2 = np.asarray(pos2, np.double)

    pos1 = np.matmul(camera_matrix, pos1)
    pos2 = np.matmul(camera_matrix, pos2)

    # a, b, c, d, e, f, g = cv.decomposeProjectionMatrix(pos1)
    #
    # print(a, b, c/c[3], sep='\n\n')
    #
    # a, b, c, d, e, f, g = cv.decomposeProjectionMatrix(pos2)
    #
    # print(a, b, c / c[3], sep='\n\n')

    fp1 = np.asarray(fp1, np.double)

    fp2 = np.asarray(fp2, np.double)

    loc = cv.triangulatePoints(pos1, pos2, fp1.T, fp2.T)

    X = loc / loc[3]
    X1 = pos1[:3] @ X
    X2 = pos2[:3] @ X

    print(X[:4], X1, X2, sep='\n\n')


def non_distort(x, y):
    test = np.asarray([[[x + 1920 / 2, y + 1080 / 2]]], dtype=np.float32)
    xy_undistorted = cv.undistortPoints(test, camera_matrix, 0)
    # print(xy_undistorted[0][0][0], xy_undistorted[0][0][1])
    return [xy_undistorted[0][0][0], xy_undistorted[0][0][1]]


if __name__ == '__main__':
    for i in range(0, 100, 10):
        for j in range(0, 100, 10):
            pass
    point_3d(non_distort(45, 0),
             non_distort(-45, 0),
             [1, 0, 0],
             [1, 0, 0])


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source