【问题标题】:Why is the performace of cv2.calibratecamera() decreasing drastically with more images?为什么 cv2.calibratecamera() 的性能会随着图像的增多而急剧下降?
【发布时间】:2021-07-19 23:00:19
【问题描述】:

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

代码:(来自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())

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

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

【问题讨论】:

  • 根据我的经验,超过 100 张图像,您不会再提高准确性。一个非常重要的方面实际上是实验设置,我对你的了解不多,但通常人们倾向于使用设计不佳的目标。此外,您必须注意光学参数对于给定的校准是恒定的。
  • @87VN0 我完全同意我不需要 500 多张图像,但我仍然想知道 VisionLib(也使用 OpenCV)如何能够为我提供即时结果。

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


【解决方案1】:

首先,我强烈怀疑您的速度急剧下降的原因与内存有关:您可能会用完并开始交换。

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

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

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

【讨论】:

  • 我实际上是想坚持你分享的我之前遇到的完全相同的帖子。我知道我可能会因为图像数量过多而过火,但我已经尝试过 VisionLib 的校准(使用 OpenCV),它们能够提供几乎即时的结果,包含 500 多张图像。我想复制一些类似的东西。
  • 我不怀疑这是可能的,我也对大型图像集进行了捆绑调整。我质疑这个特定用例的有用性:如果您的相机可以校准(意思是,它确实是时间不变的),并且您有一个专门的图像捕获步骤进行校准,那么使用 500 张图像,每张产生 100 点或所以,是极其多余的——绝大多数数据点可能是相关的。如果您控制图像捕获(例如,您正在匹配移动某些给定的镜头),那么情况就完全不同了。
  • 这是一个有用的见解。我的整个想法是获得 500 多张图像,这样如果一些图像具有较大的相对误差,数据量就会降低。另外,我不会控制图像捕获,将显示实时反馈图像以显示有多少相机的视野被图案覆盖(如 opencv 的交互式校准)。
猜你喜欢
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
  • 1970-01-01
  • 2012-08-25
  • 2021-05-06
  • 1970-01-01
  • 2014-01-29
  • 2020-01-31
相关资源
最近更新 更多