Skip to content

Commit 58c4a4e

Browse files
committed
Add demo, update doc
1 parent 1dab420 commit 58c4a4e

File tree

4 files changed

+117
-3
lines changed

4 files changed

+117
-3
lines changed

docs/source/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Discorpy's documentation
44
Discorpy is an open-source Python package implementing methods for calibrating and correcting distortion
55
in lens-based imaging systems :cite:`Vo:2015` :cite:`Vo:2025`. Unlike existing approaches that require multiple calibration
66
images or iterative optimization, Discorpy and its algorithms can independently characterize both radial and
7-
perspective distortion with high accuracy across a wide range of distortion strengthsusing only a single calibration
7+
perspective distortion with high accuracy across a wide range of distortion strengths - using only a single calibration
88
image and direct computation. This makes the software a practical tool for a wide range of imaging applications.
99

1010
To support different experimental conditions and enable fully automated workflows, Discorpy offers flexibility in

docs/source/technical_notes/fisheye_correction.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,9 @@ Using other types of calibration images
473473
---------------------------------------
474474

475475
Other types of calibration images can also be used and are straightforward to process using the Discorpy API.
476-
The following shows the results of using a chessboard image. Both the `image <https://github.com/DiamondLightSource/discorpy/tree/master/data/fisheye>`__
477-
and the `code <https://github.com/DiamondLightSource/discorpy/tree/master/examples>`__
476+
The following shows the results of using a chessboard image and a dot-pattern image.
477+
Both the `images <https://github.com/DiamondLightSource/discorpy/tree/master/data/fisheye>`__
478+
and the `codes <https://github.com/DiamondLightSource/discorpy/tree/master/examples>`__
478479
are available on the Discorpy GitHub page. As can be seen, the calibration image clearly has perspective
479480
distortion, but this is no longer a problem with the latest developments.
480481

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#==============================================================================
2+
# Demonstration on how to calibrate a fisheye camera using a dot-pattern image
3+
# =============================================================================
4+
5+
import numpy as np
6+
import discorpy.losa.loadersaver as losa
7+
import discorpy.prep.preprocessing as prep
8+
import discorpy.proc.processing as proc
9+
import discorpy.util.utility as util
10+
import matplotlib.pyplot as plt
11+
12+
13+
file_path = r"..\data\fisheye\GoPro8_dot_pattern.jpg"
14+
test_file_path = r"..\data\fisheye\GoPro8_testing_image.jpg"
15+
output_base = r"F:\tmp\fisheye_correction_dot_pattern"
16+
17+
print(" 1-> Load image ...")
18+
img0 = losa.load_image(file_path)
19+
(height, width) = img0.shape
20+
img_norm = prep.normalization_fft(img0, 10)
21+
22+
num_factor = 5
23+
mat1 = prep.binarization(img_norm, ratio=0.3)
24+
(dot_size, dist_dot) = prep.calc_size_distance(mat1, ratio=0.3)
25+
26+
print(" 2-> Calculate slope and distance between lines...")
27+
slope_hor = prep.calc_hor_slope(mat1, ratio=0.3)
28+
slope_ver = prep.calc_ver_slope(mat1, ratio=0.3)
29+
dist_hor = dist_ver = dist_dot
30+
print(f" Horizontal slope: {slope_hor} Distance: {dist_hor}")
31+
print(f" Vertical slope : {slope_ver} Distance: {dist_ver}")
32+
print(" 3-> Extract reference-points !!!!")
33+
34+
list_points = prep.get_points_dot_pattern(mat1, binarize=False)
35+
list_points_hor_lines = list_points
36+
list_points_ver_lines = np.copy(list_points)
37+
38+
hor_margin = (450, 100)
39+
ver_margin = (100, 100)
40+
list_points_hor_lines = prep.remove_points_using_parabola_mask(list_points_hor_lines,
41+
height, width,
42+
hor_curviness=0.4,
43+
ver_curviness=0.3,
44+
hor_margin=hor_margin,
45+
ver_margin=ver_margin)
46+
47+
list_points_ver_lines = prep.remove_points_using_parabola_mask(list_points_ver_lines,
48+
height, width,
49+
hor_curviness=0.4,
50+
ver_curviness=0.3,
51+
hor_margin=hor_margin,
52+
ver_margin=ver_margin)
53+
54+
# mask = prep.make_parabola_mask(height, width,hor_curviness=0.4, ver_curviness=0.3,
55+
# hor_margin=hor_margin, ver_margin=ver_margin)
56+
# plt.imshow(img_norm * mask, origin="lower")
57+
# plt.plot(list_points_hor_lines[:, 1], list_points_hor_lines[:, 0], ".", color="red")
58+
# plt.plot(list_points_ver_lines[:, 1], list_points_ver_lines[:, 0], ".", color="blue")
59+
# plt.show()
60+
61+
print(" 4-> Group points into lines !!!!")
62+
list_hor_lines = prep.group_dots_hor_lines_based_polyfit(list_points_hor_lines,
63+
slope_hor, dist_hor,
64+
ratio=0.1, num_dot_miss=3,
65+
accepted_ratio=0.65, order=2)
66+
list_ver_lines = prep.group_dots_ver_lines_based_polyfit(list_points_ver_lines,
67+
slope_ver, dist_ver,
68+
ratio=0.1, num_dot_miss=3,
69+
accepted_ratio=0.65, order=2)
70+
71+
list_hor_lines = prep.remove_residual_dots_hor(list_hor_lines, slope_hor, 2.0)
72+
list_ver_lines = prep.remove_residual_dots_ver(list_ver_lines, slope_ver, 2.0)
73+
74+
plt.imshow(img_norm, origin="lower")
75+
for line in list_hor_lines:
76+
plt.plot(line[:, 1], line[:, 0], "-o", color="red")
77+
plt.show()
78+
79+
plt.imshow(img_norm, origin="lower")
80+
for line in list_ver_lines:
81+
plt.plot(line[:, 1], line[:, 0], "-o", color="blue")
82+
plt.show()
83+
84+
# Find center of distortion
85+
xcenter, ycenter = proc.find_center_based_vanishing_points_iteration(
86+
list_hor_lines, list_ver_lines, iteration=2)
87+
print(f"Center of distortion: X-center {xcenter}. Y-center {ycenter}")
88+
89+
# Correct perspective distortion
90+
corr_hor_lines, corr_ver_lines = proc.correct_perspective_effect(
91+
list_hor_lines, list_ver_lines, xcenter, ycenter)
92+
93+
# Calculate polynomial coefficients of the radial distortion
94+
list_bfact = proc.calc_coef_backward(corr_hor_lines, corr_ver_lines, xcenter,
95+
ycenter, num_factor)
96+
print(f"Polynomial coefficients of radial distortion: {list_bfact}")
97+
losa.save_metadata_json(output_base + "/distortion_parameters.json", xcenter,
98+
ycenter, list_bfact)
99+
100+
# Load calibration image as color image
101+
img0 = losa.load_image(file_path, average=False)
102+
img_corr = util.unwarp_color_image_backward(img0, xcenter, ycenter, list_bfact,
103+
pad=400)
104+
### Using OpenCV-remap backend for fast computing.
105+
# img_corr = util.unwarp_image_backward_cv2(img0, xcenter, ycenter, list_bfact,
106+
# pad=400)
107+
losa.save_image(output_base + "/corrected_img.jpg", img_corr)
108+
109+
# Load another image for correction.
110+
img0 = losa.load_image(test_file_path, average=False)
111+
img_corr = util.unwarp_color_image_backward(img0, xcenter, ycenter, list_bfact,
112+
pad=400)
113+
losa.save_image(output_base + "/corrected_test_img.jpg", img_corr)
File renamed without changes.

0 commit comments

Comments
 (0)