Skip to content

Commit 8f3772f

Browse files
committed
Make C++ and Python examples consistent
1 parent 3633968 commit 8f3772f

35 files changed

Lines changed: 395 additions & 338 deletions

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
build
1+
data/KITTI07/image_0
22
slides
3+
build
34

45
x64
56
Debug

examples/3d_rotation_conversion.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
from scipy.spatial.transform import Rotation
33

44
# The given 3D rotation
5-
euler = (45, 30, 60) # Unit: [deg] in XYZ-order
5+
euler = (45, 30, 60) # Unit: [deg] in the XYZ-order
66

77
# Generate 3D rotation object
88
robj = Rotation.from_euler('zyx', euler[::-1], degrees=True)
99

1010
# Print other representations
1111
print('\n## Euler Angle (ZYX)')
12-
print(np.rad2deg(robj.as_euler('zyx'))) # [60, 30, 45] [deg]
12+
print(np.rad2deg(robj.as_euler('zyx'))) # [60, 30, 45] [deg] in the ZYX-order
1313
print('\n## Rotation Matrix')
1414
print(robj.as_matrix())
1515
print('\n## Rotation Vector')
1616
print(robj.as_rotvec()) # [0.97, 0.05, 1.17]
17-
print('\n## Quaternion (XYZW)') # [0.44, 0.02, 0.53, 0.72]
18-
print(robj.as_quat())
17+
print('\n## Quaternion (XYZW)')
18+
print(robj.as_quat()) # [0.44, 0.02, 0.53, 0.72]

examples/affine_estimation_implement.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import cv2 as cv
21
import numpy as np
2+
import cv2 as cv
33

44
def getAffineTransform(src, dst):
55
if len(src) == len(dst):
@@ -12,7 +12,7 @@ def getAffineTransform(src, dst):
1212
b.append(q[1])
1313
x = np.linalg.pinv(A) @ b
1414

15-
# Reorganize 'H'
15+
# Reorganize `x` as a matrix
1616
H = np.array([[x[0], x[1], x[4]], [x[2], x[3], x[5]]])
1717
return H
1818

examples/camera_calibration.cpp

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
#include "opencv2/opencv.hpp"
2-
#include "fstream"
2+
#include "iostream"
33

44
int main()
55
{
6-
const char* input = "data/chessboard.avi";
6+
const char* video_file = "../data/chessboard.avi";
77
cv::Size board_pattern(10, 7);
88
float board_cellsize = 0.025f;
99
bool select_images = true;
1010

1111
// Open a video
1212
cv::VideoCapture video;
13-
if (!video.open(input)) return -1;
13+
if (!video.open(video_file)) return -1;
1414

1515
// Select images
1616
std::vector<cv::Mat> images;
@@ -24,20 +24,19 @@ int main()
2424
if (select_images)
2525
{
2626
// Show the image and keep it if selected
27-
cv::imshow("3DV Tutorial: Camera Calibration", image);
27+
cv::imshow("Camera Calibration", image);
2828
int key = cv::waitKey(1);
29-
if (key == 27) break; // 'ESC' key: Exit
30-
else if (key == 32) // 'Space' key: Pause
29+
if (key == 32) // Space: Pause and show corners
3130
{
3231
std::vector<cv::Point2f> pts;
3332
bool complete = cv::findChessboardCorners(image, board_pattern, pts);
3433
cv::Mat display = image.clone();
3534
cv::drawChessboardCorners(display, board_pattern, pts, complete);
36-
cv::imshow("3DV Tutorial: Camera Calibration", display);
35+
cv::imshow("Camera Calibration", display);
3736
key = cv::waitKey();
38-
if (key == 27) break; // 'ESC' key: Exit
39-
else if (key == 13) images.push_back(image); // 'Enter' key: Select
37+
if (key == 13) images.push_back(image); // Enter: Select the image
4038
}
39+
if (key == 27) break; // ESC: Exit (Complete image selection)
4140
}
4241
else images.push_back(image);
4342
}
@@ -67,14 +66,11 @@ int main()
6766
std::vector<cv::Mat> rvecs, tvecs;
6867
double rms = cv::calibrateCamera(obj_points, img_points, images[0].size(), K, dist_coeff, rvecs, tvecs);
6968

70-
// Report calibration results
71-
std::ofstream report("camera_calibration.txt");
72-
if (!report.is_open()) return -1;
73-
report << "## Camera Calibration Results" << std::endl;
74-
report << "* The number of applied images = " << img_points.size() << std::endl;
75-
report << "* RMS error = " << rms << std::endl;
76-
report << "* Camera matrix (K) = " << std::endl << " " << K.row(0) << K.row(1) << K.row(2) << std::endl;
77-
report << "* Distortion coefficient (k1, k2, p1, p2, k3, ...) = " << std::endl << " " << dist_coeff.t() << std::endl;
78-
report.close();
69+
// Print calibration results
70+
std::cout << "## Camera Calibration Results" << std::endl;
71+
std::cout << "* The number of applied images = " << img_points.size() << std::endl;
72+
std::cout << "* RMS error = " << rms << std::endl;
73+
std::cout << "* Camera matrix (K) = " << std::endl << " " << K.row(0) << K.row(1) << K.row(2) << std::endl;
74+
std::cout << "* Distortion coefficient (k1, k2, p1, p2, k3, ...) = " << std::endl << " " << dist_coeff.t() << std::endl;
7975
return 0;
8076
}

examples/camera_calibration.py

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import numpy as np
22
import cv2 as cv
33

4-
def select_img_from_video(input_file, board_pattern, select_all=False, wait_msec=10):
4+
def select_img_from_video(video_file, board_pattern, select_all=False, wait_msec=10, wnd_name='Camera Calibration'):
55
# Open a video
6-
video = cv.VideoCapture(input_file)
7-
assert video.isOpened(), 'Cannot read the given input, ' + input_file
6+
video = cv.VideoCapture(video_file)
7+
assert video.isOpened()
88

99
# Select images
1010
img_select = []
@@ -20,21 +20,19 @@ def select_img_from_video(input_file, board_pattern, select_all=False, wait_msec
2020
# Show the image
2121
display = img.copy()
2222
cv.putText(display, f'NSelect: {len(img_select)}', (10, 25), cv.FONT_HERSHEY_DUPLEX, 0.6, (0, 255, 0))
23-
cv.imshow('Camera Calibration', display)
23+
cv.imshow(wnd_name, display)
2424

2525
# Process the key event
2626
key = cv.waitKey(wait_msec)
27-
if key == 27: # 'ESC' key: Exit (Complete image selection)
28-
break
29-
elif key == ord(' '): # 'Space' key: Pause and show corners
27+
if key == ord(' '): # Space: Pause and show corners
3028
complete, pts = cv.findChessboardCorners(img, board_pattern)
3129
cv.drawChessboardCorners(display, board_pattern, pts, complete)
32-
cv.imshow('Camera Calibration', display)
30+
cv.imshow(wnd_name, display)
3331
key = cv.waitKey()
34-
if key == 27: # ESC
35-
break
36-
elif key == ord('\r'):
37-
img_select.append(img) # 'Enter' key: Select the image
32+
if key == ord('\r'):
33+
img_select.append(img) # Enter: Select the image
34+
if key == 27: # ESC: Exit (Complete image selection)
35+
break
3836

3937
cv.destroyAllWindows()
4038
return img_select
@@ -47,23 +45,21 @@ def calib_camera_from_chessboard(images, board_pattern, board_cellsize, K=None,
4745
complete, pts = cv.findChessboardCorners(gray, board_pattern)
4846
if complete:
4947
img_points.append(pts)
50-
assert len(img_points) > 0, 'There is no set of complete chessboard points!'
48+
assert len(img_points) > 0
5149

5250
# Prepare 3D points of the chess board
5351
obj_pts = [[c, r, 0] for r in range(board_pattern[1]) for c in range(board_pattern[0])]
54-
obj_points = [np.array(obj_pts, dtype=np.float32) * board_cellsize] * len(img_points) # Must be 'np.float32'
52+
obj_points = [np.array(obj_pts, dtype=np.float32) * board_cellsize] * len(img_points) # Must be `np.float32`
5553

5654
# Calibrate the camera
5755
return cv.calibrateCamera(obj_points, img_points, gray.shape[::-1], K, dist_coeff, flags=calib_flags)
5856

59-
60-
6157
if __name__ == '__main__':
62-
input_file = '../data/chessboard.avi'
58+
video_file = '../data/chessboard.avi'
6359
board_pattern = (10, 7)
6460
board_cellsize = 0.025
6561

66-
img_select = select_img_from_video(input_file, board_pattern)
62+
img_select = select_img_from_video(video_file, board_pattern)
6763
assert len(img_select) > 0, 'There is no selected images!'
6864
rms, K, dist_coeff, rvecs, tvecs = calib_camera_from_chessboard(img_select, board_pattern, board_cellsize)
6965

examples/camera_calibration_implement.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ def calibrateCamera(obj_pts, img_pts, img_size):
2626

2727
if __name__ == '__main__':
2828
img_size = (640, 480)
29-
img_files = ['../bin/data/image_formation1.xyz', '../bin/data/image_formation2.xyz']
29+
img_files = ['../data/image_formation1.xyz', '../data/image_formation2.xyz']
3030
img_pts = []
3131
for file in img_files:
32-
pts = np.loadtxt('../bin/data/image_formation1.xyz', dtype=np.float32)
32+
pts = np.loadtxt(file, dtype=np.float32)
3333
img_pts.append(pts[:,:2])
3434

35-
pts = np.loadtxt('../bin/data/box.xyz', dtype=np.float32)
35+
pts = np.loadtxt('../data/box.xyz', dtype=np.float32)
3636
obj_pts = [pts] * len(img_pts) # Copy the object point as much as the number of image observation
3737

3838
# Calibrate the camera

examples/distortion_correction.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,28 @@
22

33
int main()
44
{
5-
const char* input = "data/chessboard.avi";
6-
cv::Matx33d K(432.7390364738057, 0, 476.0614994349778, 0, 431.2395555913084, 288.7602152621297, 0, 0, 1);
5+
// The given video and calibration data
6+
const char* video_file = "../data/chessboard.avi";
7+
cv::Matx33d K(432.7390364738057, 0, 476.0614994349778,
8+
0, 431.2395555913084, 288.7602152621297,
9+
0, 0, 1); // Derived from `calibrate_camera.py`
710
std::vector<double> dist_coeff = { -0.2852754904152874, 0.1016466459919075, -0.0004420196146339175, 0.0001149909868437517, -0.01803978785585194 };
811

912
// Open a video
1013
cv::VideoCapture video;
11-
if (!video.open(input)) return -1;
14+
if (!video.open(video_file)) return -1;
1215

1316
// Run distortion correction
1417
bool show_rectify = true;
1518
cv::Mat map1, map2;
1619
while (true)
1720
{
18-
// Grab an image from the video
21+
// Read an image from the video
1922
cv::Mat image;
2023
video >> image;
2124
if (image.empty()) break;
2225

23-
// Rectify geometric distortion (c.f. 'cv::undistort()' can be applied for one-time remapping.)
26+
// Rectify geometric distortion (Alternative: `cv.undistort()`)
2427
cv::String info = "Original";
2528
if (show_rectify)
2629
{
@@ -32,16 +35,11 @@ int main()
3235
cv::putText(image, info, cv::Point(5, 15), cv::FONT_HERSHEY_PLAIN, 1, cv::Vec3b(0, 255, 0));
3336

3437
// Show the image
35-
cv::imshow("3DV Tutorial: Distortion Correction", image);
36-
int key = cv::waitKey(1);
37-
if (key == 27) break; // 'ESC' key: Exit
38-
else if (key == 9) show_rectify = !show_rectify; // 'Tab' key: Toggle rectification
39-
else if (key == 32) // 'Space' key: Pause
40-
{
41-
key = cv::waitKey();
42-
if (key == 27) break; // 'ESC' key: Exit
43-
else if (key == 9) show_rectify = !show_rectify; // 'Tab' key: Toggle rectification
44-
}
38+
cv::imshow("Geometric Distortion Correction", image);
39+
int key = cv::waitKey(10);
40+
if (key == 32) key = cv::waitKey(); // Space: Pause
41+
if (key == 27) break; // ESC: Exit
42+
else if (key == 9) show_rectify = !show_rectify; // Tab: Toggle the mode
4543
}
4644

4745
video.release();

examples/distortion_correction.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
import cv2 as cv
33

44
# The given video and calibration data
5-
input_file = '../data/chessboard.avi'
5+
video_file = '../data/chessboard.avi'
66
K = np.array([[432.7390364738057, 0, 476.0614994349778],
77
[0, 431.2395555913084, 288.7602152621297],
8-
[0, 0, 1]])
8+
[0, 0, 1]]) # Derived from `calibrate_camera.py`
99
dist_coeff = np.array([-0.2852754904152874, 0.1016466459919075, -0.0004420196146339175, 0.0001149909868437517, -0.01803978785585194])
1010

1111
# Open a video
12-
video = cv.VideoCapture(input_file)
13-
assert video.isOpened(), 'Cannot read the given input, ' + input_file
12+
video = cv.VideoCapture(video_file)
13+
assert video.isOpened(), 'Cannot read the given input, ' + video_file
1414

1515
# Run distortion correction
1616
show_rectify = True
@@ -21,7 +21,7 @@
2121
if not valid:
2222
break
2323

24-
# Rectify geometric distortion (Alternative: cv.undistort())
24+
# Rectify geometric distortion (Alternative: `cv.undistort()`)
2525
info = "Original"
2626
if show_rectify:
2727
if map1 is None or map2 is None:
@@ -31,13 +31,13 @@
3131
cv.putText(img, info, (10, 25), cv.FONT_HERSHEY_DUPLEX, 0.6, (0, 255, 0))
3232

3333
# Show the image and process the key event
34-
cv.imshow("Distortion Correction", img)
34+
cv.imshow("Geometric Distortion Correction", img)
3535
key = cv.waitKey(10)
36-
if key == ord(' '):
36+
if key == ord(' '): # Space: Pause
3737
key = cv.waitKey()
38-
if key == 27: # ESC
38+
if key == 27: # ESC: Exit
3939
break
40-
elif key == ord('\t'):
40+
elif key == ord('\t'): # Tab: Toggle the mode
4141
show_rectify = not show_rectify
4242

4343
video.release()

examples/distortion_visualization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
merge = np.hstack((img_vector, img_grid))
3535
info = f'Focal: {K[0, 0]:.0f}, k1: {dist_coeff[0]:.2f}, k2: {dist_coeff[1]:.2f}, p1: {dist_coeff[2]:.2f}, p2: {dist_coeff[3]:.2f}'
3636
cv.putText(merge, info, (10, 25), cv.FONT_HERSHEY_DUPLEX, 0.6, (0, 0, 0))
37-
cv.imshow('Distortion Visualization: Vectors | Grids', merge)
37+
cv.imshow('Geometric Distortion Visualization: Vectors | Grids', merge)
3838
key = cv.waitKey()
3939
if key == 27: # ESC
4040
break

examples/fundamental_mat_estimation_implement.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import cv2 as cv
21
import numpy as np
2+
import cv2 as cv
33

44
def findFundamentalMat(pts1, pts2):
55
if len(pts1) == len(pts2):
@@ -16,16 +16,16 @@ def findFundamentalMat(pts1, pts2):
1616
_, _, Vt = np.linalg.svd(A, full_matrices=True)
1717
x = Vt[-1]
1818

19-
# Reorganize 'F' and enforce 'rank(F) = 2'
19+
# Reorganize `x` as `F` and enforce 'rank(F) = 2'
2020
F = x.reshape(3, -1)
2121
U, S, Vt = np.linalg.svd(F)
2222
S[-1] = 0
2323
F = U @ np.diag(S) @ Vt
2424
return F / F[-1,-1] # Normalize the last element as 1
2525

2626
if __name__ == '__main__':
27-
pts0 = np.loadtxt('../bin/data/image_formation0.xyz')
28-
pts1 = np.loadtxt('../bin/data/image_formation1.xyz')
27+
pts0 = np.loadtxt('../data/image_formation0.xyz')
28+
pts1 = np.loadtxt('../data/image_formation1.xyz')
2929

3030
my_F = findFundamentalMat(pts0, pts1)
3131
cv_F, _ = cv.findFundamentalMat(pts0, pts1, cv.FM_8POINT)

0 commit comments

Comments
 (0)