main.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import cv2
  2. import glob
  3. from display import Display
  4. from extractor import Frame, denormalize, match_frames, add_ones
  5. import numpy as np
  6. from pointmap import Map, Point
  7. from utils import read_calibration_file, extract_intrinsic_matrix
  8. # calib_file_path = "../data/data_odometry_gray/dataset/sequences/00/calib.txt"
  9. # calib_lines = read_calibration_file(calib_file_path)
  10. # K = extract_intrinsic_matrix(calib_lines, camera_id='P0')
  11. # Camera intrinsics
  12. W, H = 1920 // 2, 1080 // 2
  13. # F = 270
  14. F = 450
  15. K = np.array([[F, 0, W // 2], [0, F, H // 2], [0, 0, 1]])
  16. Kinv = np.linalg.inv(K)
  17. # display = Display(1920, 1080)
  18. mapp = Map()
  19. mapp.create_viewer()
  20. def triangulate(pose1, pose2, pts1, pts2):
  21. ret = np.zeros((pts1.shape[0], 4))
  22. pose1 = np.linalg.inv(pose1)
  23. pose2 = np.linalg.inv(pose2)
  24. for i, p in enumerate(zip(add_ones(pts1), add_ones(pts2))):
  25. A = np.zeros((4, 4))
  26. A[0] = p[0][0] * pose1[2] - pose1[0]
  27. A[1] = p[0][1] * pose1[2] - pose1[1]
  28. A[2] = p[1][0] * pose2[2] - pose2[0]
  29. A[3] = p[1][1] * pose2[2] - pose2[1]
  30. _, _, vt = np.linalg.svd(A)
  31. ret[i] = vt[3]
  32. return ret
  33. def process_frame(img):
  34. img = cv2.resize(img, (W, H))
  35. frame = Frame(mapp, img, K)
  36. if frame.id == 0:
  37. return
  38. # previous frame f2 to the current frame f1.
  39. f1 = mapp.frames[-1]
  40. f2 = mapp.frames[-2]
  41. idx1, idx2, Rt = match_frames(f1, f2)
  42. print(f"=------------Rt {Rt}")
  43. # f2.pose represents the transformation from the world coordinate system to the coordinate system of the previous frame f2.
  44. # Rt represents the transformation from the coordinate system of f2 to the coordinate system of f1.
  45. # By multiplying Rt with f2.pose, you get a new transformation that directly maps the world coordinate system to the coordinate system of f1.
  46. f1.pose = np.dot(Rt, f2.pose)
  47. # The output is a matrix where each row is a 3D point in homogeneous coordinates [𝑋, 𝑌, 𝑍, 𝑊]
  48. pts4d = triangulate(f1.pose, f2.pose, f1.pts[idx1], f2.pts[idx2])
  49. # This line normalizes the 3D points by dividing each row by its fourth coordinate W
  50. # The homogeneous coordinates [𝑋, 𝑌, 𝑍, 𝑊] are converted to Euclidean coordinates
  51. pts4d /= pts4d[:, 3:]
  52. # Reject points without enough "Parallax" and points behind the camera
  53. # checks if the absolute value of the fourth coordinate W is greater than 0.005.
  54. # checks if the z-coordinate of the points is positive.
  55. # returns, A boolean array indicating which points satisfy both criteria.
  56. good_pts4d = (np.abs(pts4d[:, 3]) > 0.005) & (pts4d[:, 2] > 0)
  57. for i, p in enumerate(pts4d):
  58. # If the point is not good (i.e., good_pts4d[i] is False), the loop skips the current iteration and moves to the next point.
  59. if not good_pts4d[i]:
  60. continue
  61. pt = Point(mapp, p)
  62. pt.add_observation(f1, i)
  63. pt.add_observation(f2, i)
  64. for pt1, pt2 in zip(f1.pts[idx1], f2.pts[idx2]):
  65. u1, v1 = denormalize(K, pt1)
  66. u2, v2 = denormalize(K, pt2)
  67. # cv2.circle(img, (u1,v1), 3, (0,255,0), 2)
  68. cv2.circle(img, (u1,v1), 2, (77, 243, 255))
  69. cv2.line(img, (u1,v1), (u2, v2), (255,0,0))
  70. cv2.circle(img, (u2, v2), 2, (204, 77, 255))
  71. # 2-D display
  72. # img = cv2.resize(img, ( 320, 180))
  73. # display.paint(img)
  74. # 3-D display
  75. mapp.display()
  76. mapp.display_image(img)
  77. if __name__== "__main__":
  78. cap = cv2.VideoCapture("videos/car.mp4")
  79. while cap.isOpened():
  80. ret, frame = cap.read()
  81. # print("frame shape: ", frame.shape)
  82. print("\n################# [NEW FRAME] #################\n")
  83. if ret == True:
  84. process_frame(frame)
  85. else:
  86. break
  87. if cv2.waitKey(1) & 0xFF == ord('q'):
  88. break
  89. # Release the capture and close any OpenCV windows
  90. cap.release()
  91. cv2.destroyAllWindows()