FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Merge pull request #15 from marcelsheeny/3d_reconstruction · codeplaysoftware/visioncpp@588cfa9 · GitHub

This repository was archived by the owner on Apr 29, 2024. It is now read-only.

Repository navigation

Commit 588cfa9

Browse files
Luke Iwanski
authored
Merge pull request #15 from marcelsheeny/3d_reconstruction
adding depth map reconstruction
2 parents a257e34 + e49c92b commit 588cfa9

3 files changed

Lines changed: 193 additions & 0 deletions

File tree

‎data/tsukuba_l.png‎

83.2 KB
LoadingViewer requires iframe.

‎data/tsukuba_r.png‎

83.1 KB
LoadingViewer requires iframe.
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
// This file is part of VisionCPP, a lightweight C++ template library
2+
// for computer vision and image processing.
3+
//
4+
// Copyright (C) 2016 Codeplay Software Limited. All Rights Reserved.
5+
//
6+
// Contact: visioncpp@codeplay.com
7+
//
8+
// Licensed under the Apache License, Version 2.0 (the "License");
9+
// you may not use this file except in compliance with the License.
10+
// You may obtain a copy of the License at
11+
//
12+
// http://www.apache.org/licenses/LICENSE-2.0
13+
//
14+
// Unless required by applicable law or agreed to in writing, software
15+
// distributed under the License is distributed on an "AS IS" BASIS,
16+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
// See the License for the specific language governing permissions and
18+
// limitations under the License.
19+
20+
/// \file depth_map_from_2_images.cpp
21+
///
22+
/// ---------Example---------
23+
/// Depth Map From 2 images
24+
///
25+
/// \brief This example implements a Depth Map reconstruction from two images
26+
/// using the block match algorithm
27+
/// \param blockSize - this parameter defines the size of the block to be
28+
/// searched
29+
/// \param maxDisp - this parameter defines the maximum disparity between
30+
/// pixels. It means the max number of pixels it will be used to search for the
31+
/// best match.
32+
33+
// include OpenCV for camera display
34+
#include <opencv2/opencv.hpp>
35+
36+
// include VisionCpp
37+
#include <visioncpp.hpp>
38+
39+
// include limits to define infinity
40+
#include <limits>
41+
42+
// Tunable parameters for the algorithm
43+
constexpr int blockSize = 11;
44+
constexpr int maxDisp = 25;
45+
46+
constexpr int halfBlock = blockSize / 2;
47+
48+
// Stereo block matching algorithm for depth map reconstruction
49+
struct Stereo_BMA {
50+
// function that computers the sum of absolute difference of two blocks
51+
float SAD(const float im1[blockSize * blockSize],
52+
const float im2[blockSize * blockSize]) {
53+
float r = 0;
54+
for (size_t i = 0; i < blockSize * blockSize; i++) {
55+
r += cl::sycl::fabs(im1[i] - im2[i]);
56+
}
57+
return r;
58+
}
59+
60+
// Function to get block of size blockSize frin (c,r) pixel
61+
template <typename T>
62+
void getBlock(const T& I, const int& c, const int& r, const int& layer,
63+
float block[blockSize * blockSize]) {
64+
int cnt = 0;
65+
for (int i2 = -halfBlock; i2 <= halfBlock; i2++) {
66+
for (int j2 = -halfBlock; j2 <= halfBlock; j2++) {
67+
block[cnt++] = I.at(c + i2, r + j2)[layer];
68+
}
69+
}
70+
}
71+
72+
// function that computes the depth map
73+
template <typename T>
74+
visioncpp::pixel::U8C1 operator()(const T& I) {
75+
// get block from left image
76+
float block_l[blockSize * blockSize];
77+
getBlock(I, I.I_c, I.I_r, 0, block_l);
78+
79+
// start with best sum of absolute difference equals to infinity
80+
float bestSAD = std::numeric_limits<float>::infinity();
81+
int bestJ = I.I_c;
82+
83+
// for loop to find best match
84+
float block_r[blockSize * blockSize];
85+
for (int m = 0; m < maxDisp; m++) {
86+
// get block from right image
87+
getBlock(I, I.I_c - m, I.I_r, 1, block_r);
88+
89+
// sum of absolute difference
90+
float temp = SAD(block_l, block_r);
91+
92+
// store the smallest SAD
93+
if (temp < bestSAD) {
94+
bestSAD = temp;
95+
bestJ = I.I_c - m;
96+
}
97+
}
98+
99+
// Compute disparity value
100+
return visioncpp::pixel::U8C1(I.I_c - bestJ);
101+
}
102+
};
103+
104+
// main program
105+
int main(int argc, char** argv) {
106+
// load images left and write in gray scale
107+
cv::Mat input_l =
108+
cv::imread("../data/tsukuba_l.png", CV_LOAD_IMAGE_GRAYSCALE);
109+
cv::Mat input_r =
110+
cv::imread("../data/tsukuba_r.png", CV_LOAD_IMAGE_GRAYSCALE);
111+
112+
if (!input_l.data || !input_r.data) { // check if we succeeded
113+
std::cout << "Loading image failed." << std::endl;
114+
return -1;
115+
}
116+
117+
// selecting device
118+
auto dev = visioncpp::make_device<visioncpp::backend::sycl,
119+
visioncpp::device::cpu>();
120+
121+
// defining the image size constants
122+
constexpr size_t COLS = 640;
123+
constexpr size_t ROWS = 480;
124+
125+
// resize images
126+
cv::resize(input_l, input_l, cv::Size(COLS, ROWS), 0, 0, cv::INTER_CUBIC);
127+
cv::resize(input_r, input_r, cv::Size(COLS, ROWS), 0, 0, cv::INTER_CUBIC);
128+
129+
// Shared Memory variable
130+
constexpr size_t SM = 16;
131+
132+
// creating a pointer to store the results
133+
std::shared_ptr<unsigned char> output(
134+
new unsigned char[COLS * ROWS],
135+
[](unsigned char* dataMem) { delete[] dataMem; });
136+
137+
// init output image from OpenCV for displaying results
138+
cv::Mat outputImage(ROWS, COLS, CV_8UC1, output.get());
139+
140+
// the node which gets the input data from OpenCV
141+
{
142+
// store the left image in the terminal node
143+
auto in_l =
144+
visioncpp::terminal<visioncpp::pixel::U8C1, COLS, ROWS,
145+
visioncpp::memory_type::Buffer2D>(input_l.data);
146+
147+
// store the right image in the terminal node
148+
auto in_r =
149+
visioncpp::terminal<visioncpp::pixel::U8C1, COLS, ROWS,
150+
visioncpp::memory_type::Buffer2D>(input_r.data);
151+
152+
// the node which gets the output data
153+
auto out =
154+
visioncpp::terminal<visioncpp::pixel::U8C1, COLS, ROWS,
155+
visioncpp::memory_type::Buffer2D>(output.get());
156+
157+
// convert images to float
158+
auto fgrey_l = visioncpp::point_operation<visioncpp::OP_U8C1ToFloat>(in_l);
159+
auto fgrey_r = visioncpp::point_operation<visioncpp::OP_U8C1ToFloat>(in_r);
160+
161+
// merge images
162+
auto merge =
163+
visioncpp::point_operation<visioncpp::OP_Merge2Chns>(fgrey_l, fgrey_r);
164+
165+
// compute depth map
166+
auto depth = visioncpp::neighbour_operation<
167+
Stereo_BMA, halfBlock, halfBlock + maxDisp, halfBlock, halfBlock>(
168+
merge);
169+
170+
// convert to unsigned char for displaying purposes
171+
// scale threhold to display
172+
auto scale_node = visioncpp::terminal<float, visioncpp::memory_type::Const>(
173+
static_cast<float>(8.0f));
174+
auto display =
175+
visioncpp::point_operation<visioncpp::OP_Scale>(depth, scale_node);
176+
177+
// assign to the output
178+
auto exec = visioncpp::assign(out, display);
179+
180+
// execute expression tree
181+
visioncpp::execute<visioncpp::policy::Fuse, SM, SM, SM, SM>(exec, dev);
182+
}
183+
184+
// Display results
185+
cv::imshow("Image left", input_l);
186+
cv::imshow("Image right", input_r);
187+
cv::imshow("Depth Map", outputImage);
188+
189+
// wait key to be pressed to finalize
190+
cv::waitKey(0);
191+
192+
return 0;
193+
}

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL