From 5b8a98e65b3e6287f6c1060de7986c66ddee7e02 Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Fri, 10 Oct 2025 16:25:10 +0200 Subject: [PATCH] Tweaks for convenience --- 00-find-corners.py | 24 +++++++++++++++++++----- 01-calibrate.py | 27 ++++++++++++++++++--------- 02-testcalibration-and-draw-points.py | 21 +++++++++++++++------ 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/00-find-corners.py b/00-find-corners.py index 2b5a5d6..93f57ff 100644 --- a/00-find-corners.py +++ b/00-find-corners.py @@ -12,6 +12,7 @@ Usage: ''' + from pathlib import Path import numpy as np import cv2 @@ -19,13 +20,21 @@ import json import tqdm import math -dataset = Path('hof3-cam-baumer') - +# SETTINGS: +CALIB_FISHEYE = True # set needed detections. Use math.inf to scan the whole video needed_detections = math.inf # 20 - # Defining the dimensions of checkerboard CHECKERBOARD = (6,9) +CROPPED_HEIGHT = None # 1520 + +dataset = Path('hof3-cam-baumer-cropped') +videofile = dataset / "chessboard.mp4" + +# ----- +# END OF SETTINGS + +snapshot_file = videofile.with_name(videofile.stem + '_snapshot.png') # termination criteria criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) @@ -39,7 +48,6 @@ objp[:,:2] = np.mgrid[0:CHECKERBOARD[0],0:CHECKERBOARD[1]].T.reshape(-1,2) objpoints = [] # 3d point in real world space imgpoints = [] # 2d points in image plane. -videofile = dataset / "chessboard7.mp4" cap = cv2.VideoCapture(videofile) frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) @@ -56,11 +64,17 @@ p2 = tqdm.tqdm(total=needed_detections) first_found=False no_frames_for = 0 +needs_snapshot = not snapshot_file.exists() + while ((found < needed_detections) if math.isfinite(needed_detections) else True): ret, img = cap.read() # Capture frame-by-frame if not ret: break + if needs_snapshot: + cv2.imwrite(snapshot_file, img) + needs_snapshot = False + p.update() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) @@ -98,5 +112,5 @@ cv2.destroyAllWindows() print(f"Found {found} detections") -np.savez(dataset / "chessboard7-points.npz", objpoints=objpoints, imgpoints=imgpoints) +np.savez(videofile.with_name(videofile.stem+'-points.npz') , objpoints=objpoints, imgpoints=imgpoints) diff --git a/01-calibrate.py b/01-calibrate.py index d0d5c11..c38a336 100644 --- a/01-calibrate.py +++ b/01-calibrate.py @@ -20,18 +20,21 @@ import json import tqdm import math +# SETTINGS: CALIB_FISHEYE = True - -dataset = Path('hof3-cam-baumer') - # set needed detections. Use math.inf to scan the whole video needed_detections = math.inf # 20 - # Defining the dimensions of checkerboard CHECKERBOARD = (6,9) +CROPPED_HEIGHT = None # 1520 -CROPPED_HEIGHT = 1520 +dataset = Path('hof3-cam-baumer-cropped') +videofile = dataset / "chessboard.mp4" +# ----- +# END OF SETTINGS + +snapshot_file = videofile.with_name(videofile.stem + '_snapshot.png') # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0) if not CALIB_FISHEYE: @@ -46,7 +49,7 @@ else: objpoints = [] # 3d point in real world space imgpoints = [] # 2d points in image plane. -videofile = dataset / "chessboard7.mp4" + cap = cv2.VideoCapture(videofile) _, img = cap.read() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) @@ -60,7 +63,7 @@ dim = { } -loaded = np.load(dataset / "chessboard-points.npz") +loaded = np.load(videofile.with_name(videofile.stem+'-points.npz') ) objpoints, imgpoints = loaded['objpoints'], loaded['imgpoints'] print(f"Calculating matrixes with {len(objpoints)} detections") @@ -120,8 +123,12 @@ else: if not dim2: dim2 = dim1 if not dim3: - dim3 = dim1 - dim3 = (dim1[0], CROPPED_HEIGHT) + if CROPPED_HEIGHT: + dim3 = (dim1[0], CROPPED_HEIGHT) + else: + dim3 = dim1 + + scaled_K = K * dim1[0] / DIM[0] # The values of K is to scale with image dimension. scaled_K[2][2] = 1.0 # Except that K[2][2] is always 1.0 # This is how scaled_K, dim2 and balance are used to determine the final K used to un-distort image. OpenCV document failed to make this clear! @@ -172,5 +179,7 @@ else: # img2 = cv2.imread("2.png") # cv2.imshow("none undistorted", img2) cv2.waitKey(0) + # while cv2.waitKey(0) != ord('q'): + # pass cv2.destroyAllWindows() diff --git a/02-testcalibration-and-draw-points.py b/02-testcalibration-and-draw-points.py index 2490c43..88170f6 100644 --- a/02-testcalibration-and-draw-points.py +++ b/02-testcalibration-and-draw-points.py @@ -9,6 +9,7 @@ used for the homography later. this allows for more precise point placement, but might need some conversion in the next step 3. Points are read and saved from points.json in the dataset folder """ +from pathlib import Path import cv2 import json import os @@ -16,11 +17,19 @@ import numpy as np from load_calibration import load_calibration -dataset = 'hof3-cam-baumer' -snapshot_img = 'snapshot.png' -points_fname = dataset + '/points.json' +# SETTINGS + +dataset = Path('hof3-cam-baumer-cropped') +videofile = dataset / 'chessboard.mp4' +points_fname = dataset / 'points.json' + +# END SETTINGS + +w, h, undistorted_img, undistort_points = load_calibration(dataset / "calibration.json") + + +snapshot_file = videofile.with_name(videofile.stem + '_snapshot.png') -w, h, undistorted_img, undistort_points = load_calibration(dataset + "/fisheye_calibration_data.json") # with open(dataset + '/calibration-chessboard4.json', 'r') as fp: # with open(dataset + '/calibration-chessboard4.json', 'r') as fp: @@ -36,7 +45,7 @@ def add_point(event,x,y,flags,param): selected = None for i, p in enumerate(points): d = (p[0]-x)**2 + (p[1]-y)**2 - if d < 14: + if d < 25: selected = i break print('click', selected) @@ -52,7 +61,7 @@ cv2.namedWindow('original image') cv2.setMouseCallback('original image',add_point) # cap = cv2.VideoCapture("./hof2-hikvision.mp4") -cap = cv2.VideoCapture(dataset + "/" + snapshot_img) +cap = cv2.VideoCapture(snapshot_file) img_w = cap.get(cv2.CAP_PROP_FRAME_WIDTH) img_h = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)