【问题标题】:Undistortion crops the image and distort edges不失真裁剪图像并扭曲边缘
【发布时间】:2019-10-25 23:38:14
【问题描述】:

我正在尝试校准鱼眼相机的图像并使其不失真。
我的代码是:

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)

它给出了以下图像: undistorted image

虽然原始图像是: original image

中心似乎没有失真,但角落被扭曲并且图像本身被裁剪。 我不确定校准过程是否正确。如果有人对此有经验,如果您查看代码并可能发现错误,我会很高兴。

【问题讨论】:

  • 裁剪是不可避免的,因为图像的边缘在不失真后将不完整。您无法恢复从未捕获的图像部分。

标签: python opencv camera-calibration


【解决方案1】:

快速回答:校准错误。您的未失真图像是使用(非常)错误的内在函数和失真系数获得的。

抱歉,我没有调试您的代码,但代码可以正常工作,但仍然没有得到正确的校准。并非一切都是代码:您必须选择有用的棋盘姿势和许多图像来改进校准。

建议:通过鱼眼校准,开始尝试仅获取内在函数(相机中心和焦点),避免计算失真系数。

【讨论】:

  • 谢谢。我有 16 张图片。相机是固定的,我只移动棋盘图像。
猜你喜欢
  • 1970-01-01
  • 2018-07-02
  • 2016-08-29
  • 1970-01-01
  • 1970-01-01
  • 2022-08-04
  • 1970-01-01
  • 2017-11-07
  • 2022-01-02
相关资源
最近更新 更多