enzyme69 / blendersushi

Blender Sushi related scripts. Mostly about Sverchok, Geometry Nodes, Animation Nodes, and related Python scripts.
243 stars 33 forks source link

LIVENODING 1100 / Depth Map Disparity from Stereo Pair Photo #489

Open enzyme69 opened 5 years ago

enzyme69 commented 5 years ago

depth_disparity_032.blend.zip

enzyme69 commented 5 years ago
"""
in   sigma s             default=1.0     nested=2
in   lmbda s       default=80000     nested=2
in   numDispMult s       default=1     nested=2
in   blockSizeVal s       default=1     nested=2
in   window_size_val s       default=3     nested=2
in   uniquenessRatioVal s       default=1     nested=2
in   speckleWindowSizeVal s       default=1     nested=2
in   origin v          default=(0,0,0) n=2
out  verts v
out  textureVal s
"""

### REQUIREMENTS:
### Python 3.7 inside and outside Blender
### OpenCV2 module
### sklearn module
### 

import sys
sklearn_path = r"/usr/local/lib/python3.7/site-packages" #it depend on your OS but just paste the path where is sklearn
#if not sklearn_path in sys.path:
#    sys.path.append(sklearn_path)   

sys.path.append(sklearn_path) 

import numpy as np
from sklearn.preprocessing import normalize
import cv2

#lets now load the images in the same folder, the image for the left eye and the image for the right eye:

print('loading images...')
imgL = cv2.imread('/Users/jimmygunawan/IMG_1696_L.jpg')  # downscale images for faster processing if you like
imgR = cv2.imread('/Users/jimmygunawan/IMG_1696_R.jpg')

#Now comes the interesting part, we define the parameters for the SGBM. These parameters can be changed although I recommend to use the below for standard web image sizes:

# SGBM Parameters -----------------
window_size = window_size_val                    # wsize default 3; 5; 7 for SGBM reduced size image; 15 for SGBM full size image (1300px and above); 5 Works nicely

left_matcher = cv2.StereoSGBM_create(
    minDisparity = 0,
    numDisparities = numDispMult * 16,             # max_disp has to be dividable by 16 f. E. HH 192, 256
    blockSize = blockSizeVal,
    P1=8 * 3 * window_size ** 2,    # wsize default 3; 5; 7 for SGBM reduced size image; 15 for SGBM full size image (1300px and above); 5 Works nicely
    P2=32 * 3 * window_size ** 2,
    disp12MaxDiff=1,
    uniquenessRatio=uniquenessRatioVal,
    speckleWindowSize=speckleWindowSizeVal,
    speckleRange=0,
    preFilterCap=2,
    mode=cv2.STEREO_SGBM_MODE_SGBM_3WAY
)
#This leads us to define the right_matcher so we can use it for our filtering later. This is a simple one-liner:

right_matcher = cv2.ximgproc.createRightMatcher(left_matcher)
#To obtain hole free depth-images we can use the WLS-Filter. This filter also requires some parameters which are shown below:

# FILTER Parameters
#lmbda = 80000
#sigma = 1.4
visual_multiplier = 1.0

wls_filter = cv2.ximgproc.createDisparityWLSFilter(matcher_left=left_matcher)
wls_filter.setLambda(lmbda)
wls_filter.setSigmaColor(sigma)
#Now we can compute the disparities and convert the resulting images to the desired int16 format or how OpenCV names it: CV_16S for our filter:

print('computing disparity...')
displ = left_matcher.compute(imgL, imgR)  # .astype(np.float32)/16
dispr = right_matcher.compute(imgR, imgL)  # .astype(np.float32)/16
displ = np.int16(displ)
dispr = np.int16(dispr)
filteredImg = wls_filter.filter(displ, imgL, None, dispr)  # important to put "imgL" here!!!
#Finally if you show this image with imshow() you may not see anything. This is due to values being not normalized to a 8-bit format. So lets fix this by normalizing our depth map:

filteredImg = cv2.normalize(src=filteredImg, dst=filteredImg, beta=0, alpha=255, norm_type=cv2.NORM_MINMAX);
filteredImg = np.uint8(filteredImg)

print("shape", filteredImg.shape)

# FOR SVERCHOK VIEWER
#max = np.amax(filteredImg)
#data = np.interp(filteredImg,[0, max],[0, 255])
#img = np.reshape(filteredImg, (1192,671, 4))
#textureVal = filteredImg
filteredImgROTATED = np.flip(filteredImg, 0)
textureVal = filteredImgROTATED

#print(filteredImg)

cv2.imwrite(r'depth_out.png', filteredImg)

#cv2.imshow('Disparity Map', filteredImg)
#cv2.waitKey()
#cv2.destroyAllWindows()
print('depth_map_generated!')
skywo1f commented 4 years ago

loading images... Traceback (most recent call last): File "liveNoding.py", line 40, in window_size = window_size_val # wsize default 3; 5; 7 for SGBM reduced size image; 15 for SGBM full size image (1300px and above); 5 Works nicely NameError: name 'window_size_val' is not defined