def solve_for_r1(pts, K, lane_width): """ Solve for first column of the rotation matrix, utilizing the fact that we know the lane width. We require two pairs of points (p1,p2), (p3,p4), such that p1 is directly across from p2 (same for p3, p4). Input: tuple pts: ((p1, p2), (p3, p4)) where each point is a pixel coord: (float x, float y) nparray K The 3x3 camera intrinsic matrix. float lane_width The width of the lane (e.g., 3.66 meters). Output: nparray r1 A 3x1 column vector consisting of the first column of R. """ (fx, fy, (cx, cy)) = util_camera.get_intrinsics(K) # Construct data matrix A Araw = np.zeros([len(pts) * 2, 4]) i = 0 # Actual index into A for ii, (pi, pj) in enumerate(pts): xi, yi = pi xj, yj = pj Araw[i, :] = (0, -fy, (-cy + yj), (yi - yj)) Araw[i + 1, :] = (fx, 0, (cx - xj), (-xj + xi)) #Araw[i+2, :] = (-yj*fx, xj*fy, -yj*cx + xj*cy, yj*xi - xj*yi) i += 2 rnk = numpy.linalg.matrix_rank(Araw) print " Rank(A):", rnk if rnk == 3: A = Araw # Perfect! Just the rank we want. elif rnk < 3: raise Exception( "Matrix A needs to have rank either 4 or 3! Rank was: {0}".format( rnk)) else: # A is full rank - perform fixed-rank approx. -> rank 3 print "(solve_for_r1) A is full rank, performing fixed rank approx..." U, S, V = numpy.linalg.svd(Araw) if (np.linalg.det(V) < 0): # We require U,V to have positive determinant print " U,V had negative determinant, correcting." U = -U V = -V S_part = np.diag([S[0], S[1], S[2], 0]) # Kill last singular value S_new = np.zeros([Araw.shape[0], 4]) S_new[0:4, :] = S_part A = np.dot(U, np.dot(S_new, V)) print " new rank:", np.linalg.matrix_rank(A) if np.linalg.matrix_rank(A) != 3: raise Exception("(solve_for_r1) What?! Fixed-rank approx. failed!") U, S, V = numpy.linalg.svd(A) if (np.linalg.det(V) < 0): # We require U,V to have positive determinant print " U,V had negative determinant, correcting." U = -U V = -V v = V[-1, :] residual = numpy.linalg.norm(np.dot(A, v.T)) print "(solve_for_r1) Residual: {0}".format(residual) gamma = v[-1] v_norm = v / gamma r11, r21, r31, _ = v_norm return np.array([r11, r21, r31])
def solve_for_r1(pts, K, lane_width): """ Solve for first column of the rotation matrix, utilizing the fact that we know the lane width. We require two pairs of points (p1,p2), (p3,p4), such that p1 is directly across from p2 (same for p3, p4). Input: tuple pts: ((p1, p2), (p3, p4)) where each point is a pixel coord: (float x, float y) nparray K The 3x3 camera intrinsic matrix. float lane_width The width of the lane (e.g., 3.66 meters). Output: nparray r1 A 3x1 column vector consisting of the first column of R. """ (fx, fy, (cx, cy)) = util_camera.get_intrinsics(K) # Construct data matrix A Araw = np.zeros([len(pts) * 2, 4]) i = 0 # Actual index into A for ii, (pi, pj) in enumerate(pts): xi, yi = pi xj, yj = pj Araw[i, :] = (0, -fy, (-cy + yj), (yi - yj)) Araw[i+1, :] = (fx, 0, (cx - xj), (-xj + xi)) #Araw[i+2, :] = (-yj*fx, xj*fy, -yj*cx + xj*cy, yj*xi - xj*yi) i += 2 rnk = numpy.linalg.matrix_rank(Araw) print " Rank(A):", rnk if rnk == 3: A = Araw # Perfect! Just the rank we want. elif rnk < 3: raise Exception("Matrix A needs to have rank either 4 or 3! Rank was: {0}".format(rnk)) else: # A is full rank - perform fixed-rank approx. -> rank 3 print "(solve_for_r1) A is full rank, performing fixed rank approx..." U, S, V = numpy.linalg.svd(Araw) if (np.linalg.det(V) < 0): # We require U,V to have positive determinant print " U,V had negative determinant, correcting." U = -U V = -V S_part = np.diag([S[0], S[1], S[2], 0]) # Kill last singular value S_new = np.zeros([Araw.shape[0], 4]) S_new[0:4, :] = S_part A = np.dot(U, np.dot(S_new, V)) print " new rank:", np.linalg.matrix_rank(A) if np.linalg.matrix_rank(A) != 3: raise Exception("(solve_for_r1) What?! Fixed-rank approx. failed!") U, S, V = numpy.linalg.svd(A) if (np.linalg.det(V) < 0): # We require U,V to have positive determinant print " U,V had negative determinant, correcting." U = -U V = -V v = V[-1, :] residual = numpy.linalg.norm(np.dot(A, v.T)) print "(solve_for_r1) Residual: {0}".format(residual) gamma = v[-1] v_norm = v / gamma r11, r21, r31, _ = v_norm return np.array([r11, r21, r31])
def solve_for_t(pts, K, r1, r3, lane_width): """ Recover the translation vector T, using the computed r1, r3. The input points pairs must be directly across from the lanes. Input: tuple pts: ((pt1, pt2), ...) Each point pair (pt_i, pt_j) must be directly across the lanes i.e. (X_j - X_i) = 3.66 meters, and: X_i = -1.83 meters X_j = +1.83 meters nparray K 3x3 camera intrinsic matrix. nparray r1, r3 The 3x1 column vectors comprising the first/third columns of the rotation matrix R. float lane_width Width of the lane (in meters). Output: nparray T The translation vector T as a 3x1 column vector. """ (fx, fy, (cx, cy)) = util_camera.get_intrinsics(K) Kinv = numpy.linalg.inv(K) r11, r21, r31 = r1 r13, r23, r33 = r3 ww = lane_width / 2 # Construct data matrix A Araw = np.zeros([len(pts) * 6, 5]) i = 0 # Actual index into A for ii, (pi, pj) in enumerate(pts): xi, yi = pi xj, yj = pj bi = np.array([(xi - cx) / fx, (yi - cy) / fy, 1]).T bj = np.array([(xj - cx) / fx, (yj - cy) / fy, 1]).T Araw[i, :] = [r13, 1, 0, 0, -ww * r11 - bi[0]] Araw[i + 1, :] = [r23, 0, 1, 0, -ww * r21 - bi[1]] Araw[i + 2, :] = [r33, 0, 0, 1, -ww * r31 - bi[2]] Araw[i + 3, :] = [r13, 1, 0, 0, -ww * r11 - bj[0]] Araw[i + 4, :] = [r23, 0, 1, 0, -ww * r21 - bj[1]] Araw[i + 5, :] = [r33, 0, 0, 1, -ww * r31 - bj[2]] i += 6 rnk = np.linalg.matrix_rank(Araw) if rnk == 4: A = Araw # Perfect! Just the rank we want. elif rnk < 4: raise Exception( "(solve_for_r3) Matrix rank needs to be either 5 or 4 (was: {0})". format(rnk)) else: # Perform fixed-rank approx on Araw (want rank 4) print "(solve_for_t): Araw has full rank, performing fixed_rank approx..." U, S, V = np.linalg.svd(Araw) if np.linalg.svd(V) < 0: U = -U V = -V S_new = np.zeros([U.shape[0], 5]) for i in xrange(4): S_new[i, i] = S[i] A = np.dot(U, np.dot(S_new, V)) print np.allclose(Araw, A) print Araw[0, :] print '==' print A[0, :] print "(solve_for_t): Rank(A):", np.linalg.matrix_rank(A) U, S, V = numpy.linalg.svd(A) if np.linalg.det(V) < 0: U = -U V = -V v = V[-1, :] print " residual: {0}".format(np.linalg.norm(np.dot(A, v))) gamma = v[-1] v_norm = v / gamma Z, tx, ty, tz, _ = v_norm return np.array([tx, ty, tz]).T
def solve_for_t(pts, K, r1, r3, lane_width): """ Recover the translation vector T, using the computed r1, r3. The input points pairs must be directly across from the lanes. Input: tuple pts: ((pt1, pt2), ...) Each point pair (pt_i, pt_j) must be directly across the lanes i.e. (X_j - X_i) = 3.66 meters, and: X_i = -1.83 meters X_j = +1.83 meters nparray K 3x3 camera intrinsic matrix. nparray r1, r3 The 3x1 column vectors comprising the first/third columns of the rotation matrix R. float lane_width Width of the lane (in meters). Output: nparray T The translation vector T as a 3x1 column vector. """ (fx, fy, (cx, cy)) = util_camera.get_intrinsics(K) Kinv = numpy.linalg.inv(K) r11, r21, r31 = r1 r13, r23, r33 = r3 ww = lane_width / 2 # Construct data matrix A Araw = np.zeros([len(pts) * 6, 5]) i = 0 # Actual index into A for ii, (pi, pj) in enumerate(pts): xi, yi = pi xj, yj = pj bi = np.array([(xi - cx) / fx, (yi - cy) / fy, 1]).T bj = np.array([(xj - cx) / fx, (yj - cy) / fy, 1]).T Araw[i, :] = [r13, 1, 0, 0, -ww*r11 - bi[0]] Araw[i+1, :] = [r23, 0, 1, 0, -ww*r21 - bi[1]] Araw[i+2, :] = [r33, 0, 0, 1, -ww*r31 - bi[2]] Araw[i+3, :] = [r13, 1, 0, 0, -ww*r11 - bj[0]] Araw[i+4, :] = [r23, 0, 1, 0, -ww*r21 - bj[1]] Araw[i+5, :] = [r33, 0, 0, 1, -ww*r31 - bj[2]] i += 6 rnk = np.linalg.matrix_rank(Araw) if rnk == 4: A = Araw # Perfect! Just the rank we want. elif rnk < 4: raise Exception("(solve_for_r3) Matrix rank needs to be either 5 or 4 (was: {0})".format(rnk)) else: # Perform fixed-rank approx on Araw (want rank 4) print "(solve_for_t): Araw has full rank, performing fixed_rank approx..." U, S, V = np.linalg.svd(Araw) if np.linalg.svd(V) < 0: U = -U V = -V S_new = np.zeros([U.shape[0], 5]) for i in xrange(4): S_new[i,i] = S[i] A = np.dot(U, np.dot(S_new, V)) print np.allclose(Araw, A) print Araw[0,:] print '==' print A[0,:] print "(solve_for_t): Rank(A):", np.linalg.matrix_rank(A) U, S, V = numpy.linalg.svd(A) if np.linalg.det(V) < 0: U = -U V = -V v = V[-1, :] print " residual: {0}".format(np.linalg.norm(np.dot(A, v))) gamma = v[-1] v_norm = v / gamma Z, tx, ty, tz, _ = v_norm return np.array([tx, ty, tz]).T