Калибровка RaspiCam с помощью OpenCV

2

Я пытаюсь откалибровать камеру объектива RaspiCam Fisheye с помощью OpenCV. Я использую пример кода Python, и номера строк и столбцов на шахматной доске также верны, но каким-то образом я не могу получить успешный результат. Я протестировал множество фотографий ниже, вы можете их увидеть. Мой исходный код: https://github.com/jagracar/OpenCV-python-tests/blob/master/OpenCV-tutorials/cameraCalibration/cameraCalibration.py

строки и столбцы моей шахматной доски: rows = 9, cols = 6

Изображение 174551

но не получает успешный результат

Изображение 174551

Изменение: мое решение

https://gist.github.com/mesutpiskin/0412c44bae399adf1f48007f22bdd22d

Теги:
opencv
camera-calibration
fisheye

2 ответа

3
Лучший ответ

Начиная с opencv 3, был введен модуль " fisheye ", который довольно хорошо управляет калибровкой линз типа "рыбий глаз". (По крайней мере, для тех, кто не знаком с математикой за процессом калибровки.)

# Checkboard dimensions
CHECKERBOARD = (6,9)
subpix_criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.1)
calibration_flags = cv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC + cv2.fisheye.CALIB_CHECK_COND + cv2.fisheye.CALIB_FIX_SKEW
objp = np.zeros((1, CHECKERBOARD[0]*CHECKERBOARD[1], 3), np.float32)
objp[0,:,: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.

### read images and for each image:
img = cv2.imread(fname)
img_shape = img.shape[:2]

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH+cv2.CALIB_CB_FAST_CHECK+cv2.CALIB_CB_NORMALIZE_IMAGE)
# If found, add object points, image points (after refining them)
if ret == True:
    objpoints.append(objp)
    cv2.cornerSubPix(gray,corners,(3,3),(-1,-1),subpix_criteria)
    imgpoints.append(corners)
###

# calculate K & D
N_imm = # number of calibration images
K = np.zeros((3, 3))
D = np.zeros((4, 1))
rvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(N_imm)]
tvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(N_imm)]
retval, K, D, rvecs, tvecs = cv2.fisheye.calibrate(
    objpoints,
    imgpoints,
    gray.shape[::-1],
    K,
    D,
    rvecs,
    tvecs,
    calibration_flags,
    (cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-6))

И теперь, когда у вас есть K и D, вы можете неуверенно:

img = # your image to undistort
map1, map2 = cv2.fisheye.initUndistortRectifyMap(K, D, np.eye(3), K, DIM, cv2.CV_16SC2)
undistorted_img = cv2.remap(img, map1, map2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)

это должно сработать!

ОБНОВЛЕНИЕ Изображение 174551

Если вы хотите увидеть скрытые части изображения (например, часть за пределами желтой рамки на изображении выше), после калибровки вам понадобится следующее:

img = cv2.imread(img_path)
img_dim = img.shape[:2][::-1]  

DIM = # dimension of the images used for calibration

scaled_K = K * img_dim[0] / DIM[0]  
scaled_K[2][2] = 1.0  
new_K = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(scaled_K, D,
    img_dim, np.eye(3), balance=balance)
map1, map2 = cv2.fisheye.initUndistortRectifyMap(scaled_K, D, np.eye(3),
    new_K, img_dim, cv2.CV_16SC2)
undist_image = cv2.remap(img, map1, map2, interpolation=cv2.INTER_LINEAR,
    borderMode=cv2.BORDER_CONSTANT)

Теперь, изменяя balance значение, вы должны уменьшить или увеличить размер финального изображения (по сравнению с изображением выше, практически желтый прямоугольник).

Из OpenCV API: balance: устанавливает новое фокусное расстояние в диапазоне между минимальным фокусным расстоянием и максимальным фокусным расстоянием. Баланс находится в диапазоне [0, 1].

  • 0
    У меня к тебе вопрос. Края изображения не появляются. Посмотрите на эту ссылку image.ibb.co/mg6dKd/Screenshot_2.png
  • 0
    Я обновил ответ!
Показать ещё 1 комментарий
2

Во-первых, насколько я вижу, у вашей камеры есть оптическая система рыбий глаз, но она не дает всей поверхности изображения рыбий глаз (обычно это круг внутри черной рамки). Второй. Код, который вы используете, предназначен для обычной камеры или широкоугольного (90-110 градусов). Это не для рыбий глаз (~ 180 градусов). В третьих. Вы можете использовать ссылку URL-адреса исходного кода из ЗДЕСЬ

  • 0
    привет спасибо за ответ это должно работать! но у меня есть проблема края изображения не появляются. Посмотрите на эту ссылку image.ibb.co/mg6dKd/Screenshot_2.png Характеристики моей камеры Диафрагма (F): 2,35 Поле зрения: 160 градусов Угол диагонали: 160 градусов Горизонтальный угол: 120 градусов

Ещё вопросы

Сообщество Overcoder
Наверх
Меню