Недискажение обрезает изображение и искажает края - PullRequest
0 голосов
/ 25 октября 2019

Я пытаюсь откалибровать и отменить искажение изображения с камеры типа «рыбий глаз».
Мой код:

import cv2
import os
import numpy as np

CHECKERBOARD = (5,7)
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
R = np.zeros((1, 1, 3), dtype=np.float64)
T = np.zeros((1, 1, 3), dtype=np.float64)
objp = np.zeros( (CHECKERBOARD[0]*CHECKERBOARD[1], 1, 3) , np.float64)
objp[:,0, :2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)
_img_shape = None
objpoints = [] # 3d point in real world space
imgpoints = []

N_OK = len(objpoints)

images = os.listdir('./images/')

for fname in images:
    img = cv2.imread(fname)
    img = cv2.imread('./images/'+fname)
    #print(fname + str(os.path.exists('./images/'+fname)))
    ext = os.path.splitext(fname)[-1].lower()
    if ext == ".jpg":
        print(img.shape[:2])
        if _img_shape == None:
            _img_shape = img.shape[:2]
        else:
            assert _img_shape == img.shape[:2], "All images must share the same size."

        gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
        ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD,cv2.CALIB_CB_ADAPTIVE_THRESH+cv2.CALIB_CB_FAST_CHECK+cv2.CALIB_CB_NORMALIZE_IMAGE)
        if ret == True:
            objpoints.append(objp)
            cv2.cornerSubPix(gray,corners,(3,3),(-1,-1),subpix_criteria)
            imgpoints.append(corners)

N_OK = len(objpoints)
K = np.zeros((3, 3))
D = np.zeros((4, 1))
rvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(N_OK)]
tvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(N_OK)]
rms, 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)
    )

DIM=_img_shape[::-1]
K=np.array(K.tolist())
D=np.array(D.tolist())

И функция для удаления искажения:

def undistort(img_path):    
    img = cv2.imread(img_path)
    h,w = img.shape[:2]    
    nk = K.copy()
    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)    
    cv2.imwrite('calibresult1.png',undistorted_img)

Это даетследующее изображение: неискаженное изображение

Исходное изображение: исходное изображение

Центр выглядит неискаженным, но углы искажены и само изображениеобрезается. Я не уверен, что процесс калибровки правильный. Если у кого-то есть опыт работы с ним, я был бы рад, если вы посмотрите на код и, возможно, найдете ошибки.

1 Ответ

0 голосов
/ 25 октября 2019

Быстрый ответ: плохая калибровка. Ваше неискаженное изображение было получено с (очень) неправильными характеристиками и коэффициентами искажения.

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

Рекомендация: с калибровкой «рыбий глаз», начните пытаться получить только внутренние характеристики (центр камеры и фокус) и избегайте вычисления коэффициентов искажения.

...