Search code examples
c++opencvimage-processingcomputer-vision

Black columns in the disparity map when using StereoBM


I am trying to use StereoBM in OpenCV to extract a disparity map from a pair of images. Ignoring the bad quality of the disparity map below, you can see that it has a number of black columns on the left which correspond to the parameter ndisparities. I thought that ndisparities only tells StereoBM how "far" away it can search for a correspondence. What could cause this behaviour? It seems to limit the width of the resulting depth map, but I don't see why.

Disparity map

You can see the stereo pair here and my code below. Thanks in advance for any pointers!

Mat Limg = imread("left.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Mat Rimg = imread("right.jpg", CV_LOAD_IMAGE_GRAYSCALE);

Mat disp(Limg.size(), CV_16SC1), disp8U;
int ndisparities = 512;
StereoBM SBM(StereoBM::BASIC_PRESET, ndisparities , 11);
SBM(Limg, Rimg, disp, CV_16S);

double minVal, maxVal;
minMaxLoc( disp, &minVal, &maxVal );
disp.convertTo( disp8U, CV_8UC1, 255/(maxVal - minVal));
imshow("disparity", disp8U)

Solution

  • The disparity map quantifies the longitudinal (epipolar) offset between corresponding pairs of points in the left and right image.

    In principle,

     disparity := x_l - x_r
    

    where x_l and x_r are the projections on the focal plane of the two cameras of a given point in the space. (Keep in mind that large disparities characterize pixels which are closer to the cameras. [A])


    The parameter ndisparities quantifies the expected maximum disparity you can have (assuming you can neglect the min disparity).

    Since you are assuming that ndisparities is your largest disparity, it holds true

        x_l - x_r < ndisparities,
    

    i.e.

        x_r > x_l - ndisparities 
    

    therefore, it makes no sense looking for correspondences with the right image of any pixel in the first ndisparities columns of the left image: simply you can't have.

    In a sense, the view cone of the right camera starts exactly ndisparities columns on the right of view cone of the left camera.


    A FIX:

    If you want less black columns on the left hand side of the disparity map, you need to be able to assume lower values of ndisparities.

    Since ndisparities depends on the distance from the cameras of the closest object (from [A]), either put the cameras further away from the object or put the cameras closer one another.

    In your very specific case you have a huge disparity (a lot of work for the stereoBM)!! The 'x' symbol in the foreground shows a disparity comparable with the scale of the image!! I believe you need to put your cameras further away.