Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Stereo Vision (Python) - How can I improve my Stereo Rectification results?

Hi all,

I am carrying out an undergraduate where I need to find out the depth of a stereo image, thus it is crucial to get a good disparity map for the calculations to be accurate. My rectification results are pretty mediocre at best and I have carried out the calibration countless times with no success, only minimal variations between results. I would highly appreciate experts' guidance on this issue.

I cannot post my results on this question as I have insufficient karma, but the rectified images look as if they were warped in a spiral manner and overriding the original video capture. Copy this in the url if you wish to see a sample of my results: scontent.fmla1-2.fna.fbcdn.net/v/t35.0-12/17571001_10212528106338046_845875913_o.png?oh=3ef04efa50a3d9f4e4d253f2f57ae298&oe=58DAF735

This is my code for the calibration:

import cv,time,sys
import cv2
from itertools import izip
# python calibrate.py board_w,board_h and boards_n should be given by the user
n_boards=0  #no of boards
board_w=int(sys.argv[1])    # number of horizontal corners
board_h=int(sys.argv[2])    # number of vertical corners
n_boards=int(sys.argv[3])   # no. of views passed as pictures
board_n=board_w*board_h     # no of total corners
board_sz=(board_w,board_h)  # size of board

#   creation of memory storages for left camera
image_points0=cv.CreateMat(n_boards*board_n,2,cv.CV_32FC1)
object_points=cv.CreateMat(n_boards*board_n,3,cv.CV_32FC1)
point_counts=cv.CreateMat(n_boards,1,cv.CV_32SC1)
intrinsic_matrix0=cv.CreateMat(3,3,cv.CV_32FC1)
distortion_coefficient0=cv.CreateMat(5,1,cv.CV_32FC1)

#   creation of memory storages for right camera
image_points1=cv.CreateMat(n_boards*board_n,2,cv.CV_32FC1)
intrinsic_matrix1=cv.CreateMat(3,3,cv.CV_32FC1)
distortion_coefficient1=cv.CreateMat(5,1,cv.CV_32FC1)

R=cv.CreateMat(3,3,cv.CV_64F)
T=cv.CreateMat(3,1,cv.CV_64F)
E=cv.CreateMat(3,3,cv.CV_64F)
F=cv.CreateMat(3,3,cv.CV_64F)
#term_crit=(cv.CV_TERMCRIT_EPS+cv.CV_TERMCRIT_ITER,30,0.1)
#capture frames of specified properties and modification of matrix values
i=0
z=0     # to print number of frames
successes=0


#   capturing required number of views

found=0
with open('Left.txt','rb') as f:
    imgl= [line.strip() for line in f]
    with open('Right.txt','rb') as f1:
         imgr=[line.strip() for line in f1]
         for (image0,image1) in izip(imgl,imgr):
        if image0 =='' or image1== '' :
            break;
        else:

                Image0 = cv.LoadImage(image0)
                Image1 = cv.LoadImage(image1)

            gray_image0=cv.CreateImage(cv.GetSize(Image0),8,1)
            cv.CvtColor(Image0,gray_image0,cv.CV_BGR2GRAY)
            gray_image1=cv.CreateImage(cv.GetSize(Image1),8,1)
            cv.CvtColor(Image1,gray_image1,cv.CV_BGR2GRAY)
            (found0,corners0)=cv.FindChessboardCorners(gray_image0,board_sz,cv.CV_CALIB_CB_ADAPTIVE_THRESH| cv.CV_CALIB_CB_FILTER_QUADS)
            (found1,corners1)=cv.FindChessboardCorners(gray_image1,board_sz,cv.CV_CALIB_CB_ADAPTIVE_THRESH| cv.CV_CALIB_CB_FILTER_QUADS)
            cv.FindCornerSubPix(gray_image0,corners0,(11,11),(-1,-1),(cv.CV_TERMCRIT_EPS+cv.CV_TERMCRIT_ITER,30,0.001))
            cv.FindCornerSubPix(gray_image1,corners1,(11,11),(-1,-1),(cv.CV_TERMCRIT_EPS+cv.CV_TERMCRIT_ITER,30,0.001))     
            # if got a good image,draw chess board
            if found0==1 and found1==1:
                print "found frame number {0}".format(z+1)
                cv.DrawChessboardCorners(Image0,board_sz,corners0,1) 
                cv.DrawChessboardCorners(Image1,board_sz,corners1,1) 
                cv.ShowImage("Left cam corners",Image0);
                cv.ShowImage("Right cam corners",Image1);
                cv.WaitKey(33)
                corner_count0=len(corners0)
                corner_count1=len(corners1)
                print "corner count0",corner_count0
                print "corner count1",corner_count1
                z=z+1

            # if got a good image, add to matrix
            if len(corners0)==board_n and len(corners1)==board_n:
                step=successes*board_n
                k=step
                for j in range(board_n):
                    cv.Set2D(image_points0,k,0,corners0[j][0])
                    cv.Set2D(image_points0,k,1,corners0[j][1])

                    cv.Set2D(image_points1,k,0,corners1[j][0])
                    cv.Set2D(image_points1,k,1,corners1[j][1])

                    cv.Set2D(object_points,k,0,float(j)/float(board_w))
                    cv.Set2D(object_points,k,1,float(j)%float(board_w))
                    cv.Set2D(object_points,k,2,0.0)

                    k=k+1
                    cv.Set2D(point_counts,successes,0,board_n)
            successes=successes+1
            print successes
            time.sleep(2)
            print "-------------------------------------------------"
            print "\n"
print "Calibration OK, Matrices Created"
cv.DestroyWindow("Test Frame")

# now assigning new matrices according to view_count
object_points2=cv.CreateMat(successes*board_n,3,cv.CV_32FC1)
image_points20=cv.CreateMat(successes*board_n,2,cv.CV_32FC1)
image_points21=cv.CreateMat(successes*board_n,2,cv.CV_32FC1)
point_counts2=cv.CreateMat(successes,1,cv.CV_32SC1)

#transfer points to matrices

for i in range(successes*board_n):
    cv.Set2D(image_points20,i,0,cv.Get2D(image_points0,i,0))
    cv.Set2D(image_points20,i,1,cv.Get2D(image_points0,i,1))

    cv.Set2D(image_points21,i,0,cv.Get2D(image_points1,i,0))
    cv.Set2D(image_points21,i,1,cv.Get2D(image_points1,i,1))

    cv.Set2D(object_points2,i,0,cv.Get2D(object_points,i,0))
    cv.Set2D(object_points2,i,1,cv.Get2D(object_points,i,1))
    cv.Set2D(object_points2,i,2,cv.Get2D(object_points,i,2))


for i in range(successes):
    cv.Set2D(point_counts2,i,0,cv.Get2D(point_counts,i,0))

cv.Set2D(intrinsic_matrix0,0,0,1.0)
cv.Set2D(intrinsic_matrix0,1,1,1.0)

cv.Set2D(intrinsic_matrix1,0,0,1.0)
cv.Set2D(intrinsic_matrix1,1,1,1.0)

print "Checking Camera Calibration"
# camera calibration
#cv.StereoCalibrate(object_points2,image_points20,image_points21,point_counts2,intrinsic_matrix0,
#distortion_coefficient0,intrinsic_matrix1,distortion_coefficient1,cv.GetSize(Image0),R,T,E,F,
#(cv.CV_TERMCRIT_ITER+cv.CV_TERMCRIT_EPS, 30, 1e-6), (cv.CV_CALIB_SAME_FOCAL_LENGTH+cv.CV_CALIB_ZERO_TANGENT_DIST+cv.CV_CALIB_FIX_FOCAL_LENGTH ))
cv.StereoCalibrate(object_points2,image_points20,image_points21,point_counts2,intrinsic_matrix0,
distortion_coefficient0,intrinsic_matrix1,distortion_coefficient1,cv.GetSize(Image0),R,T,E,F,
(cv2.TERM_CRITERIA_MAX_ITER + cv2.TERM_CRITERIA_EPS, 100, 1e-5), (cv2.CALIB_FIX_ASPECT_RATIO + cv2.CALIB_ZERO_TANGENT_DIST + cv2.CALIB_SAME_FOCAL_LENGTH+
cv.CV_CALIB_FIX_K1+
cv.CV_CALIB_FIX_K2+
cv.CV_CALIB_FIX_K3))
print "Calibration Successful"  

# storing results in xml files
cv.Save("Image points1.xml",image_points20)
cv.Save("Image points2.xml",image_points21)
cv.Save("Intrinsics0.xml",intrinsic_matrix0)
cv.Save("Distortion0.xml",distortion_coefficient0)

cv.Save("Intrinsics1.xml",intrinsic_matrix1)
cv.Save("Distortion1.xml",distortion_coefficient1)
cv.Save("R.xml",R)
cv.Save("T.xml",T)

This is my code for the rectification:

import cv
import time
import numpy as np

def stereorectify(image0,image1):   

# Loading matrices output from the calibration step
    intrinsic0=cv.Load("Intrinsics0.xml")
    distortion0=cv.Load("Distortion0.xml")
    intrinsic1=cv.Load("Intrinsics1.xml")
    distortion1=cv.Load("Distortion1.xml")
    R=cv.Load("R.xml")
    T=cv.Load("T.xml")

# Rectification
    Ro=cv.CreateMat(3,1,cv.CV_64F);
    cv.Rodrigues2(R, Ro)
    size=cv.GetSize(image0)
    R1=cv.CreateMat(3,3,cv.CV_64F)
    R2=cv.CreateMat(3,3,cv.CV_64F)
    P1=cv.CreateMat(3,4,cv.CV_64F)
    P2=cv.CreateMat(3,4,cv.CV_64F)
    #Q=cv.CreateMat(4,4,cv.CV_64F)
    height,width=240, 320
    focal_length=0.8*width
    Q = np.float32([[1, 0, 0, -0.5 * width],
                    [0, -1, 0, 0.5 * height],
                    [0, 0, 0, -focal_length],
                    [0, 0, 1, 0]])
    flags=cv.CV_CALIB_ZERO_DISPARITY
    #cv.StereoRectify(intrinsic0, intrinsic1, distortion0,distortion1,(320,240),R,T,R2, R1, P1,P2, cv.fromarray(Q) ,0,0)
    cv.StereoRectify(intrinsic0, intrinsic1, distortion0,distortion1,(640,480),R,T,R2, R1, P1,P2, cv.fromarray(Q) ,0,0)

#print newImageSize
    map1x = cv.CreateImage(size, cv.IPL_DEPTH_32F,1)
    map2x = cv.CreateImage(size, cv.IPL_DEPTH_32F,1)
#Right maps
    map1y = cv.CreateImage(size, cv.IPL_DEPTH_32F,1)
    map2y = cv.CreateImage(size, cv.IPL_DEPTH_32F,1)

# Undistorting/ Rectification
    cv.InitUndistortRectifyMap(intrinsic0, distortion0, R1, intrinsic0, map1x, map1y)
    cv.InitUndistortRectifyMap(intrinsic1, distortion1, R2, intrinsic1,map2x, map2y)
    cv.InitUndistortRectifyMap(intrinsic0, distortion0, R1, intrinsic0, map1x, map1y)
    cv.InitUndistortRectifyMap(intrinsic1, distortion1, R2, intrinsic1,map2x, map2y)
    cv.Remap(image0,image0, map1x, map1y,cv.CV_INTER_CUBIC)
    cv.Remap(image1,image1, map2x, map2y,cv.CV_INTER_CUBIC)

    cv.Save("R1.xml",R1);
    cv.Save("map1x.xml",map1x);
    #cv.Save("Q.xml",Q)
    return image0,image1

I would appreciate any help which could aid me in yielding better results as I feel I've hit a dead end and cannot improve. Thanks!!

Stereo Vision (Python) - How can I improve my Stereo Rectification results?

Hi all,

I am carrying out an undergraduate where I need to find out the depth of a stereo image, thus it is crucial to get a good disparity map for the calculations to be accurate. My rectification results are pretty mediocre at best and I have carried out the calibration countless times with no success, only minimal variations between results. I would highly appreciate experts' guidance on this issue.issue. Like, can I try changing some parameters of my stereoRectify method? I already tried to tinker with the stereocalibrate parameters with minimal success.

I cannot post my results on this question as I have insufficient karma, but the rectified images look as if they were warped in a spiral manner and overriding the original video capture. Copy this in the url URL if you wish to see a sample of my results: scontent.fmla1-2.fna.fbcdn.net/v/t35.0-12/17571001_10212528106338046_845875913_o.png?oh=3ef04efa50a3d9f4e4d253f2f57ae298&oe=58DAF735

This is my code for the calibration:

import cv,time,sys
import cv2
from itertools import izip
# python calibrate.py board_w,board_h and boards_n should be given by the user
n_boards=0  #no of boards
board_w=int(sys.argv[1])    # number of horizontal corners
board_h=int(sys.argv[2])    # number of vertical corners
n_boards=int(sys.argv[3])   # no. of views passed as pictures
board_n=board_w*board_h     # no of total corners
board_sz=(board_w,board_h)  # size of board

#   creation of memory storages for left camera
image_points0=cv.CreateMat(n_boards*board_n,2,cv.CV_32FC1)
object_points=cv.CreateMat(n_boards*board_n,3,cv.CV_32FC1)
point_counts=cv.CreateMat(n_boards,1,cv.CV_32SC1)
intrinsic_matrix0=cv.CreateMat(3,3,cv.CV_32FC1)
distortion_coefficient0=cv.CreateMat(5,1,cv.CV_32FC1)

#   creation of memory storages for right camera
image_points1=cv.CreateMat(n_boards*board_n,2,cv.CV_32FC1)
intrinsic_matrix1=cv.CreateMat(3,3,cv.CV_32FC1)
distortion_coefficient1=cv.CreateMat(5,1,cv.CV_32FC1)

R=cv.CreateMat(3,3,cv.CV_64F)
T=cv.CreateMat(3,1,cv.CV_64F)
E=cv.CreateMat(3,3,cv.CV_64F)
F=cv.CreateMat(3,3,cv.CV_64F)
#term_crit=(cv.CV_TERMCRIT_EPS+cv.CV_TERMCRIT_ITER,30,0.1)
#capture frames of specified properties and modification of matrix values
i=0
z=0     # to print number of frames
successes=0


#   capturing required number of views

found=0
with open('Left.txt','rb') as f:
    imgl= [line.strip() for line in f]
    with open('Right.txt','rb') as f1:
         imgr=[line.strip() for line in f1]
         for (image0,image1) in izip(imgl,imgr):
        if image0 =='' or image1== '' :
            break;
        else:

                Image0 = cv.LoadImage(image0)
                Image1 = cv.LoadImage(image1)

            gray_image0=cv.CreateImage(cv.GetSize(Image0),8,1)
            cv.CvtColor(Image0,gray_image0,cv.CV_BGR2GRAY)
            gray_image1=cv.CreateImage(cv.GetSize(Image1),8,1)
            cv.CvtColor(Image1,gray_image1,cv.CV_BGR2GRAY)
            (found0,corners0)=cv.FindChessboardCorners(gray_image0,board_sz,cv.CV_CALIB_CB_ADAPTIVE_THRESH| cv.CV_CALIB_CB_FILTER_QUADS)
            (found1,corners1)=cv.FindChessboardCorners(gray_image1,board_sz,cv.CV_CALIB_CB_ADAPTIVE_THRESH| cv.CV_CALIB_CB_FILTER_QUADS)
            cv.FindCornerSubPix(gray_image0,corners0,(11,11),(-1,-1),(cv.CV_TERMCRIT_EPS+cv.CV_TERMCRIT_ITER,30,0.001))
            cv.FindCornerSubPix(gray_image1,corners1,(11,11),(-1,-1),(cv.CV_TERMCRIT_EPS+cv.CV_TERMCRIT_ITER,30,0.001))     
            # if got a good image,draw chess board
            if found0==1 and found1==1:
                print "found frame number {0}".format(z+1)
                cv.DrawChessboardCorners(Image0,board_sz,corners0,1) 
                cv.DrawChessboardCorners(Image1,board_sz,corners1,1) 
                cv.ShowImage("Left cam corners",Image0);
                cv.ShowImage("Right cam corners",Image1);
                cv.WaitKey(33)
                corner_count0=len(corners0)
                corner_count1=len(corners1)
                print "corner count0",corner_count0
                print "corner count1",corner_count1
                z=z+1

            # if got a good image, add to matrix
            if len(corners0)==board_n and len(corners1)==board_n:
                step=successes*board_n
                k=step
                for j in range(board_n):
                    cv.Set2D(image_points0,k,0,corners0[j][0])
                    cv.Set2D(image_points0,k,1,corners0[j][1])

                    cv.Set2D(image_points1,k,0,corners1[j][0])
                    cv.Set2D(image_points1,k,1,corners1[j][1])

                    cv.Set2D(object_points,k,0,float(j)/float(board_w))
                    cv.Set2D(object_points,k,1,float(j)%float(board_w))
                    cv.Set2D(object_points,k,2,0.0)

                    k=k+1
                    cv.Set2D(point_counts,successes,0,board_n)
            successes=successes+1
            print successes
            time.sleep(2)
            print "-------------------------------------------------"
            print "\n"
print "Calibration OK, Matrices Created"
cv.DestroyWindow("Test Frame")

# now assigning new matrices according to view_count
object_points2=cv.CreateMat(successes*board_n,3,cv.CV_32FC1)
image_points20=cv.CreateMat(successes*board_n,2,cv.CV_32FC1)
image_points21=cv.CreateMat(successes*board_n,2,cv.CV_32FC1)
point_counts2=cv.CreateMat(successes,1,cv.CV_32SC1)

#transfer points to matrices

for i in range(successes*board_n):
    cv.Set2D(image_points20,i,0,cv.Get2D(image_points0,i,0))
    cv.Set2D(image_points20,i,1,cv.Get2D(image_points0,i,1))

    cv.Set2D(image_points21,i,0,cv.Get2D(image_points1,i,0))
    cv.Set2D(image_points21,i,1,cv.Get2D(image_points1,i,1))

    cv.Set2D(object_points2,i,0,cv.Get2D(object_points,i,0))
    cv.Set2D(object_points2,i,1,cv.Get2D(object_points,i,1))
    cv.Set2D(object_points2,i,2,cv.Get2D(object_points,i,2))


for i in range(successes):
    cv.Set2D(point_counts2,i,0,cv.Get2D(point_counts,i,0))

cv.Set2D(intrinsic_matrix0,0,0,1.0)
cv.Set2D(intrinsic_matrix0,1,1,1.0)

cv.Set2D(intrinsic_matrix1,0,0,1.0)
cv.Set2D(intrinsic_matrix1,1,1,1.0)

print "Checking Camera Calibration"
# camera calibration
#cv.StereoCalibrate(object_points2,image_points20,image_points21,point_counts2,intrinsic_matrix0,
#distortion_coefficient0,intrinsic_matrix1,distortion_coefficient1,cv.GetSize(Image0),R,T,E,F,
#(cv.CV_TERMCRIT_ITER+cv.CV_TERMCRIT_EPS, 30, 1e-6), (cv.CV_CALIB_SAME_FOCAL_LENGTH+cv.CV_CALIB_ZERO_TANGENT_DIST+cv.CV_CALIB_FIX_FOCAL_LENGTH ))
cv.StereoCalibrate(object_points2,image_points20,image_points21,point_counts2,intrinsic_matrix0,
distortion_coefficient0,intrinsic_matrix1,distortion_coefficient1,cv.GetSize(Image0),R,T,E,F,
(cv2.TERM_CRITERIA_MAX_ITER + cv2.TERM_CRITERIA_EPS, 100, 1e-5), (cv2.CALIB_FIX_ASPECT_RATIO + cv2.CALIB_ZERO_TANGENT_DIST + cv2.CALIB_SAME_FOCAL_LENGTH+
cv.CV_CALIB_FIX_K1+
cv.CV_CALIB_FIX_K2+
cv.CV_CALIB_FIX_K3))
print "Calibration Successful"  

# storing results in xml files
cv.Save("Image points1.xml",image_points20)
cv.Save("Image points2.xml",image_points21)
cv.Save("Intrinsics0.xml",intrinsic_matrix0)
cv.Save("Distortion0.xml",distortion_coefficient0)

cv.Save("Intrinsics1.xml",intrinsic_matrix1)
cv.Save("Distortion1.xml",distortion_coefficient1)
cv.Save("R.xml",R)
cv.Save("T.xml",T)

This is my code for the rectification:

import cv
import time
import numpy as np

def stereorectify(image0,image1):   

# Loading matrices output from the calibration step
    intrinsic0=cv.Load("Intrinsics0.xml")
    distortion0=cv.Load("Distortion0.xml")
    intrinsic1=cv.Load("Intrinsics1.xml")
    distortion1=cv.Load("Distortion1.xml")
    R=cv.Load("R.xml")
    T=cv.Load("T.xml")

# Rectification
    Ro=cv.CreateMat(3,1,cv.CV_64F);
    cv.Rodrigues2(R, Ro)
    size=cv.GetSize(image0)
    R1=cv.CreateMat(3,3,cv.CV_64F)
    R2=cv.CreateMat(3,3,cv.CV_64F)
    P1=cv.CreateMat(3,4,cv.CV_64F)
    P2=cv.CreateMat(3,4,cv.CV_64F)
    #Q=cv.CreateMat(4,4,cv.CV_64F)
    height,width=240, 320
    focal_length=0.8*width
    Q = np.float32([[1, 0, 0, -0.5 * width],
                    [0, -1, 0, 0.5 * height],
                    [0, 0, 0, -focal_length],
                    [0, 0, 1, 0]])
    flags=cv.CV_CALIB_ZERO_DISPARITY
    #cv.StereoRectify(intrinsic0, intrinsic1, distortion0,distortion1,(320,240),R,T,R2, R1, P1,P2, cv.fromarray(Q) ,0,0)
    cv.StereoRectify(intrinsic0, intrinsic1, distortion0,distortion1,(640,480),R,T,R2, R1, P1,P2, cv.fromarray(Q) ,0,0)

#print newImageSize
    map1x = cv.CreateImage(size, cv.IPL_DEPTH_32F,1)
    map2x = cv.CreateImage(size, cv.IPL_DEPTH_32F,1)
#Right maps
    map1y = cv.CreateImage(size, cv.IPL_DEPTH_32F,1)
    map2y = cv.CreateImage(size, cv.IPL_DEPTH_32F,1)

# Undistorting/ Rectification
    cv.InitUndistortRectifyMap(intrinsic0, distortion0, R1, intrinsic0, map1x, map1y)
    cv.InitUndistortRectifyMap(intrinsic1, distortion1, R2, intrinsic1,map2x, map2y)
    cv.InitUndistortRectifyMap(intrinsic0, distortion0, R1, intrinsic0, map1x, map1y)
    cv.InitUndistortRectifyMap(intrinsic1, distortion1, R2, intrinsic1,map2x, map2y)
    cv.Remap(image0,image0, map1x, map1y,cv.CV_INTER_CUBIC)
    cv.Remap(image1,image1, map2x, map2y,cv.CV_INTER_CUBIC)

    cv.Save("R1.xml",R1);
    cv.Save("map1x.xml",map1x);
    #cv.Save("Q.xml",Q)
    return image0,image1

I would appreciate any help which could aid me in yielding better results as I feel I've hit a dead end and cannot improve. Thanks!!