Skip to content

Instantly share code, notes, and snippets.

@andijakl
Last active September 20, 2023 13:39
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andijakl/ffe6e5e16742455291ef2a4edbe63cb7 to your computer and use it in GitHub Desktop.
Save andijakl/ffe6e5e16742455291ef2a4edbe63cb7 to your computer and use it in GitHub Desktop.
Calculate the stereo disparity with OpenCV and show a normalized depth map.
# ------------------------------------------------------------
# CALCULATE DISPARITY (DEPTH MAP)
# Adapted from: https://github.com/opencv/opencv/blob/master/samples/python/stereo_match.py
# and: https://docs.opencv.org/master/dd/d53/tutorial_py_depthmap.html
# StereoSGBM Parameter explanations:
# https://docs.opencv.org/4.5.0/d2/d85/classcv_1_1StereoSGBM.html
# Matched block size. It must be an odd number >=1 . Normally, it should be somewhere in the 3..11 range.
block_size = 11
min_disp = -128
max_disp = 128
# Maximum disparity minus minimum disparity. The value is always greater than zero.
# In the current implementation, this parameter must be divisible by 16.
num_disp = max_disp - min_disp
# Margin in percentage by which the best (minimum) computed cost function value should "win" the second best value to consider the found match correct.
# Normally, a value within the 5-15 range is good enough
uniquenessRatio = 5
# Maximum size of smooth disparity regions to consider their noise speckles and invalidate.
# Set it to 0 to disable speckle filtering. Otherwise, set it somewhere in the 50-200 range.
speckleWindowSize = 200
# Maximum disparity variation within each connected component.
# If you do speckle filtering, set the parameter to a positive value, it will be implicitly multiplied by 16.
# Normally, 1 or 2 is good enough.
speckleRange = 2
disp12MaxDiff = 0
stereo = cv.StereoSGBM_create(
minDisparity=min_disp,
numDisparities=num_disp,
blockSize=block_size,
uniquenessRatio=uniquenessRatio,
speckleWindowSize=speckleWindowSize,
speckleRange=speckleRange,
disp12MaxDiff=disp12MaxDiff,
P1=8 * 1 * block_size * block_size,
P2=32 * 1 * block_size * block_size,
)
disparity_SGBM = stereo.compute(img1_undistorted, img2_undistorted)
# Normalize the values to a range from 0..255 for a grayscale image
disparity_SGBM = cv.normalize(disparity_SGBM, disparity_SGBM, alpha=255,
beta=0, norm_type=cv.NORM_MINMAX)
disparity_SGBM = np.uint8(disparity_SGBM)
cv.imshow("Disparity", disparity_SGBM)
cv.imwrite("disparity_SGBM_norm.png", disparity_SGBM)
@HarshitRaj112233
Copy link

What is this img1_undistorted, img2_undistorted you never mentioned them it your code

@andijakl
Copy link
Author

These are just code snippets for embedding into the article - read the full article for the explanation and the complete code: https://www.andreasjakl.com/easily-create-depth-maps-with-smartphone-ar-part-1/

@almerr
Copy link

almerr commented Oct 24, 2021

is undistorted image= rectified image?

@andijakl
Copy link
Author

Yes - how to calculate those is described in the article series linked in the previous comment!

@almerr
Copy link

almerr commented Oct 24, 2021

cannot get good disparity maps using the code, unfortunately. possible to email u?

@TzabarDolev
Copy link

i found the opencv function to create disparity very distorted.
i wrote about disparity at the carla research blog - https://carlasimblog.wordpress.com/2023/09/20/disparity-in-stereo-cameras-measuring-understanding-and-its-crucial-role/.
i shared my code for disparity calculation using manual block matching.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment