-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
129 lines (115 loc) · 4.34 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "PMSType.h"
#include "PatchMatchStereo.h"
#include <opencv2/opencv.hpp>
void dispMatNorm(const sint32 &width, const sint32 &height, const float32 *dispMap, cv::Mat &dispMat) {
float32 minDisparity = FLT_MAX, maxDisparity = FLT_MIN;
for (sint32 i = 0; i < height; i++) {
for (sint32 j = 0; j < width; j++) {
const float32 disp = std::abs(dispMap[i * width + j]);
if (disp != Invalid_Float) {
minDisparity = std::min(minDisparity, disp);
maxDisparity = std::max(maxDisparity, disp);
}
}
}
for (uint32 i = 0; i < height; i++) {
for (uint32 j = 0; j < width; j++) {
const float32 disp = std::abs(dispMap[i * width + j]);
if (disp == Invalid_Float) {
dispMat.data[i * width + j] = 0;
} else {
dispMat.data[i * width + j] = static_cast<uchar>((disp - minDisparity) / (maxDisparity - minDisparity) *
255);
}
}
}
}
int main() {
// ··· 读取影像
std::string pathLeft = R"(..\data\cone\im2.png)";
std::string pathRight = R"(..\data\cone\im6.png)";
cv::Mat imgLeft = cv::imread(pathLeft, cv::IMREAD_COLOR);
cv::Mat imgRight = cv::imread(pathRight, cv::IMREAD_COLOR);
if (imgLeft.data == nullptr || imgRight.data == nullptr) {
std::cout << "Read Image Failed!" << std::endl;
return -1;
}
if (imgLeft.rows != imgRight.rows || imgLeft.cols != imgRight.cols) {
std::cout << "Image Size is Inconsistent!" << std::endl;
return -1;
}
// ··· SGM匹配
const auto width = static_cast<sint32>(imgLeft.cols);
const auto height = static_cast<sint32>(imgRight.rows);
// 左右影像的彩色数据
auto bytesLeft = new uint8[width * height * 3];
auto bytesRight = new uint8[width * height * 3];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
bytesLeft[i * 3 * width + 3 * j] = imgLeft.at<cv::Vec3b>(i, j)[0];
bytesLeft[i * 3 * width + 3 * j + 1] = imgLeft.at<cv::Vec3b>(i, j)[1];
bytesLeft[i * 3 * width + 3 * j + 2] = imgLeft.at<cv::Vec3b>(i, j)[2];
bytesRight[i * 3 * width + 3 * j] = imgRight.at<cv::Vec3b>(i, j)[0];
bytesRight[i * 3 * width + 3 * j + 1] = imgRight.at<cv::Vec3b>(i, j)[1];
bytesRight[i * 3 * width + 3 * j + 2] = imgRight.at<cv::Vec3b>(i, j)[2];
}
}
printf("Done!\n");
// PMS匹配参数设计
PMSOption psmOption;
// patch大小
psmOption._patchSize = 35;
// 候选视差范围
psmOption._minDisparity = 0;
psmOption._maxDisparity = 64;
// gamma
psmOption._gamma = 10.0f;
// alpha
psmOption._alpha = 0.9f;
// t_col
psmOption._tauCol = 10.0f;
// t_grad
psmOption._tauGrad = 2.0f;
// 传播迭代次数
psmOption._numIters = 3;
// 前端平行窗口
psmOption._isForceFpw = false;
// 整数视差精度
psmOption._isIntegerDisp = false;
// 一致性检查
psmOption._isCheckLR = true;
psmOption._lrCheckThres = 1.0f;
// 视差图填充
psmOption._isFillHoles = true;
PatchMatchStereo pms;
// 初始化
if (!pms.initialize(width, height, psmOption)) {
std::cout << "PMS Initialization Failure!" << std::endl;
return -2;
}
// 匹配
auto *disLeft = new float32[width * height];
auto *disRight = new float32[width * height];
if (!pms.match(bytesLeft, bytesRight, disLeft, disRight)) {
std::cout << "PMS Matching Failure!" << std::endl;
return -2;
}
// 显示视差图
cv::Mat dispMatLeft = cv::Mat(height, width, CV_8UC1);
cv::Mat dispMatRight = cv::Mat(height, width, CV_8UC1);
cv::Mat dispMat = cv::Mat(height, width * 2, CV_8UC1);
dispMatNorm(width, height, disLeft, dispMatLeft);
dispMatNorm(width, height, disRight, dispMatRight);
cv::hconcat(dispMatLeft, dispMatRight, dispMat);
cv::imwrite("../dispMatLeft.png", dispMatLeft);
cv::imshow("dispMatLeft", dispMatLeft);
cv::imwrite("../dispMatRight.png", dispMatRight);
cv::imshow("dispMatRight", dispMatRight);
cv::imshow("dispMat", dispMat);
cv::waitKey(0);
delete[] disLeft;
delete[] disRight;
disLeft = nullptr;
disRight = nullptr;
return 0;
}