从图像中消除失真(摄像机校准后)的问题

2024-06-02 00:41:29 发布

您现在位置:Python中文网/ 问答频道 /正文

{a1}是90分钟视频的单帧

如果从左上角(请参见,left-distorted)向右(请参见,right-distorted)绘制一条线,则通过查看顶线(请参见,middle-distorted)可以看到失真

左侧和右侧点之间的白线应该是直线,但与红色的直线相比,有一个轻微的U形

使用校准视频中的整帧样本(有关一些示例,请参见,indooroutdoor-1outdoor-2)使用open cv(reference)执行相机校准会生成此undistorted图像

这里,从左上角(参见,left-undistorted)到右(参见,right-undistorted)的线过度校正了失真,因为红线和白线之间的差异已经变成了倒U形(参见,middle-undistorted

我用iphone11录制了这段录音,我使用的是python3.8.8和opencv4.5.3

我遵循了StackOverflow上的建议(以及最流行的搜索结果),但使用任何棋盘格(大小、相机角度、距离和设置的变化)都无法纠正失真。我不明白为什么

更新:

根据以下对话,校准画面需要

  • 有一个焦点,类似于参考场景(在我的例子中,对象很遥远)
  • 电路板应至少覆盖图像的20%

这里是我使用的video(焦点固定在距离较远的物体上)来提取50帧的样本,以计算相机校准:

SQUARE_SIZE = 0.012
CHECKERBOARD_WIDTH = 22
CHECKERBOARD_HEIGHT = 15

objpoints = []
imgpoints = []

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
val = cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE
SAMPLE_SIZE = 50

objp = np.zeros((CHECKERBOARD_HEIGHT * CHECKERBOARD_WIDTH, 3), np.float32)
objp[:, :2] = np.mgrid[0:CHECKERBOARD_WIDTH, 0:CHECKERBOARD_HEIGHT.T.reshape(-1, 2)
objp = objp * SQUARE_SIZE

# for loop going over the sample of images
img = cv2.imread('path to image')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, (CHECKERBOARD_WIDTH[i], CHECKERBOARD_HEIGHT[i]), val)
if ret == True:
    objpoints.append(objp)
    # refining pixel coordinates for given 2d points.
    corners2 = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
    imgpoints.append(corners2)

# Calculate camera calibration
img = cv2.imread('path to reference image')
h,w = img.shape[:2]
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints,
                                                   imgpoints,
                                                   (w,h),
                                                   None,
                                                   None)                                          

newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))

# Undistort
mapx,mapy = cv2.initUndistortRectifyMap(mtx, dist, None, newcameramtx, (w,h), 5)
dst = cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)
cv2.imwrite('path to output image', dst)

不幸的是result不正确,如音高顶部红白线的偏差所示


Tags: imgsizewidthcv2校准cbheightcalib