Path: blob/master/Depth-Perception-Using-Stereo-Camera/cpp/disparity2depth_calib.cpp
3142 views
#include <opencv2/opencv.hpp>1#include <opencv2/calib3d/calib3d.hpp>2#include <opencv2/highgui/highgui.hpp>3#include <opencv2/imgproc/imgproc.hpp>4#include <stdio.h>5#include <iostream>6#include "opencv2/imgcodecs.hpp"78// initialize values for StereoSGBM parameters9int numDisparities = 8;10int blockSize = 5;11int preFilterType = 1;12int preFilterSize = 1;13int preFilterCap = 31;14int minDisparity = 0;15int textureThreshold = 10;16int uniquenessRatio = 15;17int speckleRange = 0;18int speckleWindowSize = 0;19int disp12MaxDiff = -1;202122cv::Mat imgL;23cv::Mat imgR;24cv::Mat imgL_gray;25cv::Mat imgR_gray;26cv::Mat disp, disparity, disp_8;2728std::vector<float> z_vec;29std::vector<cv::Point2f> coeff_vec;3031// These parameters can vary according to the setup32// Keeping the target object at max_dist we store disparity values33// after every sample_delta distance.34int max_dist = 230; // max distance to keep the target object (in cm)35int min_dist = 50; // Minimum distance the stereo setup can measure (in cm)36int sample_delta = 40; // Distance between two sampling points (in cm)37float Z = max_dist;3839// Defining callback functions for mouse events40void mouseEvent(int evt, int x, int y, int flags, void* param) {41float depth_val;4243if (evt == CV_EVENT_LBUTTONDOWN) {44depth_val = disparity.at<float>(y,x);4546if (depth_val > 0)47{48z_vec.push_back(Z);49coeff_vec.push_back(cv::Point2f(1.0f/(float)depth_val, 1.0f));50Z = Z-sample_delta;51}52}53}5455int main()56{5758// Creating an object of StereoBM algorithm59cv::Ptr<cv::StereoBM> stereo = cv::StereoBM::create();6061// Reading the stored the StereoBM parameters62cv::FileStorage cv_file = cv::FileStorage("../data/depth_estimation_params_cpp.xml", cv::FileStorage::READ);63cv_file["numDisparities"] >> numDisparities;64cv_file["blockSize"] >> blockSize;65cv_file["preFilterType"] >> preFilterType;66cv_file["preFilterSize"] >> preFilterSize;67cv_file["preFilterCap"] >> preFilterCap;68cv_file["minDisparity"] >> minDisparity;69cv_file["textureThreshold"] >> textureThreshold;70cv_file["uniquenessRatio"] >> uniquenessRatio;71cv_file["speckleRange"] >> speckleRange;72cv_file["speckleWindowSize"] >> speckleWindowSize;73cv_file["disp12MaxDiff"] >> disp12MaxDiff;7475// updating the parameter values of the StereoBM algorithm76stereo->setNumDisparities(numDisparities);77stereo->setBlockSize(blockSize);78stereo->setPreFilterType(preFilterType);79stereo->setPreFilterSize(preFilterSize);80stereo->setPreFilterCap(preFilterCap);81stereo->setTextureThreshold(textureThreshold);82stereo->setUniquenessRatio(uniquenessRatio);83stereo->setSpeckleRange(speckleRange);84stereo->setSpeckleWindowSize(speckleWindowSize);85stereo->setDisp12MaxDiff(disp12MaxDiff);86stereo->setMinDisparity(minDisparity);8788//Initialize variables to store the maps for stereo rectification89cv::Mat Left_Stereo_Map1, Left_Stereo_Map2;90cv::Mat Right_Stereo_Map1, Right_Stereo_Map2;9192// Reading the mapping values for stereo image rectification93cv::FileStorage cv_file2 = cv::FileStorage("../data/stereo_rectify_maps.xml", cv::FileStorage::READ);94cv_file2["Left_Stereo_Map_x"] >> Left_Stereo_Map1;95cv_file2["Left_Stereo_Map_y"] >> Left_Stereo_Map2;96cv_file2["Right_Stereo_Map_x"] >> Right_Stereo_Map1;97cv_file2["Right_Stereo_Map_y"] >> Right_Stereo_Map2;98cv_file2.release();99100// Check for left and right camera IDs101// These values can change depending on the system102int CamL_id{2}; // Camera ID for left camera103int CamR_id{0}; // Camera ID for right camera104105cv::VideoCapture camL(CamL_id), camR(CamR_id);106107// Check if left camera is attched108if (!camL.isOpened())109{110std::cout << "Could not open camera with index : " << CamL_id << std::endl;111return -1;112}113114// Check if right camera is attached115if (!camL.isOpened())116{117std::cout << "Could not open camera with index : " << CamL_id << std::endl;118return -1;119}120121cv::namedWindow("disparity",cv::WINDOW_NORMAL);122cv::resizeWindow("disparity",600,600);123cv::setMouseCallback("disparity", mouseEvent, NULL);124125while (true)126{127// Capturing and storing left and right camera images128camL >> imgL;129camR >> imgR;130131// Converting images to grayscale132cv::cvtColor(imgL, imgL_gray, cv::COLOR_BGR2GRAY);133cv::cvtColor(imgR, imgR_gray, cv::COLOR_BGR2GRAY);134135// Initialize matrix for rectified stero images136cv::Mat Left_nice, Right_nice;137138// Applying stereo image rectification on the left image139cv::remap(imgL_gray,140Left_nice,141Left_Stereo_Map1,142Left_Stereo_Map2,143cv::INTER_LANCZOS4,144cv::BORDER_CONSTANT,1450);146// Applying stereo image rectification on the right image147cv::remap(imgR_gray,148Right_nice,149Right_Stereo_Map1,150Right_Stereo_Map2,151cv::INTER_LANCZOS4,152cv::BORDER_CONSTANT,1530);154155// Calculating disparith using the StereoBM algorithm156stereo->compute(Left_nice,Right_nice,disp);157158// NOTE: compute returns a 16bit signed single channel image,159// CV_16S containing a disparity map scaled by 16. Hence it160// is essential to convert it to CV_16S and scale it down 16 times.161162// Converting disparity values to CV_32F from CV_16S163disp.convertTo(disparity,CV_32F, 1.0);164165// Scaling down the disparity values and normalizing them166disparity = (disparity/(float)16.0 - (float)minDisparity)/((float)numDisparities);167168// Displaying the disparity map169cv::imshow("disparity",disparity);170171// Close window using esc key172if (cv::waitKey(1) == 27) break;173174// Close program after taking reading for the last data point175if (Z <= min_dist) break;176177}178179//solving for M in the following equation180//|| depth = M * (1/disparity) ||181//for N data points coeff is Nx2 matrix with values182//1/disparity, 1183//and depth is Nx1 matrix with depth values184185cv::Mat Z_mat(z_vec.size(), 1, CV_32F, z_vec.data());186cv::Mat coeff(z_vec.size(), 2, CV_32F, coeff_vec.data());187188cv::Mat sol(2, 1, CV_32F);189float M;190191// Solving for M using least square fitting with QR decomposition method192cv::solve(coeff, Z_mat, sol, cv::DECOMP_QR);193194M = sol.at<float>(0,0);195196// Storing the updated value of M along with the stereo parameters197cv::FileStorage cv_file3 = cv::FileStorage("../data/depth_estimation_params_cpp.xml", cv::FileStorage::WRITE);198cv_file3.write("numDisparities",numDisparities);199cv_file3.write("blockSize",blockSize);200cv_file3.write("preFilterType",preFilterType);201cv_file3.write("preFilterSize",preFilterSize);202cv_file3.write("preFilterCap",preFilterCap);203cv_file3.write("textureThreshold",textureThreshold);204cv_file3.write("uniquenessRatio",uniquenessRatio);205cv_file3.write("speckleRange",speckleRange);206cv_file3.write("speckleWindowSize",speckleWindowSize);207cv_file3.write("disp12MaxDiff",disp12MaxDiff);208cv_file3.write("minDisparity",minDisparity);209cv_file3.write("M",M);210cv_file3.release();211212return 0;213}214215216