无法使用OpenCv UnistrationPoints方法取消对点的扭曲

2024-10-01 07:37:24 发布

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

我尝试使用OpenCV的“不失真点”方法来取消对图像中某些点的失真,但没有成功。 Here an example where I undistort all the whole picture

这就是我的无变形系数

  optic_camera_matrix: [[710.52285,  0.0,      882.14702],
                        [0.0,        713.9636, 638.8421],
                        [0.0,        0.0,      1.0]],

  distorsion_coeffs: [[-0.4176419401669212,
                                 0.15978235598732332,
                                 -8.299875092923166e-05,
                                 -0.001784191694247801,
                                 -0.027396621999692457]],

即使我可以不失真整个图像,为了优化相机处理时间,如果我只对角点(图像的红色点)进行失真:

^{pr2}$

我得到的回报是:

[[[ -6.40190065e-01   1.66883194e+00]
  [ -4.87006754e-01  -2.88225353e-01]
  [ -1.82562262e-01   3.74070629e-02]
  [ -5.28450182e-04  -3.51850584e-04]
  [  8.09574544e-01  -8.40054870e-01]
  [ -5.28259724e-02  -1.22379906e-01]]]

如果打印,它们不会像第一幅图像那样在矩形中对齐。在

我相信无畸变系数计算得很好(因为无畸变作用于第一幅图像),但这里我附上了凸轮的代码

import glob
import cv2
import numpy as np
import os
import json
import numpy as np

directory = os.path.dirname(__file__)


def get_optic_calibration_parameters(device,config_folder=None):
    if config_folder is None:
        optic_calibration_path = directory + '/../config/' + \
            device + '/optic_calibration.json'
    else:
        optic_calibration_path = config_folder + device + '/optic_calibration.json'

    if not os.path.exists(optic_calibration_path):
        os.makedirs(optic_calibration_path[:-22])

    with open(optic_calibration_path) as optic_calibration_file:
        optic_calibration = json.load(optic_calibration_file)

    optic_camera_matrix = optic_calibration['optic_camera_matrix']
    distorsion_coeffs = optic_calibration['distorsion_coeffs']
    optic_resolution = optic_calibration['optic_resolution']

    return optic_camera_matrix, distorsion_coeffs, optic_resolution


def _save_calibration_parameters(camera_matrix, distorsion_coeffs, optic_resolution, device, config_folder=None):

    if config_folder is None:
        optic_calibration_path = directory + '/../config/' + \
            device + '/optic_calibration.json'
    else:
        optic_calibration_path = config_folder + device + '/optic_calibration.json'

    if not os.path.exists(optic_calibration_path):
        os.makedirs(optic_calibration_path[:-22])

    optic_calibration_parameters = {'optic_camera_matrix': camera_matrix.tolist(),
                                    'distorsion_coeffs': distorsion_coeffs.tolist(),
                                    'optic_resolution': optic_resolution}

    with open(optic_calibration_path, 'wb') as optic_calibration_file:
        json.dump(optic_calibration_parameters, optic_calibration_file)

    return


def _get_image_points(plot=False, dim=(4, 5), input_dir='calibration_samples',extension='jp'):
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

    # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
    objp = np.zeros((dim[0] * dim[1], 3), np.float32)
    objp[:, :2] = np.mgrid[0:dim[1], 0:dim[0]].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.

    images = glob.glob(input_dir + '*.'+extension+'*')
    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, (dim[1], dim[0]), None)

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

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

            # Draw and display the corners
            if plot:
                img = cv2.drawChessboardCorners(
                    img, (dim[1], dim[0]), corners2, ret)
                cv2.imshow('img', img)
                cv2.waitKey(500)

    resolution = (img.shape[1], img.shape[0])

    return imgpoints, objpoints, resolution


def calibrate_camera(optic_resolution, imgpoints, objpoints, device, config_folder=None):

    _, camera_matrix, distorsion_coeffs, _, _ = cv2.calibrateCamera(
        objpoints, imgpoints, optic_resolution, None, None)

    _save_calibration_parameters(
        camera_matrix, distorsion_coeffs, optic_resolution, device, config_folder=config_folder)

    return

要执行函数,我加载了不同的图像:

imgpoints, objpoints, optic_resolution = _get_image_points(plot=False, dim=(4,5), input_dir=calibration_samples)
_show_N_chessborders(N=3, dim=(4,5), input_dir=calibration_samples)
calibrate_camera(optic_resolution, imgpoints, objpoints,device, config_folder=config_folder)

这就是我存储json配置文件的方式

如果有人能帮我解决问题,我将不胜感激。谢谢您!在


Tags: pathnoneconfigjsondevicefoldercv2matrix
1条回答
网友
1楼 · 发布于 2024-10-01 07:37:24

如果我没弄错的话,getOptimalNewCameraMatrix函数只适用于当你不想在不失真整个图像时使用黑色的边(请参见this问题),而不适用于不失真单个点的情况。而且,似乎P和{}只适用于立体视觉。在

我会简化它,然后说:

undistorted_points =  cv2.undistortPoints(np.array(points), optical_camera_matrix, d) 

其中optical_camera_matrix是直接来自calibrateCamera函数的矩阵。只需确保points是一个^{}数组。在

更新:

我意识到了问题所在。{这句话的秘密是^。在

Also the function performs a reverse transformation to projectPoints()

据我所知(如果我错了,请纠正我)未失真的点是标准化的。为了将它们放回像素单位,只需执行以下操作(在伪代码中):

^{pr2}$

我希望这有帮助!在

相关问题 更多 >