Can Günen
commited on
Commit
·
858a6b3
1
Parent(s):
1f7d2a8
added distortion correction
Browse files- app.py +20 -6
- distortion.py +72 -0
app.py
CHANGED
@@ -1,8 +1,17 @@
|
|
1 |
import numpy as np
|
2 |
import gradio as gr
|
|
|
|
|
|
|
|
|
|
|
3 |
|
4 |
coords = [[0,0]]
|
5 |
|
|
|
|
|
|
|
|
|
6 |
|
7 |
SHARED_UI_WARNING = f'''##### Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tempus dignissim odio, at elementum erat vulputate sit amet. Vestibulum sodales viverra fermentum. In ac hendrerit dolor, vitae mattis odio. Maecenas suscipit consectetur suscipit. Curabitur sodales dui eget neque venenatis tincidunt. In sed libero mi. Nam sollicitudin metus urna, sit amet sagittis ex laoreet sed.
|
8 |
|
@@ -44,13 +53,18 @@ with gr.Blocks() as demo:
|
|
44 |
with gr.Tab("O-Matrix"):
|
45 |
with gr.Row():
|
46 |
with gr.Column():
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
|
|
|
|
52 |
|
53 |
|
|
|
|
|
|
|
54 |
|
55 |
|
56 |
-
demo.launch()
|
|
|
1 |
import numpy as np
|
2 |
import gradio as gr
|
3 |
+
from distortion import main
|
4 |
+
import os
|
5 |
+
|
6 |
+
|
7 |
+
|
8 |
|
9 |
coords = [[0,0]]
|
10 |
|
11 |
+
import gradio as gr
|
12 |
+
import cv2
|
13 |
+
|
14 |
+
|
15 |
|
16 |
SHARED_UI_WARNING = f'''##### Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tempus dignissim odio, at elementum erat vulputate sit amet. Vestibulum sodales viverra fermentum. In ac hendrerit dolor, vitae mattis odio. Maecenas suscipit consectetur suscipit. Curabitur sodales dui eget neque venenatis tincidunt. In sed libero mi. Nam sollicitudin metus urna, sit amet sagittis ex laoreet sed.
|
17 |
|
|
|
53 |
with gr.Tab("O-Matrix"):
|
54 |
with gr.Row():
|
55 |
with gr.Column():
|
56 |
+
distorted_image = gr.Image(label="Selected Image", type="filepath")
|
57 |
+
|
58 |
+
with gr.Row():
|
59 |
+
chess_vert_input = gr.Textbox(label="Enter the number of squares in vertical direction")
|
60 |
+
chess_horz_input = gr.Textbox(label="Enter the number of squares in horizontal direction")
|
61 |
+
download_dxf = gr.Button("Generate the YAML File")
|
62 |
+
yaml_file = gr.File()
|
63 |
|
64 |
|
65 |
+
download_dxf.click(main, inputs=[distorted_image, chess_vert_input, chess_horz_input], outputs= yaml_file)
|
66 |
+
with gr.Column():
|
67 |
+
gr.Markdown(SHARED_UI_WARNING)
|
68 |
|
69 |
|
70 |
+
demo.launch(debug=True)
|
distortion.py
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import cv2
|
2 |
+
import numpy as np
|
3 |
+
from pathlib import Path
|
4 |
+
|
5 |
+
|
6 |
+
def save_coefficients(mtx, dist, path):
|
7 |
+
"""Save camera matrix and distortion coefficients to file."""
|
8 |
+
cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_WRITE)
|
9 |
+
cv_file.write('K', mtx)
|
10 |
+
cv_file.write('D', dist)
|
11 |
+
cv_file.release()
|
12 |
+
|
13 |
+
|
14 |
+
def load_coefficients(path):
|
15 |
+
"""Load camera matrix and distortion coefficients from file."""
|
16 |
+
cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_READ)
|
17 |
+
camera_matrix = cv_file.getNode('K').mat()
|
18 |
+
dist_matrix = cv_file.getNode('D').mat()
|
19 |
+
cv_file.release()
|
20 |
+
return [camera_matrix, dist_matrix]
|
21 |
+
|
22 |
+
|
23 |
+
def main(filename, board_vert, board_horz):
|
24 |
+
"""Main function to calibrate camera and undistort image."""
|
25 |
+
|
26 |
+
filename_stem = Path(filename).stem
|
27 |
+
|
28 |
+
# Define the checkerboard pattern size and criteria for corner detection
|
29 |
+
CHECKERBOARD = (int(board_vert), int(board_horz))
|
30 |
+
#CHECKERBOARD = (9, 7)
|
31 |
+
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
|
32 |
+
|
33 |
+
# Initialize object points and image points arrays
|
34 |
+
object_points = [] # 3D points in real world space
|
35 |
+
image_points = [] # 2D points in image plane
|
36 |
+
|
37 |
+
# Create the object points for the chessboard corners
|
38 |
+
objectp3d = np.zeros((1, CHECKERBOARD[0] * CHECKERBOARD[1], 3), np.float32)
|
39 |
+
objectp3d[0, :, :2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)
|
40 |
+
|
41 |
+
# Load the image and convert to grayscale
|
42 |
+
image = cv2.imread(filename)
|
43 |
+
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
44 |
+
|
45 |
+
# Find chessboard corners
|
46 |
+
ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH
|
47 |
+
+ cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE)
|
48 |
+
|
49 |
+
# If corners found, add object points and image points to arrays
|
50 |
+
if ret:
|
51 |
+
object_points.append(objectp3d)
|
52 |
+
corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
|
53 |
+
image_points.append(corners2)
|
54 |
+
image = cv2.drawChessboardCorners(image, CHECKERBOARD, corners2, ret)
|
55 |
+
|
56 |
+
# Calibrate camera using object points and image points
|
57 |
+
h, w = gray.shape[:2]
|
58 |
+
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(object_points, image_points, gray.shape[::-1], None, None)
|
59 |
+
|
60 |
+
# Save camera matrix and distortion coefficients to file
|
61 |
+
save_coefficients(mtx, dist, f"{filename_stem}.yml")
|
62 |
+
|
63 |
+
# Load camera matrix and distortion coefficients from file
|
64 |
+
mtx, dist = load_coefficients(f'{filename_stem}.yml')
|
65 |
+
|
66 |
+
# Undistort the original image using camera matrix and distortion coefficients
|
67 |
+
original = cv2.imread(filename)
|
68 |
+
dst = cv2.undistort(original, mtx, dist, None, None)
|
69 |
+
|
70 |
+
# Save the undistorted image
|
71 |
+
cv2.imwrite(f'undist_{filename_stem}.jpg', dst)
|
72 |
+
return f"{filename_stem}.yml"
|