Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hackassin
GitHub Repository: hackassin/learnopencv
Path: blob/master/Depth-Perception-Using-Stereo-Camera/cpp/disparity2depth_calib.cpp
3142 views
1
#include <opencv2/opencv.hpp>
2
#include <opencv2/calib3d/calib3d.hpp>
3
#include <opencv2/highgui/highgui.hpp>
4
#include <opencv2/imgproc/imgproc.hpp>
5
#include <stdio.h>
6
#include <iostream>
7
#include "opencv2/imgcodecs.hpp"
8
9
// initialize values for StereoSGBM parameters
10
int numDisparities = 8;
11
int blockSize = 5;
12
int preFilterType = 1;
13
int preFilterSize = 1;
14
int preFilterCap = 31;
15
int minDisparity = 0;
16
int textureThreshold = 10;
17
int uniquenessRatio = 15;
18
int speckleRange = 0;
19
int speckleWindowSize = 0;
20
int disp12MaxDiff = -1;
21
22
23
cv::Mat imgL;
24
cv::Mat imgR;
25
cv::Mat imgL_gray;
26
cv::Mat imgR_gray;
27
cv::Mat disp, disparity, disp_8;
28
29
std::vector<float> z_vec;
30
std::vector<cv::Point2f> coeff_vec;
31
32
// These parameters can vary according to the setup
33
// Keeping the target object at max_dist we store disparity values
34
// after every sample_delta distance.
35
int max_dist = 230; // max distance to keep the target object (in cm)
36
int min_dist = 50; // Minimum distance the stereo setup can measure (in cm)
37
int sample_delta = 40; // Distance between two sampling points (in cm)
38
float Z = max_dist;
39
40
// Defining callback functions for mouse events
41
void mouseEvent(int evt, int x, int y, int flags, void* param) {
42
float depth_val;
43
44
if (evt == CV_EVENT_LBUTTONDOWN) {
45
depth_val = disparity.at<float>(y,x);
46
47
if (depth_val > 0)
48
{
49
z_vec.push_back(Z);
50
coeff_vec.push_back(cv::Point2f(1.0f/(float)depth_val, 1.0f));
51
Z = Z-sample_delta;
52
}
53
}
54
}
55
56
int main()
57
{
58
59
// Creating an object of StereoBM algorithm
60
cv::Ptr<cv::StereoBM> stereo = cv::StereoBM::create();
61
62
// Reading the stored the StereoBM parameters
63
cv::FileStorage cv_file = cv::FileStorage("../data/depth_estimation_params_cpp.xml", cv::FileStorage::READ);
64
cv_file["numDisparities"] >> numDisparities;
65
cv_file["blockSize"] >> blockSize;
66
cv_file["preFilterType"] >> preFilterType;
67
cv_file["preFilterSize"] >> preFilterSize;
68
cv_file["preFilterCap"] >> preFilterCap;
69
cv_file["minDisparity"] >> minDisparity;
70
cv_file["textureThreshold"] >> textureThreshold;
71
cv_file["uniquenessRatio"] >> uniquenessRatio;
72
cv_file["speckleRange"] >> speckleRange;
73
cv_file["speckleWindowSize"] >> speckleWindowSize;
74
cv_file["disp12MaxDiff"] >> disp12MaxDiff;
75
76
// updating the parameter values of the StereoBM algorithm
77
stereo->setNumDisparities(numDisparities);
78
stereo->setBlockSize(blockSize);
79
stereo->setPreFilterType(preFilterType);
80
stereo->setPreFilterSize(preFilterSize);
81
stereo->setPreFilterCap(preFilterCap);
82
stereo->setTextureThreshold(textureThreshold);
83
stereo->setUniquenessRatio(uniquenessRatio);
84
stereo->setSpeckleRange(speckleRange);
85
stereo->setSpeckleWindowSize(speckleWindowSize);
86
stereo->setDisp12MaxDiff(disp12MaxDiff);
87
stereo->setMinDisparity(minDisparity);
88
89
//Initialize variables to store the maps for stereo rectification
90
cv::Mat Left_Stereo_Map1, Left_Stereo_Map2;
91
cv::Mat Right_Stereo_Map1, Right_Stereo_Map2;
92
93
// Reading the mapping values for stereo image rectification
94
cv::FileStorage cv_file2 = cv::FileStorage("../data/stereo_rectify_maps.xml", cv::FileStorage::READ);
95
cv_file2["Left_Stereo_Map_x"] >> Left_Stereo_Map1;
96
cv_file2["Left_Stereo_Map_y"] >> Left_Stereo_Map2;
97
cv_file2["Right_Stereo_Map_x"] >> Right_Stereo_Map1;
98
cv_file2["Right_Stereo_Map_y"] >> Right_Stereo_Map2;
99
cv_file2.release();
100
101
// Check for left and right camera IDs
102
// These values can change depending on the system
103
int CamL_id{2}; // Camera ID for left camera
104
int CamR_id{0}; // Camera ID for right camera
105
106
cv::VideoCapture camL(CamL_id), camR(CamR_id);
107
108
// Check if left camera is attched
109
if (!camL.isOpened())
110
{
111
std::cout << "Could not open camera with index : " << CamL_id << std::endl;
112
return -1;
113
}
114
115
// Check if right camera is attached
116
if (!camL.isOpened())
117
{
118
std::cout << "Could not open camera with index : " << CamL_id << std::endl;
119
return -1;
120
}
121
122
cv::namedWindow("disparity",cv::WINDOW_NORMAL);
123
cv::resizeWindow("disparity",600,600);
124
cv::setMouseCallback("disparity", mouseEvent, NULL);
125
126
while (true)
127
{
128
// Capturing and storing left and right camera images
129
camL >> imgL;
130
camR >> imgR;
131
132
// Converting images to grayscale
133
cv::cvtColor(imgL, imgL_gray, cv::COLOR_BGR2GRAY);
134
cv::cvtColor(imgR, imgR_gray, cv::COLOR_BGR2GRAY);
135
136
// Initialize matrix for rectified stero images
137
cv::Mat Left_nice, Right_nice;
138
139
// Applying stereo image rectification on the left image
140
cv::remap(imgL_gray,
141
Left_nice,
142
Left_Stereo_Map1,
143
Left_Stereo_Map2,
144
cv::INTER_LANCZOS4,
145
cv::BORDER_CONSTANT,
146
0);
147
// Applying stereo image rectification on the right image
148
cv::remap(imgR_gray,
149
Right_nice,
150
Right_Stereo_Map1,
151
Right_Stereo_Map2,
152
cv::INTER_LANCZOS4,
153
cv::BORDER_CONSTANT,
154
0);
155
156
// Calculating disparith using the StereoBM algorithm
157
stereo->compute(Left_nice,Right_nice,disp);
158
159
// NOTE: compute returns a 16bit signed single channel image,
160
// CV_16S containing a disparity map scaled by 16. Hence it
161
// is essential to convert it to CV_16S and scale it down 16 times.
162
163
// Converting disparity values to CV_32F from CV_16S
164
disp.convertTo(disparity,CV_32F, 1.0);
165
166
// Scaling down the disparity values and normalizing them
167
disparity = (disparity/(float)16.0 - (float)minDisparity)/((float)numDisparities);
168
169
// Displaying the disparity map
170
cv::imshow("disparity",disparity);
171
172
// Close window using esc key
173
if (cv::waitKey(1) == 27) break;
174
175
// Close program after taking reading for the last data point
176
if (Z <= min_dist) break;
177
178
}
179
180
//solving for M in the following equation
181
//|| depth = M * (1/disparity) ||
182
//for N data points coeff is Nx2 matrix with values
183
//1/disparity, 1
184
//and depth is Nx1 matrix with depth values
185
186
cv::Mat Z_mat(z_vec.size(), 1, CV_32F, z_vec.data());
187
cv::Mat coeff(z_vec.size(), 2, CV_32F, coeff_vec.data());
188
189
cv::Mat sol(2, 1, CV_32F);
190
float M;
191
192
// Solving for M using least square fitting with QR decomposition method
193
cv::solve(coeff, Z_mat, sol, cv::DECOMP_QR);
194
195
M = sol.at<float>(0,0);
196
197
// Storing the updated value of M along with the stereo parameters
198
cv::FileStorage cv_file3 = cv::FileStorage("../data/depth_estimation_params_cpp.xml", cv::FileStorage::WRITE);
199
cv_file3.write("numDisparities",numDisparities);
200
cv_file3.write("blockSize",blockSize);
201
cv_file3.write("preFilterType",preFilterType);
202
cv_file3.write("preFilterSize",preFilterSize);
203
cv_file3.write("preFilterCap",preFilterCap);
204
cv_file3.write("textureThreshold",textureThreshold);
205
cv_file3.write("uniquenessRatio",uniquenessRatio);
206
cv_file3.write("speckleRange",speckleRange);
207
cv_file3.write("speckleWindowSize",speckleWindowSize);
208
cv_file3.write("disp12MaxDiff",disp12MaxDiff);
209
cv_file3.write("minDisparity",minDisparity);
210
cv_file3.write("M",M);
211
cv_file3.release();
212
213
return 0;
214
}
215
216