【问题标题】:Python: OpenCV: How to get an undistorted image without the cropping?Python:OpenCV:如何在不裁剪的情况下获得不失真的图像?
【发布时间】:2020-11-05 10:39:49
【问题描述】:

这类似于 nkint 在 2013 年 9 月 11 日提出的问题。链接在这里: how to get all undistorted image with opencv 我是新用户,所以我没有足够的声誉/影响力来评论 OP。

我尝试使用 Python 而不是 C++ 来模拟 andrewmkeller 发布的代码,并根据 Josh Bosch 的回复进行了一些细微的更改。结果如下:

  #!/usr/bin/env python

  import cv2
  import numpy as np

  def loadUndistortedImage(fileName):
      # load image
      image = cv2.imread(fileName)
      #print(image)

      # set distortion coeff and intrinsic camera matrix (focal length, centerpoint offset, x-y skew)
      cameraMatrix = np.array([[894.96803896,0,470.38713516],[0,901.32629374,922.41232898], [0,0,1]])
      distCoeffs = np.array([[-0.340671222,0.110426603,-.000867987573,0.000189669273,-0.0160049526]])

      # setup enlargement and offset for new image
      y_shift = 60    #experiment with
      x_shift = 70    #experiment with    
      imageShape = image.shape  #image.size
      print(imageShape)
      imageSize = (int(imageShape[0])+2*y_shift, int(imageShape[1])+2*x_shift, 3)
      print(imageSize)
    
      # create a new camera matrix with the principal point offest according to the offset above
      newCameraMatrix, validPixROI = cv2.getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize,
        1)
      #newCameraMatrix = cv2.getDefaultNewCameraMatrix(cameraMatrix, imageSize, True) # imageSize, True

      # create undistortion maps
      R = np.array([[1,0,0],[0,1,0],[0,0,1]])
      map1, map2 = cv2.initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, imageSize,
        cv2.CV_16SC2)

      # remap
      outputImage = cv2.remap(image, map1, map2, INTER_LINEAR)
      #save output image as file with "FIX" appened to name - only works with .jpg files at the moment
      index = filename.find('.jpg')
      fixed_filename = filename[:index] +'_undistorted'+fileName[index:]
      cv2.imwrite(fixed_filename, outputImage)
      cv2.imshow('fix_img',outputImage)
      cv2.waitKey(0)
      return
    
  #Undistort the images, then save the restored images
  loadUndistortedImage('./calib/WIN_20200626_11_29_16_Pro.jpg')

这对我来说似乎很好,但是在尝试使用 cv2.getOptimalNewCameraMatrix 或 cv2.getDefaultNewCameraMatrix 和 cv2.initUndistortRectifyMap 时出现了问题。我一直被告知“该参数恰好需要 2 个参数(给定 3 个)”,即使我将参数放置在其文档中指定的位置: https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html

如果我删除可选参数,我可以从“...getDefault...”中删除错误,但我宁愿不这样做。

堆栈跟踪:

Traceback (most recent call last):
  File ".\main.py", line 46, in <module>
    loadUndistortedImage('./<image file name>.jpg')
  File ".\main.py", line 27, in loadUndistortedImage
    newCameraMatrix, validPixROI = cv2.getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1)
TypeError: function takes exactly 2 arguments (3 given)

【问题讨论】:

  • 欢迎来到 Stack Overflow。发布您收到的错误的完整回溯可能会有所帮助。
  • @Ronald 完成,先生

标签: python opencv


【解决方案1】:

我没有足够的声誉来发表评论,但你可以试试:

newcameramatrix, _ = cv2.getOptimalCameraMatrix(
    camera_matrix, dist_coeffs, (width, height), 1, (width, height)
)

根据this,函数应该是这样调用的。

现在,您可以这样做:

undistorted_image = cv2.undistort(
    image, camera_matrix, dist_coeffs, None, newcameramatrix
)
cv2.imshow("undistorted", undistorted_image)

【讨论】:

  • 这就是票!堆栈跟踪抱怨参数中的参数,即 getOptimalNew.. 和 initUndistort... 的 imageSize 参数。这些函数查找传递的 imageSize 参数,该参数是 2 个对象的元组,而我传递的 imageSize 是 3 个对象的元组。我的输出图像仍然有点古怪,所以在我用修改后的代码编辑我的帖子之前,我会做更多的调整。
【解决方案2】:

在我对 Sebastian Liendo 的回答发表评论之后,还要感谢 Github 上的芬兰回复者(我了解到,他们的问题不是针对此类一般性问题),这里是 1)python 函数的更新文档, 2)我修改后的代码的核心,它在绕过裁剪方面做得不错。 (不要做我在问题中所做的并发布整个代码,只是对您的问题至关重要的部分。)

  1. https://docs.opencv.org/4.3.0/d9/d0c/group_calib3d.html#ga7a6c4e032c97f03ba747966e6ad862b1

  2. #加载图片 图像 = cv2.imread(文件名) #images = glob.glob(pathName + '*.jpg') #在指定目录内循环 #for 图像中的文件名: #image = cv2.imread(文件名)

    #设置相机参数 高度,宽度 = image.shape[:2] cameraMatrix = np.array([[894.96803896,0,470.38713516],[0,901.32629374,922.41232898], [0,0,1]]) distCoeffs = np.array([[-0.340671222,0.110426603,-.000867987573,0.000189669273,-0.0160049526]])

    #创建新的相机矩阵 newCameraMatrix, validPixROI = cv2.getOptimalNewCameraMatrix(cameraMatrix, distCoeffs,(width, height), 1, (width, height))

    #undistort outputImage = cv2.undistort(image, cameraMatrix, distCoeffs, None, newCameraMatrix)

    #crop,修改 x, y, w, h = validPixROI #(211, 991, 547, 755) outputImage = outputImage[y-200:y+h+200, x-40:x+w+80] #fudge 因子以最小化裁剪

唯一的警告:此代码仍然裁剪了原始捕获的一些外部修剪,但幅度不大。最小化裁剪是我在 ouputImage = outputImage[...] 行中添加软糖因子的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    • 2020-05-20
    相关资源
    最近更新 更多