Raspberry pi:calibrate camera and undistortion of

2019-09-17 19:57发布

问题:

I want to remove fisheye effect from image, so I need camera matrix and distortion cofficient. That's why I created cal.py file.

When I run that file it give me camera matrix and distortion efficient which I had put in undist.py file to undistort the image. now every time i got the same RMS,camera matrix,distortion coefficient.

but when i put this parameters in undist.py file that is give me blank image.. how to solve this problem?PLz help me...Thanks in advance.i have capture 8 image and one of the sample image of chessboard pattern.

回答1:

I will do an answer to summarize all the problems solved in the comments (this way the future readers do not have to read all of them).

  1. Follow the tutorial from here to have a better understanding of what you should do and which functions to use.

  2. Check that your camera matrix have the correct form:

    [ f_x  s    c_x
      0    f_y  c_y
      0    0    1  ]
    

    the s is a skew value that I think in opencv it always gives 0.

  3. Make sure in every step that the images are loading correctly and that they are doing exactly what is intended (use imshow function to debug)

  4. This part of your code

    newcamera, roi = cv2.getOptimalNewCameraMatrix(K, d, (w,h), 0)
    newimg = cv2.undistort(img, K, d, None, newcamera)
    

is faulty. Why, well from the opencv documentation we have that:

cv2.getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, alpha[, newImgSize[, centerPrincipalPoint]]) → retval, validPixROI

and

The function computes and returns the optimal new camera matrix based on the free scaling parameter. By varying this parameter, you may retrieve only sensible pixels alpha=0 , keep all the original image pixels if there is valuable information in the corners alpha=1 , or get something in between. When alpha>0 , the undistortion result is likely to have some black pixels corresponding to “virtual” pixels outside of the captured distorted image. The original camera matrix, distortion coefficients, the computed new camera matrix, and newImageSize should be passed to initUndistortRectifyMap() to produce the maps for remap() .

This means that the new camera matrix also gives you a new valid size!! To be more specifically:

the computed new camera matrix, and newImageSize should be passed to initUndistortRectifyMap()

But the undistort function does the initUndistortRectifyMap automatically.... and it doesn't have a way to pass the newImageSize from this function. So basically you have 2 options.

  1. Use your newcamera matrix, but instead of doing undistort, you should do everything manually.... this means that you must do initUndistortRectifyMap and remap using the new sizes and new camera matrix.
  2. Use the original camera matrix obtained in the calibrateCamera function. This way it will not have this zoom effect, but you may have some extra black pixels representing the areas that you may not see due to rectification.

If not, it will always give you this zoom effect, because it will not show the invalid pixels (black pixels) of the undistorted areas.