Skip to content

Commit 4fe694a

Browse files
committed
Add fisheye calibration demo
1 parent 702a955 commit 4fe694a

File tree

3 files changed

+83
-3
lines changed

3 files changed

+83
-3
lines changed

docs/source/usage.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ Usage
77
Resources
88
---------
99

10-
- A technical report explaining step-by-step on how to calculate distortion
11-
coefficients from a dot pattern image is available at `Zenodo <https://zenodo.org/record/1322720>`__.
10+
- A peer-reviewed paper describing the methods developed and implemented for Discorpy is available on
11+
`Journal of Synchrotron Radiation <https://doi.org/10.1107/S1600577525002267>`__.
1212
- Examples of how to use the package are in the "/examples" folder at the `github page <https://github.com/DiamondLightSource/discorpy/tree/master/examples>`__.
1313
- Coefficients determined by the package can be used by other tomographic
1414
software such as `Tomopy <https://tomopy.readthedocs.io/en/latest/api/tomopy.prep.alignment.html>`__,

examples/fisheye_calibration.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#============================================================================
2+
# Demonstration on how to calibrate a fisheye camera.
3+
# ============================================================================
4+
5+
import discorpy.losa.loadersaver as losa
6+
import discorpy.prep.preprocessing as prep
7+
import discorpy.prep.linepattern as lprep
8+
import discorpy.proc.processing as proc
9+
import discorpy.post.postprocessing as post
10+
import discorpy.util.utility as util
11+
12+
file_path = "../data/GoPro8_line_pattern.jpg"
13+
output_base = "E:/fisheye_correction"
14+
num_factor = 5
15+
16+
print("1-> Load image ...")
17+
img0 = losa.load_image(file_path)
18+
(height, width) = img0.shape
19+
img_norm = prep.normalization_fft(img0, 10)
20+
21+
print("2-> Calculate slope and distance between lines...")
22+
slope_hor, dist_hor = lprep.calc_slope_distance_hor_lines(img_norm, chessboard=False)
23+
slope_ver, dist_ver = lprep.calc_slope_distance_ver_lines(img_norm, chessboard=False)
24+
print(f" Horizontal slope: {slope_hor} Distance: {dist_hor}")
25+
print(f" Vertical slope : {slope_ver} Distance: {dist_ver}")
26+
print("3-> Extract reference-points !!!!")
27+
28+
# Detect points on lines, lines are dark, background is bright.
29+
list_points_hor_lines = lprep.get_cross_points_hor_lines(img_norm, slope_ver,
30+
dist_ver, bgr='bright',
31+
chessboard=False, radius=9,
32+
sensitive=0.1)
33+
list_points_ver_lines = lprep.get_cross_points_ver_lines(img_norm, slope_hor,
34+
dist_hor, bgr='bright',
35+
chessboard=False, radius=9,
36+
sensitive=0.1)
37+
# Optional: Remove unwanted points at image border
38+
list_points_hor_lines = prep.remove_points_using_parabola_mask(
39+
list_points_hor_lines, height, width, hor_curviness=0.4, ver_curviness=0.3,
40+
hor_margin=(400, 300), ver_margin=(150, 200))
41+
42+
list_points_ver_lines = prep.remove_points_using_parabola_mask(
43+
list_points_ver_lines, height, width, hor_curviness=0.4, ver_curviness=0.3,
44+
hor_margin=(400, 300), ver_margin=(150, 200))
45+
46+
print("4-> Group points into lines !!!!")
47+
list_hor_lines = prep.group_dots_hor_lines_based_polyfit(list_points_hor_lines,
48+
slope_hor, dist_hor,
49+
ratio=0.1, num_dot_miss=3,
50+
accepted_ratio=0.65, order=2)
51+
list_ver_lines = prep.group_dots_ver_lines_based_polyfit(list_points_ver_lines,
52+
slope_ver, dist_ver,
53+
ratio=0.1, num_dot_miss=3,
54+
accepted_ratio=0.65, order=2)
55+
list_hor_lines = prep.remove_residual_dots_hor(list_hor_lines, slope_hor, 3.0)
56+
list_ver_lines = prep.remove_residual_dots_ver(list_ver_lines, slope_ver, 3.0)
57+
58+
# Find center of distortion
59+
xcenter, ycenter = proc.find_center_based_vanishing_points_iteration(
60+
list_hor_lines, list_ver_lines, iteration=2)
61+
print(f"Center of distortion: X-center {xcenter}. Y-center {ycenter}")
62+
# Correct perspective distortion
63+
corr_hor_lines, corr_ver_lines = proc.correct_perspective_effect(
64+
list_hor_lines, list_ver_lines, xcenter, ycenter)
65+
# Calculate polynomial coefficients of the radial distortion
66+
list_bfact = proc.calc_coef_backward(corr_hor_lines, corr_ver_lines, xcenter,
67+
ycenter, num_factor)
68+
print(f"Polynomial coefficients of radial distortion: {list_bfact}")
69+
losa.save_metadata_json(output_base + "/distortion_parameters.json", xcenter,
70+
ycenter, list_bfact)
71+
72+
# Load calibration image as color image
73+
img0 = losa.load_image(file_path, average=False)
74+
img_corr = util.unwarp_color_image_backward(img0, xcenter, ycenter, list_bfact,
75+
pad=400)
76+
### Using OpenCV-remap backend for fast computing.
77+
# img_corr = util.unwarp_image_backward_cv2(img0, xcenter, ycenter,
78+
# list_bfact, pad=400)
79+
losa.save_image(output_base + "/corrected_img.jpg", img_corr)

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
long_description=README,
2828
long_description_content_type="text/markdown",
2929
keywords=['Distortion correction', 'Tomography', 'Radial lens distortion',
30-
'Camera calibration', 'Perspective distortion'],
30+
'Camera calibration', 'Perspective distortion',
31+
'Fisheye distortion'],
3132
url="https://github.com/DiamondLightSource/discorpy",
3233
download_url='https://github.com/DiamondLightSource/discorpy.git',
3334
license="Apache 2.0",

0 commit comments

Comments
 (0)