为什么 cv2.calibratecamera() 的性能随着图像的增多而急剧下降?

时间:2021-04-26 14:50:06

标签: python opencv image-processing computer-vision camera-calibration

我正在使用相机校准例程,我想校准具有大量图像的相机。

代码:(来自here

import numpy as np
import cv2
import glob
import argparse

# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)


def calibrate():
    height = 8
    width = 10
    """ Apply camera calibration operation for images in the given directory path. """
    # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(8,6,0)
    objp = np.zeros((height*width, 3), np.float32)
    objp[:, :2] = np.mgrid[0:width, 0:height].T.reshape(-1, 2)

    # Arrays to store object points and image points from all the images.
    objpoints = []  # 3d point in real world space
    imgpoints = []  # 2d points in image plane.

    # Get the images
    images = glob.glob('thermal_final set/*.png')

    # Iterate through the pairs and find chessboard corners. Add them to arrays
    # If openCV can't find the corners in an image, we discard the image.
    for fname in images:
        img = cv2.imread(fname)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        # Find the chess board corners
        ret, corners = cv2.findChessboardCorners(gray, (width, height), None)

        # If found, add object points, image points (after refining them)
        if ret:
            objpoints.append(objp)

            corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
            imgpoints.append(corners2)

            # Draw and display the corners
            # Show the image to see if pattern is found ! imshow function.
            img = cv2.drawChessboardCorners(img, (width, height), corners2, ret)

    e1 = cv2.getTickCount()

    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

    e2 = cv2.getTickCount()
    t = (e2 - e1) / cv2.getTickFrequency()

    print(t)


    return [ret, mtx, dist, rvecs, tvecs]


if __name__ == '__main__':

    ret, mtx, dist, rvecs, tvecs = calibrate()

    print("Calibration is finished. RMS: ", ret)

现在,问题是 cv2.calibratecamera() 花费的时间,基于使用的点数(从图像中得出)。

40 张图片的结果:

9.34462341234 seconds
Calibration is finished. RMS:  2.357820395255311

80 张图片的结果:

66.378870749 seconds
Calibration is finished. RMS:  2.864052963156834

花费的时间随着图像的增加呈指数增长。

现在,我有大量的图片(500 张)。

我曾尝试用单个图像中的点校准相机,然后计算我得到的所有结果的平均值,但它们与我从这种方法中得到的结果不同。

此外,我确定我的设置使用的是优化的 OpenCV,请使用以下方法检查:

print(cv2.useOptimized())

如何加快此过程?我可以在这里利用线程吗?

编辑:将概念和语言从“校准图像”更新为“使用图像校准相机”

1 个答案:

答案 0 :(得分:2)

首先,我强烈怀疑您显着放缓的原因与内存有关:您可能用完了并开始交换。

但是您似乎遵循的基本方法是不正确的。您不校准图像,而是校准相机,即镜头 + 传感器组合。

校准相机意味着估计该镜头+传感器包的数学模型的参数。因此,您只需要使用足够多的独立数据点即可在参数估计中达到所需的准确度。

如果您遵循精心设计的校准程序,在大多数情况下,几十张精心挑选的图像就足够了。前段时间我写了一些关于如何做这样的设计的技巧,你可以找到它们here