Closed williamhyin closed 2 years ago
Hi @williamhyin! You should have prepared the input like this (supposing the first camera is in the origin):
# Calibration data
A1 = np.array([[258.13781734, 0., 954.22342933], [0., 258.11148133, 543.9914898], [0., 0., 1.]]) # Left camera intrinsic matrix
A2 = np.array([[1.67048218e+03, 0.00000000e+00, 9.49693383e+02],[0.00000000e+00, 1.86404224e+03, 5.41460911e+02],[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) # Right camera intrinsic matrix
RT1 = np.array([[ 1, 0, 0, 0], # Left extrinsic parameters
[0,1,0,0],
[0,0,1,0]])
RT2 = np.array([[ 0.99938327, -0.01944831, -0.02923759 , 0.01480007 ], # Right extrinsic parameters
[ 0.00775487, 0.93429903, -0.35640594, -0.58130264],
[0.03424814, 0.3559594, 0.93387364, -1.53172435]])
Is it right? Please share the two camera resolutions and maybe the images (in original resolution) too, so I can run the code and double check you results.
If I interpreted the above correctly, the camera 2 is located in [-0.07088022, -0.00291994, 1.63685026], with a baseline of ~1.638. It seems like a vertical stereo setup to me, then this should be the problem. In this case you should consider the x-axis as vertical, the y-axis as horizontal (z-axis is still going outwards the camera). In other words, you should "tilt you head by 90°".
In fact, the algorithm is considered first for horizontal stereo rig:
But nothing prevents you to rotate everything and use it vertically. In order to do this, you must rotate your images and swap the x and y values in the calibration. It's maybe easier to redo calibration with rotated images.
The algorithm ensures the minimal possible distortion for that setup (this doesn't mean that there is no distortion). You don't have to rescale nor modify any value from calibration.
Extra comment about vertical stereo rig.
If you have a vertical stereo setup, your epipolar lines would be like the following red lines (representative):
Now, since rectification means to make all the epipolar lines horizontal (same y-coordinate), you are implicitly telling to distort the image so much to achieve this. While if you tilt your head by 90° you can see that the rectification can be achieved with much less distortion.
Hope that this representative example helps to understand.
Hi @williamhyin! You should have prepared the input like this (supposing the first camera is in the origin):
# Calibration data A1 = np.array([[258.13781734, 0., 954.22342933], [0., 258.11148133, 543.9914898], [0., 0., 1.]]) # Left camera intrinsic matrix A2 = np.array([[1.67048218e+03, 0.00000000e+00, 9.49693383e+02],[0.00000000e+00, 1.86404224e+03, 5.41460911e+02],[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) # Right camera intrinsic matrix RT1 = np.array([[ 1, 0, 0, 0], # Left extrinsic parameters [0,1,0,0], [0,0,1,0]]) RT2 = np.array([[ 0.99938327, -0.01944831, -0.02923759 , 0.01480007 ], # Right extrinsic parameters [ 0.00775487, 0.93429903, -0.35640594, -0.58130264], [0.03424814, 0.3559594, 0.93387364, -1.53172435]])
Is it right? Please share the two camera resolutions and maybe the images (in original resolution) too, so I can run the code and double check you results.
If I interpreted the above correctly, the camera 2 is located in [-0.07088022, -0.00291994, 1.63685026], with a baseline of ~1.638. It seems like a vertical stereo setup to me, then this should be the problem. In this case you should consider the x-axis as vertical, the y-axis as horizontal (z-axis is still going outwards the camera). In other words, you should "tilt you head by 90°".
In fact, the algorithm is considered first for horizontal stereo rig:
But nothing prevents you to rotate everything and use it vertically. In order to do this, you must rotate your images and swap the x and y values in the calibration. It's maybe easier to redo calibration with rotated images.
The algorithm ensures the minimal possible distortion for that setup (this doesn't mean that there is no distortion). You don't have to rescale nor modify any value from calibration.
#left: resolution: origin(2880*1956) alrealy undistort to 1920*1080
A1 = np.array([[258.13781734, 0., 954.22342933],
[0., 258.11148133, 543.9914898],
[0., 0., 1.]])
RT1 = np.array([[8.2937910687219969e-03, 4.4054654421143952e-01, -8.9769145891729785e-01, -1.1221412033580425e+00],
[9.9988425750439414e-01, 7.7970227576761942e-03, 1.3064380237974873e-02, -3.7819088840089776e-03],
[1.2754788300653771e-02, -8.9769591110769498e-01, -4.4043088737727182e-01, 9.8368441356520508e-02],
[0., 0., 0., 1.]])
#right: resolution: origin(1920*1080) alrealy undistort to 1920*1080
A2 = np.array([[1.67048218e+03, 0.00000000e+00, 9.49693383e+02],
[0.00000000e+00, 1.86404224e+03, 5.41460911e+02],
[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) # Right camera intrinsic matrix
RT2 = np.array([[2.5967122092114721e-02, 7.3160908917485468e-01, -6.8122965966478066e-01, -1.7406952838516740e+00],
[9.9873399225065906e-01, 1.0382500507625871e-02, 4.9220081331396069e-02, 6.2863733933315610e-02],
[4.3082726159254334e-02, -6.8164532149788049e-01, -7.3041326274016827e-01, -1.4173031888024112e+00],
[0., 0., 0., 1.]])
#right to left:
RT = np.array([[9.9938327322281428e-01, 7.7548699688642763e-03, 3.4248141471031855e-02, 4.2175700000000003e-02],
[-1.9448309545294230e-02, 9.3429902647673801e-01, 3.5595939709530083e-01, 1.0886300000000000e+00],
[-2.9237586396353276e-02, -3.5640593586020092e-01, 9.3387363836084925e-01, 1.2236899999999999e+00],
[0., 0., 0., 1.]])
#left to right:
RT = np.array([[ 0.99938327, -0.01944831, -0.02923759, 0.01480007],
[ 0.00775487, 0.93429903, -0.35640594, -0.58130264],
[ 0.03424814, 0.3559594, 0.93387364, -1.53172435],
[ 0. 0. 0. 1. ]])
Could you please clarify what do you mean by "between using "RT1 &RT2" and "opencv RT convert to RT1 RT2" is different".
Also, please use code format in questions and share the code whenever is pertinent.
Could you please clarify what do you mean by "between using "RT1 &RT2" and "opencv RT convert to RT1 RT2" is different".
Also, please use code format in questions and share the code whenever is pertinent.
I have updated the above comment. Thanks for your reminder! And can you help me check why it did not work?
About using "RT1 &RT2" and "opencv RT convert to RT1 RT2" questions. please see this link. https://github.com/decadenza/DirectStereoRectification/issues/2#issuecomment-1031233316
In these questions, you have given a solution about deriving stereo extrinsic parameters.
Now I have both two camera extrinsic and one stereo extrinsic parameter. The effects of these two pairs are different when using your algorithms. Which one do you suggest?
Something wrong in your code.
RT1
and RT2
should be 3x4 matrices. Anyway, removing the last line, and using two separate extrinsic parameters, I get:
Perspective distortion: 6899654.115043145
(which seems quite a lot, probably for the reason explained above).
By moving the world origin into the first camera, I obtain the exact same result (up to machine precision), as expected and discussed in the previous issue.
To move the extrinsics to the first camera you may refer to my other project, particularly to this function. I used the following code:
import simplestereo as ss
R, T = ss.utils.moveExtrinsicOriginToFirstCamera(RT1[:,:3], RT2[:,:3], RT1[:,3], RT2[:,3])
RT1 = np.array([[ 1, 0, 0, 0], # Left extrinsic parameters
[0, 1, 0, 0],
[0, 0, 1, 0]])
RT2 = np.hstack((R, T))
So, to answer your question, the result must be the same whatever the origin of your system of reference. Paste your entire code and the images if you'd like more help.
Extra comment about vertical stereo rig.
If you have a vertical stereo setup, your epipolar lines would be like the following red lines (representative):
Now, since rectification means to make all the epipolar lines horizontal (same y-coordinate), you are implicitly telling to distort the image so much to achieve this. While if you tilt your head by 90° you can see that the rectification can be achieved with much less distortion.
Hope that this representative example helps to understand.
Hi i am trying do vertical stereo setup with example images as you said. But it seems that the vertical rectification is not successful. Can you help me check it ? The following are code:
import cv2
import numpy as np
import rectification
if __name__ == "__main__":
print("Direct Rectification EXAMPLE")
# Load images
img1 = cv2.imread("img/left.png") # Left image
img2 = cv2.imread("img/right.png") # Right image
def rotate(image, intrinsic_m, extrinsic_m):
(h, w) = image.shape[:2]
# calculate the center of the image
rotated90 = cv2.rotate(image, cv2.cv2.ROTATE_90_CLOCKWISE)
intrinsic90 = intrinsic_m.copy()
intrinsic90[0, 0] = intrinsic_m[1, 1]
intrinsic90[1, 1] = intrinsic_m[0, 0]
intrinsic90[0, 2] = rotated90.shape[0] - intrinsic_m[1, 2]
intrinsic90[1, 2] = intrinsic_m[0, 2]
rotation_z = np.array([[np.cos(90), -np.sin(90), 0], [np.sin(90), np.cos(90), 0], [0, 0, 1]])
extrinsic90 = rotation_z @ extrinsic_m[:3, :]
return rotated90, intrinsic90, extrinsic90
# Calibration data
A1 = np.array([[960, 0, 960 / 2], [0, 960, 540 / 2], [0, 0, 1]]) # Left camera intrinsic matrix
A2 = np.array([[960, 0, 960 / 2], [0, 960, 540 / 2], [0, 0, 1]]) # Right camera intrinsic matrix
RT1 = np.array([[0.98920029, -0.11784191, -0.08715574, 2.26296163], # Left extrinsic parameters
[-0.1284277, -0.41030705, -0.90285909, 0.15825593],
[0.07063401, 0.90430164, -0.42101002, 11.0683527],
[0.,0.,0.,1.]])
RT2 = np.array([[0.94090474, 0.33686835, 0.03489951, 1.0174818], # Right extrinsic parameters
[0.14616159, -0.31095025, -0.93912017, 2.36511779],
[-0.30550784, 0.88872361, -0.34181178, 14.08488464],
[0.,0.,0.,1.]])
img1, A1, RT1 = rotate(img1, A1, RT1)
img2, A2, RT2 = rotate(img2, A2, RT2)
dims1 = img1.shape[::-1][1:] # Image dimensions as (width, height)
dims2 = img2.shape[::-1][1:]
# Distortion coefficients
# Empty because we're using digitally acquired images (no lens distortion).
# See OpenCV distortion parameters for help.
distCoeffs1 = np.array([])
distCoeffs2 = np.array([])
# 3x4 camera projection matrices
Po1 = A1.dot(RT1)
Po2 = A2.dot(RT2)
# Fundamental matrix F is usually known from calibration, alternatively
# you can get the Fundamental matrix from projection matrices
F = rectification.getFundamentalMatrixFromProjections(Po1, Po2)
# ANALYTICAL RECTIFICATION to get the **rectification homographies that minimize distortion**
# See function dr.getAnalyticalRectifications() for details
Rectify1, Rectify2 = rectification.getDirectRectifications(A1, A2, RT1, RT2, dims1, dims2, F)
# Final rectified image dimensions (common to both images)
destDims = dims1
# Get fitting affine transformation to fit the images into the frame
# Affine transformations do not introduce perspective distortion
Fit1, Fit2 = rectification.getFittingMatrices(Rectify1, Rectify2, dims1, dims2, destDims=dims1)
# Compute maps with OpenCV considering rectifications, fitting transformations and lens distortion
# These maps can be stored and applied to rectify any image pair of the same stereo rig
mapx1, mapy1 = cv2.initUndistortRectifyMap(A1, distCoeffs1, Rectify1.dot(A1), Fit1, destDims, cv2.CV_32FC1)
mapx2, mapy2 = cv2.initUndistortRectifyMap(A2, distCoeffs2, Rectify2.dot(A2), Fit2, destDims, cv2.CV_32FC1)
# Apply final transformation to images
img1_rect = cv2.remap(img1, mapx1, mapy1, interpolation=cv2.INTER_LINEAR);
img2_rect = cv2.remap(img2, mapx2, mapy2, interpolation=cv2.INTER_LINEAR);
# Draw a line as reference (optional)
img1_rect = cv2.line(img1_rect, (0, int((destDims[1] - 1) / 2)), (destDims[0] - 1, int((destDims[1] - 1) / 2)),
color=(0, 0, 255), thickness=1)
img2_rect = cv2.line(img2_rect, (0, int((destDims[1] - 1) / 2)), (destDims[0] - 1, int((destDims[1] - 1) / 2)),
color=(0, 0, 255), thickness=1)
# Print some info
perspDist = rectification.getLoopZhangDistortionValue(Rectify1, dims1) + rectification.getLoopZhangDistortionValue(
Rectify2, dims2)
print("Perspective distortion:", perspDist)
# Show images
# cv2.imshow('LEFT Rectified', img1_rect)
# cv2.imshow('RIGHT Rectified', img2_rect)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
import matplotlib.pyplot as plt # plt
plt.figure()
plt.subplot(1, 2, 1)
plt.imshow(img1_rect)
plt.subplot(1, 2, 2)
plt.imshow(img2_rect)
plt.show()
Thanks
Hello @williamhyin,
I appreciate your request, so even if it's not an issue, I'll try to explain with a clearer example.
1) Suppose we have a vertical stereo rig, with a top camera and a bottom one. The system is calibrated (we know intrinsics and extrinsics). Let's take the two pictures from a virtual scene I made for you... Say cheese:
2) Ok, the algorithm doesn't care if the x-axis is actually horizontal. Let's tilt our head to the right (90°).
What did we do? We rotated the world axes (rotation of 90° along z-axis).
We'll see the two pictures rotated (reduced size for clarity):
3) Axes in the camera intrinsic and extrinsics must be also swapped.
4) Proceed with the algorithm as normal.
5) Rotate the rectified images back to the original orientation.
6) That's all folks.
Here's the code I used for this. You should be able to download and use the first two images I linked above.
import cv2
import numpy as np
import rectification
def swap(m):
s = m.copy()
# focal length
s[0, 0] = m[1, 1]
s[1, 1] = m[0, 0]
# principal point
s[0, 2] = m[1, 2]
s[1, 2] = m[0, 2]
# skew factor
s[0, 1] = m[1, 0]
s[1, 0] = m[0, 1]
return s
def rotateWorld90(extrinsic_m):
a = np.pi/2
rotation_z = np.array([[np.cos(a), -np.sin(a), 0], [np.sin(a), np.cos(a), 0], [0, 0, 1]])
extrinsic90 = rotation_z @ extrinsic_m
return extrinsic90
if __name__ == "__main__":
print("Direct Rectification EXAMPLE")
# Load images
img1 = cv2.imread("img/top.png") # Top image
img2 = cv2.imread("img/bottom.png") # Bottom image
# Calibration data VERTICAL STEREO
A1 = np.array([[1.77777783e+03, 0.00000000e+00, 6.40000000e+02],
[0.00000000e+00, 1.77777783e+03, 3.60000000e+02],
[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) # TOP camera intrinsic matrix
A2 = np.array([[1.77777783e+03, 0.00000000e+00, 6.40000000e+02],
[0.00000000e+00, 1.77777783e+03, 3.60000000e+02],
[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) # BOTTOM camera intrinsic matrix
RT1 = np.array([[-1.00000036e+00, 4.81966929e-08, 1.04109733e-06,
-9.54865165e-09],
[-3.08187566e-07, -9.67931986e-01, -2.51212329e-01,
1.91765144e-01],
[ 9.95603841e-07, -2.51212329e-01, 9.67932343e-01,
4.97697853e-02]])
RT2 = np.array([[-0.95603412, 0.28449398, -0.07114441, 0.01241635],
[-0.29285026, -0.91345638, 0.28255302, -0.32894552],
[ 0.01539733, 0.29096505, 0.95660955, 0.09808378]])
### Tilt your head to the right side: the new y axis is the old x axis.
# Rotate images
img1 = cv2.rotate(img1, cv2.ROTATE_90_CLOCKWISE)
img2 = cv2.rotate(img2, cv2.ROTATE_90_CLOCKWISE)
# Swap intrinsics
A1 = swap(A1)
A2 = swap(A2)
# Rotate world
RT1 = rotateWorld90(RT1)
RT2 = rotateWorld90(RT2)
### FROM HERE everything is left unchanged...
dims1 = img1.shape[::-1][1:] # Image dimensions as (width, height)
dims2 = img2.shape[::-1][1:]
# Distortion coefficients
# Empty because we're using digitally acquired images (no lens distortion).
# See OpenCV distortion parameters for help.
distCoeffs1 = np.array([])
distCoeffs2 = np.array([])
# 3x4 camera projection matrices
Po1 = A1.dot(RT1)
Po2 = A2.dot(RT2)
# Fundamental matrix F is usually known from calibration, alternatively
# you can get the Fundamental matrix from projection matrices
F = rectification.getFundamentalMatrixFromProjections(Po1, Po2)
# ANALYTICAL RECTIFICATION to get the **rectification homographies that minimize distortion**
# See function dr.getAnalyticalRectifications() for details
Rectify1, Rectify2 = rectification.getDirectRectifications(A1, A2, RT1, RT2, dims1, dims2, F)
# Final rectified image dimensions (common to both images)
destDims = dims1
# Get fitting affine transformation to fit the images into the frame
# Affine transformations do not introduce perspective distortion
Fit1, Fit2 = rectification.getFittingMatrices(Rectify1, Rectify2, dims1, dims2, destDims=dims1)
# Compute maps with OpenCV considering rectifications, fitting transformations and lens distortion
# These maps can be stored and applied to rectify any image pair of the same stereo rig
mapx1, mapy1 = cv2.initUndistortRectifyMap(A1, distCoeffs1, Rectify1.dot(A1), Fit1, destDims, cv2.CV_32FC1)
mapx2, mapy2 = cv2.initUndistortRectifyMap(A2, distCoeffs2, Rectify2.dot(A2), Fit2, destDims, cv2.CV_32FC1)
# Apply final transformation to images
img1_rect = cv2.remap(img1, mapx1, mapy1, interpolation=cv2.INTER_LINEAR);
img2_rect = cv2.remap(img2, mapx2, mapy2, interpolation=cv2.INTER_LINEAR);
# Draw (horizontal) lines as reference (optional)
for y in [385,572,700]:
img1_rect = cv2.line(img1_rect, (0,y), (destDims[0] - 1, y),
color=(255, 0, 0), thickness=1)
img2_rect = cv2.line(img2_rect, (0,y), (destDims[0] - 1, y),
color=(255, 0, 0), thickness=1)
### ... UNTIL HERE
# Rotate images back to the expected position
img1_rect = cv2.rotate(img1_rect, cv2.ROTATE_90_COUNTERCLOCKWISE)
img2_rect = cv2.rotate(img2_rect, cv2.ROTATE_90_COUNTERCLOCKWISE)
# Print some info
perspDist = rectification.getLoopZhangDistortionValue(Rectify1, dims1) + rectification.getLoopZhangDistortionValue(
Rectify2, dims2)
print("Perspective distortion:", perspDist)
# Show images
cv2.imshow('TOP Rectified', img1_rect)
cv2.imshow('BOTTOM Rectified', img2_rect)
cv2.waitKey(0)
cv2.destroyAllWindows()
N.B. Note that np.sin
and np.cos
expect an angle in radiants!
Hello @williamhyin,
I appreciate your request, so even if it's not an issue, I'll try to explain with a clearer example.
- Suppose we have a vertical stereo rig, with a top camera and a bottom one. The system is calibrated (we know intrinsics and extrinsics). Let's take the two pictures from a virtual scene I made for you... Say cheese:
![]()
- Ok, the algorithm doesn't care if the x-axis is actually horizontal. Let's tilt our head to the right (90°). What did we do? We rotated the world axes (rotation of 90° along z-axis). We'll see the two pictures rotated (reduced size for clarity):
- Axes in the camera intrinsic and extrinsics must be also swapped.
- Proceed with the algorithm as normal.
- Rotate the rectified images back to the original orientation.
![]()
- That's all folks.
Here's the code I used for this. You should be able to download and use the first two images I linked above.
import cv2 import numpy as np import rectification def swap(m): s = m.copy() # focal length s[0, 0] = m[1, 1] s[1, 1] = m[0, 0] # principal point s[0, 2] = m[1, 2] s[1, 2] = m[0, 2] # skew factor s[0, 1] = m[1, 0] s[1, 0] = m[0, 1] return s def rotateWorld90(extrinsic_m): a = np.pi/2 rotation_z = np.array([[np.cos(a), -np.sin(a), 0], [np.sin(a), np.cos(a), 0], [0, 0, 1]]) extrinsic90 = rotation_z @ extrinsic_m return extrinsic90 if __name__ == "__main__": print("Direct Rectification EXAMPLE") # Load images img1 = cv2.imread("img/top.png") # Top image img2 = cv2.imread("img/bottom.png") # Bottom image # Calibration data VERTICAL STEREO A1 = np.array([[1.77777783e+03, 0.00000000e+00, 6.40000000e+02], [0.00000000e+00, 1.77777783e+03, 3.60000000e+02], [0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) # TOP camera intrinsic matrix A2 = np.array([[1.77777783e+03, 0.00000000e+00, 6.40000000e+02], [0.00000000e+00, 1.77777783e+03, 3.60000000e+02], [0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) # BOTTOM camera intrinsic matrix RT1 = np.array([[-1.00000036e+00, 4.81966929e-08, 1.04109733e-06, -9.54865165e-09], [-3.08187566e-07, -9.67931986e-01, -2.51212329e-01, 1.91765144e-01], [ 9.95603841e-07, -2.51212329e-01, 9.67932343e-01, 4.97697853e-02]]) RT2 = np.array([[-0.95603412, 0.28449398, -0.07114441, 0.01241635], [-0.29285026, -0.91345638, 0.28255302, -0.32894552], [ 0.01539733, 0.29096505, 0.95660955, 0.09808378]]) ### Tilt your head to the right side: the new y axis is the old x axis. # Rotate images img1 = cv2.rotate(img1, cv2.ROTATE_90_CLOCKWISE) img2 = cv2.rotate(img2, cv2.ROTATE_90_CLOCKWISE) # Swap intrinsics A1 = swap(A1) A2 = swap(A2) # Rotate world RT1 = rotateWorld90(RT1) RT2 = rotateWorld90(RT2) ### FROM HERE everything is left unchanged... dims1 = img1.shape[::-1][1:] # Image dimensions as (width, height) dims2 = img2.shape[::-1][1:] # Distortion coefficients # Empty because we're using digitally acquired images (no lens distortion). # See OpenCV distortion parameters for help. distCoeffs1 = np.array([]) distCoeffs2 = np.array([]) # 3x4 camera projection matrices Po1 = A1.dot(RT1) Po2 = A2.dot(RT2) # Fundamental matrix F is usually known from calibration, alternatively # you can get the Fundamental matrix from projection matrices F = rectification.getFundamentalMatrixFromProjections(Po1, Po2) # ANALYTICAL RECTIFICATION to get the **rectification homographies that minimize distortion** # See function dr.getAnalyticalRectifications() for details Rectify1, Rectify2 = rectification.getDirectRectifications(A1, A2, RT1, RT2, dims1, dims2, F) # Final rectified image dimensions (common to both images) destDims = dims1 # Get fitting affine transformation to fit the images into the frame # Affine transformations do not introduce perspective distortion Fit1, Fit2 = rectification.getFittingMatrices(Rectify1, Rectify2, dims1, dims2, destDims=dims1) # Compute maps with OpenCV considering rectifications, fitting transformations and lens distortion # These maps can be stored and applied to rectify any image pair of the same stereo rig mapx1, mapy1 = cv2.initUndistortRectifyMap(A1, distCoeffs1, Rectify1.dot(A1), Fit1, destDims, cv2.CV_32FC1) mapx2, mapy2 = cv2.initUndistortRectifyMap(A2, distCoeffs2, Rectify2.dot(A2), Fit2, destDims, cv2.CV_32FC1) # Apply final transformation to images img1_rect = cv2.remap(img1, mapx1, mapy1, interpolation=cv2.INTER_LINEAR); img2_rect = cv2.remap(img2, mapx2, mapy2, interpolation=cv2.INTER_LINEAR); # Draw (horizontal) lines as reference (optional) for y in [385,572,700]: img1_rect = cv2.line(img1_rect, (0,y), (destDims[0] - 1, y), color=(255, 0, 0), thickness=1) img2_rect = cv2.line(img2_rect, (0,y), (destDims[0] - 1, y), color=(255, 0, 0), thickness=1) ### ... UNTIL HERE # Rotate images back to the expected position img1_rect = cv2.rotate(img1_rect, cv2.ROTATE_90_COUNTERCLOCKWISE) img2_rect = cv2.rotate(img2_rect, cv2.ROTATE_90_COUNTERCLOCKWISE) # Print some info perspDist = rectification.getLoopZhangDistortionValue(Rectify1, dims1) + rectification.getLoopZhangDistortionValue( Rectify2, dims2) print("Perspective distortion:", perspDist) # Show images cv2.imshow('TOP Rectified', img1_rect) cv2.imshow('BOTTOM Rectified', img2_rect) cv2.waitKey(0) cv2.destroyAllWindows()
N.B. Note that
np.sin
andnp.cos
expect an angle in radiants!
I have found error that i used np.sin(90) for rotated extrinsic parameter calculation. Thank you very much for your careful explanation and guidance! You are the greatest author and also the friendliest author I have ever seen!
Thank you for using this code. If you need stereo vision for your project, may I suggest to give a look at my other repository https://github.com/decadenza/SimpleStereo, which contains calibration and matching algorithms, and also this rectification algorithm and more. Cheers.
Hi
Thanks for your kindly help and guidance before.
I have a question about rectification with different fov(different internal parameters). One is :
the another is :
also the have a wide baseline:
T = [ 0.01480007 -0.58130264 -1.53172435]
when I use DirectStereoRectification: the perspective distortion is really big: 4077962.957242966And the rectification failed.
Can you give me some suggestions?
Will this "DirectStereoRectification" algorithms fail with two cameras with completely different internal parameters? Should i scale to the similar focal length? Or is this related to the x_axis baseline length? too small failed?
Thanks