def test_refineTriangulate(self):
     #First, create the true point
     X_true = np.random.rand(3) * 400 - 200.
     #Find the location of the object in 4 cameras
     N_cams = 4
     w_cams = np.zeros((N_cams, 3))
     Rs = []
     Ks = []
     Ps = []
     x_true = []
     for i in range(N_cams):
         w_cams[i] = np.random.rand(3) * 400 - 200
         Rs.append(van.rotateCameraAtPoint(X_true, w_cams[i], True))
         im_size = np.random.rand(2) * 2000. + 400.  #between 400 and 2400
         focal_length = np.random.rand(1).item() * 2000. + 500.
         Ks.append(self.K)
         '''np.array([[focal_length, 0., im_size[0]/2.0],
                       [0., focal_length, im_size[1]/2.0],
                       [0., 0., 1.]]))'''
         Ps.append(van.createP(Ks[i], Rs[i], w_cams[i]))
         x_true.append(van.projectPoints(Ps[i], X_true))
     PX_list = list(zip(Ps, x_true))
     X_ret = van.refineTriangulate(PX_list)
     #I choose the atol to correspond with the convergence criteria
     # in refineTriangulate
     self.assertTrue(np.allclose(X_ret, X_true, atol=1E-5))
    def test_projectPoints(self):
        #Really, this tests createP as well...
        X_test = np.array([[0., 1., -1., 0., 0.], [0., 0., 0., 1., -1.],
                           [10., 10., 20., 10., 20.]])
        K_test = np.array([[1000., 0., 500.], [0., 1000., 500.], [0., 0., 1.]])
        R1 = np.eye(3)
        t1 = np.zeros((3, ))
        x1 = van.projectPoints(van.createP(K_test, R1, t1), X_test)
        should_be1 = 500. + np.array([[0., 100., -50., 0., 0.],
                                      [0., 0., 0., 100., -50.]])
        self.assertTrue(np.allclose(should_be1, x1))

        #Shift the camera right 1 meter
        t2 = np.array([1., 0., 0.]).reshape((3, ))
        x2 = van.projectPoints(van.createP(K_test, R1, t2), X_test)
        should_be2 = 500. + np.array([[-100., 0, -100., -100., -50.],
                                      [0., 0., 0., 100., -50.]])
        self.assertTrue(np.allclose(should_be2, x2))

        #Shift the camera down 1 meter
        t3 = np.array([0., 1., 0.]).reshape((3, ))
        x3 = van.projectPoints(van.createP(K_test, R1, t3), X_test)
        should_be3 = 500. + np.array([[0., 100., -50., 0., 0.],
                                      [-100., -100., -50., 0., -100.]])
        self.assertTrue(np.allclose(should_be3, x3))

        #Now to test rotation somehow...
        R2 = van.createRot((1., 2., 3.), True)
        R_X_test = np.dot(R2.T, X_test)
        x4 = van.projectPoints(van.createP(K_test, R2, t1), R_X_test)
        self.assertTrue(np.allclose(should_be1, x4))
Exemplo n.º 3
0
    def test_backupCamera(self):
        #I will create a bunch of points in front of a camera, then move it forward.
        #After that, call backupCamera and make sure it ends up equal to or forward of
        #the original location
        rotation = np.zeros((3))
        rotation[0] = np.random.rand(1) * m.pi * 2 - m.pi
        R = van.createRot(rotation)
        im_size = (self.K[0, 2] * 2., self.K[1, 2] * 2.)
        pts = self.createRandomWorldPoints(self.K,
                                           R,
                                           np.zeros((3)),
                                           10,
                                           dist_range=(10, 50))[0]
        new_loc = np.array([0., 0., 9.])
        bu_loc = van.backupCamera(pts, R, new_loc, self.K, im_size)
        self.assertTrue(bu_loc[0] == 0.)
        self.assertTrue(bu_loc[1] == 0.)
        self.assertTrue(bu_loc[2] >= 0.)
        #Now test the projections...
        P = van.createP(self.K, R, bu_loc)
        im_pts = van.projectPoints(P, pts)
        for i in range(im_pts.shape[1]):
            self.assertTrue(van.inImage(im_pts[:, i], im_size))

        #Now do the same thing, but with a buffer...
        bu_loc = van.backupCamera(pts, R, new_loc, self.K, im_size, 10)
        #Now test the projections...
        P = van.createP(self.K, R, bu_loc)
        im_pts = van.projectPoints(P, pts)
        for i in range(im_pts.shape[1]):
            self.assertTrue(van.inImage(im_pts[:, i], im_size, 10))
    def test_rotateCameraAtPoint(self):
        N = 20  #number of times to test it...

        for i in range(N):
            #create two random points, one for the camera, one for the point
            w_cam = np.random.rand(3) * 200 - 100
            w_pt = np.random.rand(3) * 200 - 100
            R = van.rotateCameraAtPoint(w_pt, w_cam, True)
            tst = van.projectPoints(van.createP(self.K, R, w_cam),
                                    w_pt).reshape((2))
            #Point should be at cx, cy in K matrix
            self.assertTrue(np.allclose(tst, self.K[:2, 2]))
    def createRandomWorldPoints(self,
                                K,
                                c_R_w,
                                w_t_cam,
                                num_pts,
                                dist_range=None):
        '''Create num_pts random world locations within the view of the camera
        at location w_t_cam and with orientation c_R_w.  dist_range defines how
        far away from the camera the points can be.  Default is between 1 and 51 meters.
        
        Note that "in camera field of view" is assumed to be at pixel locations between
        0 and 2*the center offset location in K.  i.e. x is between 0 and 2*K[0,2] and 
        y is between 0 and 2*K[1,2]

        This function returns a tuple of the world points and their pixel locations
        '''
        if dist_range is None:
            dist_range = (1., 51.)
        diff_dist = dist_range[1] - dist_range[0]

        d_rand = np.random.rand(num_pts) * diff_dist + dist_range[0]
        #Create some random image locations, assume a 640x480 image...
        x_rand = np.random.rand(2, num_pts)
        x_rand[0, :] *= 2 * K[0, 2]
        x_rand[1, :] *= 2 * K[1, 2]
        x_d_tuples = list((x_rand[:, ii], d_rand[ii]) for ii in range(num_pts))
        #Took random image points and projected them into space
        return (van.backprojectPoints(self.K, c_R_w, w_t_cam,
                                      x_d_tuples), x_rand)
    def test_projectPoints_and_backProject(self):
        #This tests that backProject is the opposite of projectPoints.  They could both
        #be wrong in the same way and this would not discover it.  Therefore a unit
        #test for one or the other should be used.  This should then confirm that they
        #are both okay (at least that is my thinking)
        n_random_locs = 10
        n_random_pts = 10

        for ii in range(n_random_locs):
            #Create a random rotation and location
            rand_rot = np.random.rand(3, 1) * 2 * m.pi - m.pi
            #skew symmetric
            SS = van.createSkewSymmMat(rand_rot)
            R_rand = la.expm(SS)
            #Somewhere in a 400x400x400 cube centered on the origin
            t_rand = np.random.rand(3) * 400 - 200
            #Generate the world points
            X, x_rand = self.createRandomWorldPoints(self.K, R_rand, t_rand,
                                                     n_random_pts)
            #Now take those random world points and project them back into the image
            x_after = van.projectPoints(van.createP(self.K, R_rand, t_rand), X)
            self.assertTrue(np.allclose(x_after, x_rand))
    def test_imPointDerivX(self):
        #This will be numerical test
        #Create a random world location and some random points in space
        #Move the points by a small amount (numerical derivative)
        #Compare with computed derivative
        N_tests = 20
        ss = .01  # step size
        for i in range(N_tests):
            #create random im_size
            im_size = np.random.rand(2) * 2000. + 400.  #between 400 and 2400
            focal_length = np.random.rand(1).item() * 2000. + 500.
            K = np.array([[focal_length, 0., im_size[0] / 2.0],
                          [0., focal_length, im_size[1] / 2.0], [0., 0., 1.]])
            rot = np.random.rand(3) * 2 * m.pi
            R = van.createRot(rot)
            w_cam = np.random.rand(3) * 400. - 200.
            P = van.createP(K, R, w_cam)
            true_x_loc = np.random.rand(2) * im_size
            X = van.backprojectPoints(
                K, R, w_cam,
                [(true_x_loc, (np.random.rand(1) * 500 + 50).item())]).reshape(
                    (3, ))
            X += np.random.rand(3) * 2 - 1
            im_x = van.projectPoints(P, X).reshape((2, ))
            #This function should do a "closed form" derivative
            comput_deriv = van.imPointDerivX(P, X)
            #Compute a numerical derivative
            numer_deriv = np.zeros((2, 3))
            for j in range(3):
                curr_X = X.copy()
                curr_X[j] += ss
                curr_im_pt = van.projectPoints(P, curr_X).reshape((2, ))
                numer_deriv[:, j] = (curr_im_pt - im_x) / ss
            #Compare the numerical and closed form derivative
            self.assertTrue(
                np.allclose(comput_deriv, numer_deriv, rtol=ss * .1))

        #I should really do a test to make sure that if row == 0 or row==1 it doesn't croak
        comput_deriv = van.imPointDerivX(P, X)
        comput_deriv0 = van.imPointDerivX(P, X, 0).reshape((1, 3))
        comput_deriv1 = van.imPointDerivX(P, X, 1).reshape((1, 3))
        test_deriv = np.concatenate((comput_deriv0, comput_deriv1), axis=0)
        self.assertTrue(np.allclose(comput_deriv, test_deriv))
    def test_backupCamera(self):
        #I will create a bunch of points in front of a camera, then move it forward.
        #After that, call backupCamera and make sure it ends up equal to or forward of
        #the original location
        rotation = np.zeros((3))
        rotation[0] = np.random.rand(1) * m.pi * 2 - m.pi
        R = van.createRot(rotation)
        im_size = (self.K[0, 2] * 2., self.K[1, 2] * 2.)
        pts = self.createRandomWorldPoints(self.K,
                                           R,
                                           np.zeros((3)),
                                           10,
                                           dist_range=(10, 50))[0]
        new_loc = np.array([0., 0., 9.])
        bu_loc = van.backupCamera(pts, R, new_loc, self.K, im_size)
        self.assertTrue(bu_loc[0] == 0.)
        self.assertTrue(bu_loc[1] == 0.)
        self.assertTrue(
            bu_loc[2] >= 0.
        )  #if you do a random or otherwise "sub-optimal backup step", this test can be modified
        #Now test the projections...
        P = van.createP(self.K, R, bu_loc)
        im_pts = van.projectPoints(P, pts)
        for i in range(im_pts.shape[1]):
            self.assertTrue(van.inImage(im_pts[:, i], im_size))

        #Now do the same thing, but with a buffer...
        bu_loc = van.backupCamera(pts, R, new_loc, self.K, im_size, 10)
        #Now test the projections...
        P = van.createP(self.K, R, bu_loc)
        im_pts = van.projectPoints(P, pts)
        for i in range(im_pts.shape[1]):
            self.assertTrue(van.inImage(im_pts[:, i], im_size, 10))

        #Try to do a more complex test
        #Create some points
        N_tests = 20
        for ii in range(N_tests):
            N_pts = 20
            pts = np.random.rand(3, N_pts) * 100 - 50
            cam_loc = np.random.rand(3) * 100 - 50
            random_rot = np.random.rand(3) * 2 * m.pi
            c_R_w = van.createRot(random_rot)
            t_cam = van.backupCamera(pts, c_R_w, cam_loc, self.K, im_size, 3)
            #Now test the projections...
            P = van.createP(self.K, c_R_w, t_cam)
            im_pts = van.projectPoints(P, pts)
            for i in range(N_pts):
                self.assertTrue(van.inImage(im_pts[:, i], im_size, 3))
            for i in range(N_pts):
                z_val = (np.dot(
                    P, np.array([pts[0, i], pts[1, i], pts[2, i], 1.])))[2]
                self.assertTrue(z_val >= 0)  #Make sure z is positive