Skip to content

Commit 68174d3

Browse files
committed
add calibration
1 parent 3fe14e0 commit 68174d3

13 files changed

Lines changed: 325 additions & 1 deletion

calibration/board.jpg

3.4 MB
Loading
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import cv2
2+
import numpy as np
3+
import copy
4+
import yaml
5+
6+
input = "data/chessboard.avi"
7+
8+
board_pattern = (10, 7)
9+
select_images = True
10+
11+
capture = cv2.VideoCapture(input)
12+
13+
if capture.isOpened() == False: raise Exception("No video")
14+
15+
images = []
16+
17+
while True:
18+
ret1, image = capture.read()
19+
if not ret1: break
20+
if select_images:
21+
cv2.imshow("3DV Tutorial: Camera Calibration", image)
22+
key = cv2.waitKey(1)
23+
if key == 27: break # 'ESC' key: Exit
24+
elif key == 32: # 'Space' key: Pause
25+
ret2, pts = cv2.findChessboardCorners(image, board_pattern, None) # No flags
26+
27+
# display = image.clone()
28+
display = copy.deepcopy(image)
29+
display = cv2.drawChessboardCorners(display, board_pattern, pts, ret2)
30+
cv2.imshow("3DV Tutorial: Camera Calibration", display)
31+
key = cv2.waitKey()
32+
if key == 27: break
33+
elif key == 13: images.append(image) # 'Enter' key: Save
34+
else:
35+
images.append(image)
36+
37+
capture.release()
38+
39+
if(len(images)) == 0:
40+
print("no images")
41+
raise Exception("There is no captured images!")
42+
43+
# Find 2D corner points from given images
44+
img_points = []
45+
h, w = 0,0
46+
for image in images:
47+
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
48+
h, w = gray.shape
49+
ret3, corners = cv2.findChessboardCorners(gray, board_pattern) # No flags
50+
if ret3 == True:
51+
img_points.append(corners)
52+
53+
if len(img_points) == 0:
54+
raise Exception("No 2d Corner pts")
55+
56+
# Prepare 3D points of the chess board
57+
objp = np.zeros((10*7, 3), np.float32)
58+
objp[:, :2] = np.mgrid[0:7, 0:10].T.reshape(-1, 2)
59+
obj_points = []
60+
for _ in images:
61+
obj_points.append(objp)
62+
63+
# Calibrate Camera
64+
K = np.eye(3,3, dtype=np.float32)
65+
dist_coeff = np.zeros((4,1))
66+
rms, K, dist_coeff, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, (h,w), None, None)
67+
68+
# Report calibration results
69+
print("## Camera Calibration Results")
70+
print(f"* The number of applied images = {w}x{h}")
71+
print(f"* RMS error = {rms}")
72+
print(f"* Camera matrix (K) = \n{K}")
73+
print(f"* Distortion coefficient (k1, k2, p1, p2, k3, ...) = {dist_coeff}")
74+
75+
# Save as cam_config.yaml
76+
file_name = "cfg/cam_config.yaml"
77+
cam_dict = {
78+
"Intrinsic": K.flatten().tolist(),
79+
"Distortion": dist_coeff.flatten().tolist(),
80+
"RMS": rms,
81+
}
82+
with open(file_name, 'w') as f:
83+
yaml.dump(cam_dict, f, sort_keys=False, default_flow_style=False)
84+
85+
print("End!")
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import cv2
2+
import numpy as np
3+
import copy
4+
import yaml
5+
import time
6+
7+
help_msg = "At least 40 images is needed for calibrating camera. We Take picture in every 2 sec."
8+
board_pattern = (10, 7)
9+
10+
capture = cv2.VideoCapture(0)
11+
if capture.isOpened() == False: raise Exception("No video")
12+
13+
images = []
14+
count = 0
15+
TIME_LIMIT = 2
16+
t = time.time()
17+
18+
print(help_msg)
19+
20+
while True:
21+
ret1, image = capture.read()
22+
if not ret1: break
23+
24+
key = cv2.waitKey(1)
25+
if key == 27 or count == 40: break # 'ESC' key: Exit
26+
# elif key == 13: images.append(image) # 'Enter' key: Save image
27+
if time.time() - t > TIME_LIMIT:
28+
images.append(image)
29+
count += 1
30+
ret2, pts = cv2.findChessboardCorners(image, board_pattern, None) # No flags
31+
image = copy.deepcopy(image)
32+
image = cv2.drawChessboardCorners(image, board_pattern, pts, ret2)
33+
34+
cv2.imshow("3DV Tutorial: Camera Calibration", image)
35+
36+
capture.release()
37+
38+
if(len(images)) == 0:
39+
print("no images")
40+
raise Exception("There is no captured images!")
41+
42+
# Find 2D corner points from given images
43+
img_points = []
44+
h, w = 0,0
45+
for image in images:
46+
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
47+
h, w = gray.shape
48+
ret3, corners = cv2.findChessboardCorners(gray, board_pattern) # No flags
49+
if ret3 == True:
50+
img_points.append(corners)
51+
52+
if len(img_points) == 0:
53+
raise Exception("No 2d Corner pts")
54+
55+
# Prepare 3D points of the chess board
56+
objp = np.zeros((10*7, 3), np.float32)
57+
objp[:, :2] = np.mgrid[0:7, 0:10].T.reshape(-1, 2)
58+
obj_points = []
59+
for _ in images:
60+
obj_points.append(objp)
61+
62+
# Calibrate Camera
63+
K = np.eye(3,3, dtype=np.float32)
64+
dist_coeff = np.zeros((4,1))
65+
rms, K, dist_coeff, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, (h,w), None, None)
66+
67+
# Report calibration results
68+
print("## Camera Calibration Results")
69+
print(f"* The number of applied images = {w}x{h}")
70+
print(f"* RMS error = {rms}")
71+
print(f"* Camera matrix (K) = \n{K}")
72+
print(f"* Distortion coefficient (k1, k2, p1, p2, k3, ...) = {dist_coeff}")
73+
74+
# Save as cam_config.yaml
75+
file_name = "cfg/cam_config.yaml"
76+
cam_dict = {
77+
"Intrinsic": K.flatten().tolist(),
78+
"Distortion": dist_coeff.flatten().tolist(),
79+
"RMS": rms,
80+
}
81+
with open(file_name, 'w') as f:
82+
yaml.dump(cam_dict, f, sort_keys=False, default_flow_style=False)
83+
84+
print("End!")

calibration/corner.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import cv2
2+
import numpy as np
3+
4+
def main():
5+
img_name = "board.jpg"
6+
img = cv2.imread(img_name)
7+
img = cv2.resize(img, (640, 640))
8+
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
9+
10+
11+
gray = np.float32(gray)
12+
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
13+
14+
# img[dst>0.01*dst.max()]=[0,0,255]
15+
x = dst[dst>0.01*dst.max()]
16+
print(x.shape)
17+
# for corner in img[dst>0.01*dst.max()]:
18+
# print(corner.shape)
19+
# img = cv2.circle(img, tuple(corner), 5, (0, 0, 255), 1)
20+
21+
# print(dst.shape)
22+
# print(test.shape)
23+
cv2.imshow("img", img)
24+
cv2.waitKey(0)
25+
26+
27+
28+
if __name__ == "__main__":
29+
main()
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from re import S
2+
import cv2
3+
import numpy as np
4+
import yaml
5+
from yaml.loader import SafeLoader
6+
7+
def main():
8+
input = "data/chessboard.avi"
9+
cam_params_file = "cam_config.yaml"
10+
K = np.zeros((3,3))
11+
dist_coeff = np.zeros((4,1))
12+
with open(cam_params_file, 'r') as f:
13+
cam_params = yaml.load(f, Loader=SafeLoader)
14+
K = np.resize(cam_params["Intrinsic"], (3,3))
15+
dist_coeff = np.resize(cam_params["Distortion"], (4,1))
16+
17+
# Open Video
18+
capture = cv2.VideoCapture(input)
19+
if capture.isOpened() == False: raise Exception("No video")
20+
21+
show_rectify = True
22+
map1 = np.array([])
23+
map2 = np.array([])
24+
25+
while True:
26+
ret, image = capture.read()
27+
if not ret: break
28+
29+
info = "Original"
30+
if(show_rectify):
31+
if not (len(map1) & len(map2)):
32+
map1, map2 = cv2.initUndistortRectifyMap(K, dist_coeff, None, None, (image.shape[1], image.shape[0]), cv2.CV_32FC1)
33+
image = cv2.remap(image, map1, map2, interpolation=cv2.INTER_LINEAR)
34+
info = "Rectified"
35+
cv2.putText(image, info, (5,15), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255,0))
36+
37+
cv2.imshow("3DV Tutorial: Distortion Correction", image)
38+
39+
key = cv2.waitKey(1)
40+
if key == 27: break
41+
elif key == 9: show_rectify = not show_rectify
42+
elif key == 32:
43+
key = cv2.waitKey()
44+
if key == 27: break
45+
elif key == 9: show_rectify = not show_rectify
46+
47+
capture.release()
48+
49+
if __name__ == "__main__":
50+
main()
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import cv2
2+
import numpy as np
3+
import pyrealsense2 as rs
4+
from threading import Lock
5+
import time
6+
7+
# This is cv2 and T265
8+
frame_mutex = Lock()
9+
frame_data = {"left" : None,
10+
"right" : None,
11+
"timestamp_ms" : None
12+
}
13+
14+
def callback(frame):
15+
global frame_data
16+
if frame.is_frameset():
17+
frameset = frame.as_frameset()
18+
f1 = frameset.get_fisheye_frame(1).as_video_frame()
19+
f2 = frameset.get_fisheye_frame(2).as_video_frame()
20+
left_data = np.asanyarray(f1.get_data())
21+
right_data = np.asanyarray(f2.get_data())
22+
ts = frameset.get_timestamp()
23+
frame_mutex.acquire()
24+
frame_data["left"] = left_data
25+
frame_data["right"] = right_data
26+
frame_data["timestamp_ms"] = ts
27+
frame_mutex.release()
28+
29+
# How to see realsense with cv2
30+
pipeline = rs.pipeline()
31+
cfg = rs.config()
32+
33+
# Get Device Product
34+
pipeline.start(cfg, callback)
35+
36+
try:
37+
WINDOW_TITLE = "Realsense"
38+
cv2.namedWindow(WINDOW_TITLE, cv2.WINDOW_NORMAL)
39+
profiles = pipeline.get_active_profile()
40+
streams = {"left": profiles.get_stream(rs.stream.fisheye,1).as_video_stream_profile(),
41+
"right": profiles.get_stream(rs.stream.fisheye,2).as_video_stream_profile()}
42+
t = 0
43+
while True:
44+
t = time.time()
45+
frame_mutex.acquire()
46+
valid = frame_data["timestamp_ms"] is not None
47+
frame_mutex.release()
48+
49+
if valid:
50+
frame_mutex.acquire()
51+
frame_copy = {"left": frame_data["left"].copy(),
52+
"right": frame_data["right"].copy()}
53+
frame_shape = frame_copy["left"].shape
54+
frame_mutex.release()
55+
try:
56+
t = time.time() - t
57+
fps = 1/t
58+
59+
cv2.putText(frame_copy["left"], f"fps is {fps:.2}", (5, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,255), 2)
60+
cv2.putText(frame_copy["right"], f"shape is {frame_shape[1]} x {frame_shape[0]}", (5, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,255), 2)
61+
cv2.imshow(WINDOW_TITLE, np.hstack((frame_copy["left"], frame_copy["right"])))
62+
except Exception as e:
63+
print(e)
64+
65+
key = cv2.waitKey(1)
66+
if key == ord('q'): break
67+
68+
except Exception as e:
69+
print(e)
70+
71+
finally:
72+
pipeline.stop()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pybackend2.cpython-38-x86_64-linux-gnu.so.2
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pybackend2.cpython-38-x86_64-linux-gnu.so.2.45.0
961 KB
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pyrealsense2.cpython-38-x86_64-linux-gnu.so.2.45

0 commit comments

Comments
 (0)