4

I am studying on stereo vision depth map and I am using the opencv library.I wrote a program to obtain depth map. But when program was run I obtained an empty depth map frame.can anybody help me please, what is wrong ? code are shown in below;

#include <opencv/highgui.h>
#include <opencv/cv.h>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <math.h>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/contrib/contrib.hpp>
int main()
{
IplImage* img1 = cvLoadImage("/home/sezen/Masaüstü/imR.png");
IplImage* img2 = cvLoadImage("/home/sezen/Masaüstü/imL.png");

IplImage *rimage = cvCreateImage(
cvSize( img1->width, img1->height ), IPL_DEPTH_8U, 1 );
cvCvtColor( img1, rimage, CV_RGB2GRAY );

IplImage *limage = cvCreateImage(
cvSize( img2->width, img2->height ), IPL_DEPTH_8U, 1 );
cvCvtColor( img2, limage, CV_RGB2GRAY );

cvNamedWindow( "Right", CV_WINDOW_AUTOSIZE );
cvShowImage( "Right", rimage );

cvNamedWindow( "Left", CV_WINDOW_AUTOSIZE );
cvShowImage("Left", limage);

CvMat *matr = cvCreateMat(rimage->height,rimage->width,CV_8UC1 );
CvMat *matl = cvCreateMat(limage->height,limage->width,CV_8UC1 );
CvMat* disp = cvCreateMat(rimage->height,rimage->width,CV_16S);
CvMat* vdisp = cvCreateMat(rimage->height,rimage->width,CV_16S);

cvConvert( rimage, matr );
cvConvert( limage, matl );

CvStereoBMState *BMState = cvCreateStereoBMState();
assert(BMState != 0);
BMState->preFilterSize=21;
BMState->preFilterCap=31;
BMState->SADWindowSize=21;
BMState->minDisparity=0;
BMState->numberOfDisparities=128;
BMState->textureThreshold=10;
BMState->uniquenessRatio=15;


cvFindStereoCorrespondenceBM( matr, matl, disp, BMState);
cvNormalize(disp, vdisp, 0, 255, CV_MINMAX);

cvShowImage("depthmap", vdisp);
cvWaitKey(0);
return 0;
}
user3634599
  • 49
  • 1
  • 1
  • 2

5 Answers5

4

Here's a code for disparity map using C++ API. Final image that you normalize should be of type CV_8UC1.

Mat img1, img2, g1, g2;
Mat disp, disp8;

img1 = imread("leftImage.jpg");
img2 = imread("rightImage.jpg");

cvtColor(img1, g1, CV_BGR2GRAY);
cvtColor(img2, g2, CV_BGR2GRAY);

StereoBM sbm;
sbm.state->SADWindowSize = 9;
sbm.state->numberOfDisparities = 112;
sbm.state->preFilterSize = 5;
sbm.state->preFilterCap = 61;
sbm.state->minDisparity = -39;
sbm.state->textureThreshold = 507;
sbm.state->uniquenessRatio = 0;
sbm.state->speckleWindowSize = 0;
sbm.state->speckleRange = 8;
sbm.state->disp12MaxDiff = 1;

sbm(g1, g2, disp);
normalize(disp, disp8, 0, 255, CV_MINMAX, CV_8U);

imshow("left", img1);
imshow("right", img2);
imshow("disp", disp8);
Froyo
  • 17,947
  • 8
  • 45
  • 73
  • thank you for answer, I changed type of image with CV_8UC1 but nothing changed at result. I have still an empty depth map. – user3634599 May 14 '14 at 06:32
  • There might be issues with images. And also, your StereoBM parameters. Try to vary them and see if you get something. Also, I'd prefer using C++ API over legacy api – Froyo May 14 '14 at 06:34
3

I can only add that structure of OpenCV namespaces and classes changes every year. I placed below working source code for OpenCV 3.4.0

#include <Windows.h>
#include <Vfw.h>
#include <string>
#include <iostream>


#include "opencv2\core\core.hpp"
#include "opencv2\imgproc\imgproc.hpp"
#include "opencv2\imgcodecs\imgcodecs.hpp"
#include "opencv2\highgui\highgui.hpp"
#include "opencv2\calib3d\calib3d.hpp"

using namespace std;
using namespace cv;


int _tmain(int argc, _TCHAR* argv[])
{
    Mat im_left=imread("right.png");
    Mat im_right=imread("left.png");
    cv::Size imagesize = im_left.size();
    cv::Mat disparity_left=cv::Mat(imagesize.height,imagesize.width,CV_16S);
    cv::Mat disparity_right=cv::Mat(imagesize.height,imagesize.width,CV_16S);
    cv::Mat g1,g2,disp,disp8;
    cv::cvtColor(im_left,g1,cv::COLOR_BGR2GRAY);
    cv::cvtColor(im_right,g2,cv::COLOR_BGR2GRAY);
    cv::Ptr<cv::StereoBM> sbm = cv::StereoBM::create(0,21);
    sbm->setDisp12MaxDiff(1);
    sbm->setSpeckleRange(8);
    sbm->setSpeckleWindowSize(9);
    sbm->setUniquenessRatio(0);
    sbm->setTextureThreshold(507);
    sbm->setMinDisparity(-39);
    sbm->setPreFilterCap(61);
    sbm->setPreFilterSize(5);
    sbm->compute(g1,g2,disparity_left);
    normalize(disparity_left, disp8, 0, 255, CV_MINMAX, CV_8U);
    cv::namedWindow("Left",CV_WINDOW_FREERATIO);
    cv::imshow("Left", im_left);
    cv::namedWindow("Right",CV_WINDOW_FREERATIO);
    cv::imshow("Right", im_right);
    cv::namedWindow("Depth map",CV_WINDOW_FREERATIO);
    cv::imshow("Depth map", disp8);
    cv::waitKey(0);
    return 0;
}
  • @VideoProcesingResearcher for StereoBM class, i get plenty of has no member error such as 'StereoBM has no member "create"', 'StereoBM has no member "setDisp12MaxDiff"', it gives the same error for all sbm methods, why that may occur? – Dilara Albayrak Jun 09 '18 at 11:22
  • What version of OpenCV do you use? Did you download ready binaries or you built OpenCV from source? Some OpenCV namespaces are not available in ready binaries. I built OpenCV 3.4.0 from source – VideoProcessingResearcher Jun 10 '18 at 20:05
2

For me it worked slightly different with the init of the stereoBM object

Ptr<StereoBM> sbm = cv::StereoBM::create(16, 5);

  sbm->setDisp12MaxDiff(1);
  sbm->setSpeckleRange(8);
  sbm->setSpeckleWindowSize(0);
  sbm->setUniquenessRatio(0);
  sbm->setTextureThreshold(507);
  sbm->setMinDisparity(-39);
  sbm->setPreFilterCap(61);
  sbm->setPreFilterSize(5);
  sbm->compute(src1, src2, disp);
Ilja S.
  • 61
  • 3
  • for StereoBM class, i get plenty of has no member error such as 'StereoBM has no member "create"', 'StereoBM has no member "setDisp12MaxDiff"', it gives the same error for all sbm methods, why that may occur? – Dilara Albayrak Jun 09 '18 at 11:23
2

I edited the code to my needs, I added the camera one and two, and reading from them. Then, made the Depth map. Thanks hope its helpful.

#include <string>
#include <iostream>
#include <opencv2/opencv.hpp>
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"

using namespace std;
using namespace cv;

int main()
{
    VideoCapture leftCam(0);      //lets say 0 is left, 1 is right
    if (leftCam.isOpened() == false){cout << "error: Webcam connect unsuccessful\n";    return(0);    }
    VideoCapture rightCam(1);     //lets say 0 is left, 1 is right
    if (rightCam.isOpened() == false){cout << "error: Webcam connect unsuccessful\n";   return(0);    }
    Mat left, right;    
    Mat leftClone, rightClone;

char charCheckForEscKey = 0;

while (    charCheckForEscKey != 27 && leftCam.isOpened()  )
{

    leftCam.read(left);
    if (left.empty()){cout << "No frame to read" << endl;  break;}      
    leftClone = left.clone();               //copy from the left camera 
    imwrite("left.png", leftClone);         // write it to screenshot.png in this directory

    rightCam.read(right);
    if (right.empty()){cout << "No frame to read" << endl;  break;}     
    rightClone = right.clone();             //copy from the left camera 
    imwrite("right.png", rightClone);           // write it to screenshot.png in this directory

        Mat im_left = imread("left.png"); //left cam picture
        Mat im_right = imread("right.png"); // right cam  picture 

        Size imagesize = im_left.size();
        Mat disparity_left= Mat(imagesize.height,imagesize.width,CV_16S);
        Mat disparity_right=Mat(imagesize.height,imagesize.width,CV_16S);
        Mat g1,g2,disp,disp8;
        cvtColor(im_left,g1, COLOR_BGR2GRAY);
        cvtColor(im_right,g2, COLOR_BGR2GRAY);

        Ptr<cv::StereoBM> sbm =  StereoBM::create(0,21);

        sbm->setDisp12MaxDiff(1);
        sbm->setSpeckleRange(8);
        sbm->setSpeckleWindowSize(9);
        sbm->setUniquenessRatio(0);
        sbm->setTextureThreshold(507);
        sbm->setMinDisparity(-39);
        sbm->setPreFilterCap(61);
        sbm->setPreFilterSize(5);
        sbm->compute(g1,g2,disparity_left);

        normalize(disparity_left, disp8, 0, 255, NORM_MINMAX, CV_8U);
        namedWindow("Left", WINDOW_AUTOSIZE);
        imshow("Left", im_left);

        namedWindow("Right", WINDOW_AUTOSIZE);
        imshow("Right", im_right);
        namedWindow("Depth map", WINDOW_AUTOSIZE);
        imshow("Depth map", disp8);

        namedWindow("Left Cloned", WINDOW_FREERATIO);
        imshow("Left Cloned", leftClone);   // left is the left pic taken from camera 0

        charCheckForEscKey = waitKey(1);    
}

return(0);

}

coding
  • 21
  • 2
1
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include<opencv2/calib3d.hpp>
int main()
{
cv::Mat leftimg =cv::imread("leftimage.jpg");
cv::Mat rightimg = cv::imread("rightimage.jpg");
cv::Mat disparity_left=cv::Mat(leftimg.size(),leftimg.type());
cv::Mat disparity_right=cv::Mat(rightimg.size(),rightimg .type());
cv::Mat g1,g2,disp,disp8;
cv::cvtColor(leftimg,g1,cv::COLOR_BGR2GRAY);
cv::cvtColor(rightimg,g2,cv::COLOR_BGR2GRAY);

cv::Ptr<cv::StereoBM> sbm = cv::createStereoBM(16,21);


sbm->setDisp12MaxDiff(1);
sbm->setSpeckleRange(8);
sbm->setSpeckleWindowSize(9);
sbm->setUniquenessRatio(0);
sbm->setTextureThreshold(507);
sbm->setMinDisparity(-39);
sbm->setPreFilterCap(61);
sbm->setPreFilterSize(5);
sbm->compute(g1,g2,disparity_left);
normalize(disparity_left, disp8, 0, 255, CV_MINMAX, CV_8U);

}
Nikita Chopra
  • 440
  • 9
  • 22
  • Actually I was not able to instantiate StereoBM and when I checked in header file calib3d.hpp I found it was an abstract class and thus cannot be instantiated so I created a pointer and then tried setting the values for the field. – Nikita Chopra Sep 25 '14 at 23:39
  • @NikitaChopra for StereoBM class, i get plenty of has no member error such as 'StereoBM has no member "create"', 'StereoBM has no member "setDisp12MaxDiff"', it gives the same error for all sbm methods, why that may occur? – Dilara Albayrak Jun 09 '18 at 11:22
  • If you check the class declaration in the corresponding header file, they are declared as an abstract class, therefore, creating an instance of the class will generate a no member error. Define a pointer to the class and then do the corresponding initialization to avoid no member error. Dig more in the header files. For example in the above case if you declare like this : StereoBM sbm; (This will generate an error ) whereas cv::Ptr sbm = cv::createStereoBM(16,21); (this will compile fine) – Nikita Chopra Jun 12 '18 at 21:09