Python:OpenCV:如何在不进行裁剪的情况下获得不失真的图像?

2024-09-28 21:36:07 发布

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

这与2013年9月11日nkint的问题类似。链接如下: how to get all undistorted image with opencv 我是一个新用户,所以我没有足够的声誉/影响力对OP发表评论

我曾尝试用Python代替C++来模拟代码安德鲁麦克勒,其中一些基于Joh博世的响应的小改动。结果如下:

  #!/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.GetOptimizeNewCameraMatrix或cv2.getDefaultNewCameraMatrix和cv2.InitUnderTortyMap时出现了问题。我一直被告知“该参数正好包含2个参数(3个给定)”,尽管我在此处输入了文档中指定的参数: https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.htmlhttps://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)

Tags: theimage参数shiftwithnpfilenamecv2
2条回答

继我对Sebastian Liendo的回答发表评论之后,还要感谢Github上的一位芬兰回复者(据我所知,他的问题不是针对这些一般性问题),这里是1)python函数的更新文档,以及2)我修订代码的核心,它很好地解决了裁剪问题。(不要像我在问题中所做的那样发布整个代码,只发布你问题的关键部分。)

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

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

    #设置摄像机参数 高度,宽度=图像。形状[:2] cameraMatrix=np.数组([894.96803896,0470.38713516],[0901.32629374922.41232898],[0,0,1]) distcoefs=np.数组([-0.34067222,0.110426603,-.000867987573,0.000189669273,-0.0160049526]]

    #创建新的相机矩阵 newCameraMatrix,validPixROI=cv2.GetOptimizeNewCameraMatrix(cameraMatrix,distcoefs,(宽度,高度),1,(宽度,高度))

    #不受干扰 outputImage=cv2.不失真(图像、cameraMatrix、DistCoefs、None、newCameraMatrix)

    #作物,改良 x、 y,w,h=validPixROI#(211991547755) outputImage=outputImage[y-200:y+h+200,x-40:x+w+80]#最大限度减少裁剪的模糊因子

有一点需要注意:这段代码仍然保留了原始捕获的一些外部修饰,但没有太多。最小化裁剪是我在ouputImage=outputImage[…]行中添加模糊因子的原因

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

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

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

现在,您不必使用cv2.initUndistortRectifyMap获取未失真的图像,只需执行以下操作:

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

相关问题 更多 >