Skip to content
Snippets Groups Projects
Commit 2c572c75 authored by Sebastian Hahta's avatar Sebastian Hahta
Browse files

import libsgm

parent 9fa4ce41
No related branches found
No related tags found
1 merge request!293Move libsgm code to lib/libsgm
Showing
with 1311 additions and 0 deletions
cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CUDA_ARCH "-arch=sm_50" CACHE STRING "Value of the NVCC -arch option.")
option(ENABLE_ZED_DEMO "Build a Demo using ZED Camera" OFF)
option(ENABLE_SAMPLES "Build samples" OFF)
option(ENABLE_TESTS "Test library" OFF)
option(LIBSGM_SHARED "Build a shared library" OFF)
option(BUILD_OPENCV_WRAPPER "Make library compatible with cv::Mat and cv::cuda::GpuMat of OpenCV" OFF)
if(WIN32)
set(ZED_SDK_LIB "C:\\Program Files (x86)\\ZED SDK\\lib\\sl_zed64.lib" CACHE STRING "ZED SDK library(sl_zed**.llb) path.")
set(ZED_SDK_INCLUDE_DIR "C:\\Program Files (x86)\\ZED SDK\\include" CACHE STRING "ZED SDK include path.")
else()
set(ZED_SDK_LIB "/usr/local/zed/lib/libsl_zed.so" CACHE STRING "ZED SDK library(sl_zed**.llb) path.")
set(ZED_SDK_INCLUDE_DIR "/usr/local/zed/include" CACHE STRING "ZED SDK include path.")
endif()
project(libSGM VERSION 2.4.0)
if(BUILD_OPENCV_WRAPPER)
find_package(OpenCV REQUIRED core)
include_directories(${OpenCV_INCLUDE_DIRS})
endif()
configure_file(${CMAKE_SOURCE_DIR}/include/libsgm_config.h.in
${CMAKE_SOURCE_DIR}/include/libsgm_config.h
)
add_subdirectory(src)
if(ENABLE_SAMPLES)
add_subdirectory(sample/image)
add_subdirectory(sample/movie)
# add_subdirectory(sample/reprojection)
add_subdirectory(sample/benchmark)
if(BUILD_OPENCV_WRAPPER)
add_subdirectory(sample/image_cv_gpumat)
endif()
endif()
if(ENABLE_TESTS)
add_subdirectory(test)
endif()
if(ENABLE_ZED_DEMO)
add_subdirectory(sample/zed)
endif()
###############################################################################
# Find LibSGM
#
# This sets the following variables:
# LIBSGM_FOUND - True if LIBSGM was found.
# LIBSGM_INCLUDE_DIRS - Directories containing the LIBSGM include files.
# LIBSGM_LIBRARY - Libraries needed to use LIBSGM.
# Find lib
set(LIBSGM_FOUND FALSE CACHE BOOL "" FORCE)
find_library(LIBSGM_LIBRARY
NAMES sgm libsgm
PATH_SUFFIXES lib/
)
# Find include
find_path(LIBSGM_INCLUDE_DIRS
NAMES libsgm.h
PATH_SUFFIXES include/
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LibSGM DEFAULT_MSG LIBSGM_LIBRARY LIBSGM_INCLUDE_DIRS)
message(STATUS "(LIBSGM_FOUND : ${LIBSGM_FOUND} include: ${LIBSGM_INCLUDE_DIRS}, lib: ${LIBSGM_LIBRARY})")
mark_as_advanced(LIBSGM_FOUND)
if(LIBSGM_FOUND)
set(LIBSGM_FOUND TRUE CACHE BOOL "" FORCE)
set(LIBSGM_LIBRARIES ${LIBSGM_LIBRARY})
message(STATUS "LibSGM found ( include: ${LIBSGM_INCLUDE_DIRS}, lib: ${LIBSGM_LIBRARY})")
endif()
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
# libSGM
---
Semi-Global MatchingをベースとしたCUDA実装です。
## 概要
---
libSGMは、Semi-Global MatchingアルゴリズムをCUDAで実装したものです。
適切にキャリブレーションされた2つの入力画像から、視差画像を取得することができます。
## 特徴
---
CUDAを使用し、高速な視差画像算出が可能
## パフォーマンス
benchmarkサンプルで計測した処理時間を示します
### Settings
- image size : 1024 x 440
- disparity size : 128
- sgm path : 8 path
### Results
|Device|Processing Time[Milliseconds]|FPS|
|---|---|---|
|Tegra X2|52.4|19.1|
|GTX 1080 Ti|3.4|296|
## Requirements
libSGMはCUDA (compute capabilities >= 3.0)を必要とします。
また、サンプルをビルドする際には以下のライブラリが必要となります。
- OpenCV 3.0 以降
- CMake 3.10 以降
## build
```
$ git clone https://github.com/fixstars/libSGM.git
$ cd libSGM
$ mkdir build
$ cd build
$ cmake ../
$ make
```
## サンプル実行
```
$ pwd
.../libSGM
$ cd build
$ cd sample/movie/
$ ./stereo_movie <left image path format> <right image path format> <disparity> <frame count>
left image path format: 左側画像入力時に使用するファイルパスのフォーマット
right image path format: 右側画像入力時に使用するファイルパスのフォーマット
disparity: 視差情報を何段階で保持するか(省略可)
frame count: 全画像が何枚存在するか(省略可)
```
disparityとframe countは省略が可能です。省略した時には、それぞれ64, 100が付与されます。
ここで、left image path format, right image path formatとは、ファイル読み込み時に使用するフォーマットを意味します。
次のような連番ファイルが与えられていたとき、与えるべきpath formatは以下のようになります。
```
left_image_0000.pgm
left_image_0001.pgm
left_image_0002.pgm
left_image_0003.pgm
...
right_image_0000.pgm
right_image_0001.pgm
right_image_0002.pgm
right_image_0003.pgm
```
```
$ ./stereo_movie left_image_%04d.pgm right_image_%04d.pgm
```
movie, imageサンプルは、
http://www.6d-vision.com/scene-labeling
にて提供されている、Daimler Urban Scene Segmentation Benchmark Datasetにて
動作確認をしています。
## Authors
The "SGM Team": Samuel Audet, Yoriyuki Kitta, Yuta Noto, Ryo Sakamoto, Akihiro Takagi
[Fixstars Corporation](http://www.fixstars.com/)
## License
Apache License 2.0
# libSGM
---
A CUDA implementation performing Semi-Global Matching.
## Introduction
---
libSGM is library that implements in CUDA the Semi-Global Matching algorithm.
From a pair of appropriately calibrated input images, we can obtain the disparity map.
## Features
---
Because it uses CUDA, we can compute the disparity map at high speed.
## Performance
The libSGM performance obtained from benchmark sample
### Settings
- image size : 1024 x 440
- disparity size : 128
- sgm path : 8 path
### Results
|Device|Processing Time[Milliseconds]|FPS|
|---|---|---|
|Tegra X2|52.4|19.1|
|GTX 1080 Ti|3.4|296|
## Requirements
libSGM needs CUDA (compute capabilities >= 3.0) to be installed.
Moreover, to build the sample, we need the following libraries:
- OpenCV 3.0 or later
- CMake 3.10 or later
## Build Instructions
```
$ git clone https://github.com/fixstars/libSGM.git
$ cd libSGM
$ mkdir build
$ cd build
$ cmake ../
$ make
```
## Sample Execution
```
$ pwd
.../libSGM
$ cd build
$ cd sample/movie/
$ ./stereo_movie <left image path format> <right image path format> <disparity> <frame count>
left image path format: the format used for the file paths to the left input images
right image path format: the format used for the file paths to the right input images
disparity: the maximum number of disparities (optional)
frame count: the total number of images (optional)
```
"disparity" and "frame count" are optional. By default, they are 64 and 100, respectively.
Next, we explain the meaning of the "left image path format" and "right image path format".
When provided with the following set of files, we should pass the "path formats" given below.
```
left_image_0000.pgm
left_image_0001.pgm
left_image_0002.pgm
left_image_0003.pgm
...
right_image_0000.pgm
right_image_0001.pgm
right_image_0002.pgm
right_image_0003.pgm
```
```
$ ./stereo_movie left_image_%04d.pgm right_image_%04d.pgm
```
The sample movie images available at
http://www.6d-vision.com/scene-labeling
under "Daimler Urban Scene Segmentation Benchmark Dataset"
are used to test the software.
## Authors
The "SGM Team": Samuel Audet, Yoriyuki Kitta, Yuta Noto, Ryo Sakamoto, Akihiro Takagi
[Fixstars Corporation](http://www.fixstars.com/)
## License
Apache License 2.0
/*
Copyright 2016 Fixstars Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http ://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
/**
* @mainpage stereo-sgm
* See sgm::StereoSGM
*/
/**
* @file libsgm.h
* stereo-sgm main header
*/
#include <stdint.h>
#include "libsgm_config.h"
#if defined(LIBSGM_SHARED)
#if defined(WIN32) || defined(_WIN32)
#if defined sgm_EXPORTS
#define LIBSGM_API __declspec(dllexport)
#else
#define LIBSGM_API __declspec(dllimport)
#endif
#else
#define LIBSGM_API __attribute__((visibility("default")))
#endif
#else
#define LIBSGM_API
#endif
namespace sgm {
struct CudaStereoSGMResources;
/**
* @enum DST_TYPE
* Indicates input/output pointer type.
*/
enum EXECUTE_INOUT {
EXECUTE_INOUT_HOST2HOST = (0 << 1) | 0,
EXECUTE_INOUT_HOST2CUDA = (1 << 1) | 0,
EXECUTE_INOUT_CUDA2HOST = (0 << 1) | 1,
EXECUTE_INOUT_CUDA2CUDA = (1 << 1) | 1,
};
/**
* @brief StereoSGM class
*/
class StereoSGM {
public:
static const int SUBPIXEL_SHIFT = 4;
static const int SUBPIXEL_SCALE = (1 << SUBPIXEL_SHIFT);
struct Parameters
{
int P1;
int P2;
float uniqueness;
bool subpixel;
Parameters(int P1 = 10, int P2 = 120, float uniqueness = 0.95f, bool subpixel = false) : P1(P1), P2(P2), uniqueness(uniqueness), subpixel(subpixel) {}
};
/**
* @param width Processed image's width.
* @param height Processed image's height.
* @param disparity_size It must be 64 or 128.
* @param input_depth_bits Processed image's bits per pixel. It must be 8 or 16.
* @param output_depth_bits Disparity image's bits per pixel. It must be 8 or 16.
* @param inout_type Specify input/output pointer type. See sgm::EXECUTE_TYPE.
* @attention
* output_depth_bits must be set to 16 when subpixel is enabled.
*/
LIBSGM_API StereoSGM(int width, int height, int disparity_size, int input_depth_bits, int output_depth_bits,
EXECUTE_INOUT inout_type, const Parameters& param = Parameters());
/**
* @param width Processed image's width.
* @param height Processed image's height.
* @param disparity_size It must be 64 or 128.
* @param input_depth_bits Processed image's bits per pixel. It must be 8 or 16.
* @param output_depth_bits Disparity image's bits per pixel. It must be 8 or 16.
* @param src_pitch Source image's pitch (pixels).
* @param dst_pitch Destination image's pitch (pixels).
* @param inout_type Specify input/output pointer type. See sgm::EXECUTE_TYPE.
* @attention
* output_depth_bits must be set to 16 when subpixel is enabled.
*/
LIBSGM_API StereoSGM(int width, int height, int disparity_size, int input_depth_bits, int output_depth_bits, int src_pitch, int dst_pitch,
EXECUTE_INOUT inout_type, const Parameters& param = Parameters());
LIBSGM_API virtual ~StereoSGM();
/**
* Execute stereo semi global matching.
* @param left_pixels A pointer stored input left image.
* @param right_pixels A pointer stored input right image.
* @param dst Output pointer. User must allocate enough memory.
* @attention
* You need to allocate dst memory at least width x height x sizeof(element_type) bytes.
* The element_type is uint8_t for output_depth_bits == 8 and uint16_t for output_depth_bits == 16.
* Note that dst element value would be multiplied StereoSGM::SUBPIXEL_SCALE if subpixel option was enabled.
*/
LIBSGM_API void execute(const void* left_pixels, const void* right_pixels, void* dst);
/**
* Same as execute(left_pixels, right_pixels, dst) with image size parameters.
* Dimensions must be smaller or equal to dimensions provided in constructor.
*/
LIBSGM_API void execute(const void* left_pixels, const void* right_pixels, void* dst, const int width, const int height, const int src_pitch, const int dst_pitch);
/**
* Mask for invalid pixels. Must have same shape and pitch as src. Pixels which have non-zero values
* will be masked in final disparity image.
*/
LIBSGM_API void setMask(uint8_t* mask, int pitch);
/**
* Update parameters. Returns true if successful.
*/
LIBSGM_API bool updateParameters(const Parameters &params);
private:
StereoSGM(const StereoSGM&);
StereoSGM& operator=(const StereoSGM&);
void cuda_resource_allocate();
CudaStereoSGMResources* cu_res_;
int width_;
int height_;
int disparity_size_;
int input_depth_bits_;
int output_depth_bits_;
int src_pitch_;
int dst_pitch_;
EXECUTE_INOUT inout_type_;
Parameters param_;
};
}
#include "libsgm_wrapper.h"
#ifndef __LIBSGM_CONFIG_H__
#define __LIBSGM_CONFIG_H__
/* #undef LIBSGM_SHARED */
#define LIBSGM_VERSION 2.4.0
#define LIBSGM_VERSION_MAJOR 2
#define LIBSGM_VERSION_MINOR 4
#define LIBSGM_VERSION_PATCH 0
/* #undef BUILD_OPENCV_WRAPPER */
#endif // __LIBSGM_CONFIG_H__
#ifndef __LIBSGM_CONFIG_H__
#define __LIBSGM_CONFIG_H__
#cmakedefine LIBSGM_SHARED
#define LIBSGM_VERSION @libSGM_VERSION@
#define LIBSGM_VERSION_MAJOR @libSGM_VERSION_MAJOR@
#define LIBSGM_VERSION_MINOR @libSGM_VERSION_MINOR@
#define LIBSGM_VERSION_PATCH @libSGM_VERSION_PATCH@
#cmakedefine BUILD_OPENCV_WRAPPER
#endif // __LIBSGM_CONFIG_H__
#ifndef __LIBSGM_WRAPPER_H__
#define __LIBSGM_WRAPPER_H__
#include "libsgm.h"
#include <memory>
#ifdef BUILD_OPENCV_WRAPPER
#include <opencv2/core/cuda.hpp>
#endif
namespace sgm {
/**
* @brief LibSGMWrapper class which is wrapper for sgm::StereoSGM.
*/
class LibSGMWrapper {
public:
/**
* @param numDisparity Maximum possible disparity value
* @param P1 Penalty on the disparity change by plus or minus 1 between nieghbor pixels
* @param P2 Penalty on the disparity change by more than 1 between neighbor pixels
* @param uniquenessRatio Margin in ratio by which the best cost function value should be at least second one
* @param subpixel Disparity value has 4 fractional bits if subpixel option is enabled
*/
LIBSGM_API LibSGMWrapper(int numDisparity = 128, int P1 = 10, int P2 = 120, float uniquenessRatio = 0.95f, bool subpixel = false);
LIBSGM_API ~LibSGMWrapper();
LIBSGM_API int getNumDisparities() const;
LIBSGM_API int getP1() const;
LIBSGM_API int getP2() const;
LIBSGM_API float getUniquenessRatio() const;
LIBSGM_API bool hasSubpixel() const;
#ifdef BUILD_OPENCV_WRAPPER
/**
* Execute stereo semi global matching via wrapper class
* @param I1 Input left image. Image's type is must be CV_8U or CV_16U
* @param I2 Input right image. Image's size and type must be same with I1.
* @param disparity Output image. Its memory will be allocated automatically dependent on input image size.
* @attention
* type of output image `disparity` is CV_16U.
* Note that disparity element value would be multiplied StereoSGM::SUBPIXEL_SCALE if subpixel option was enabled.
*/
LIBSGM_API void execute(const cv::cuda::GpuMat& I1, const cv::cuda::GpuMat& I2, cv::cuda::GpuMat& disparity);
/**
* Execute stereo semi global matching via wrapper class
* @param I1 Input left image. Image's type is must be CV_8U or CV_16U
* @param I2 Input right image. Image's size and type must be same with I1.
* @param disparity Output image. Its memory will be allocated automatically dependent on input image size.
* @attention
* type of output image `disparity` is CV_16U.
* Note that disparity element value would be multiplied StereoSGM::SUBPIXEL_SCALE if subpixel option was enabled.
*/
LIBSGM_API void execute(const cv::Mat& I1, const cv::Mat& I2, cv::Mat& disparity);
#endif // BUILD_OPRENCV_WRAPPER
private:
struct Creator;
std::unique_ptr<sgm::StereoSGM> sgm_;
int numDisparity_;
sgm::StereoSGM::Parameters param_;
std::unique_ptr<Creator> prev_;
};
}
#endif // __LIBSGM_WRAPPER_H__
cmake_minimum_required(VERSION 3.1)
set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-O3 -Wall")
endif()
find_package(CUDA REQUIRED)
find_package(OpenCV REQUIRED)
if (OpenCV_VERSION VERSION_LESS 3.0)
message(FATAL_ERROR "Error: OpenCV version requires at least 3.0")
endif()
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(../../include)
cuda_add_executable(stereo_benchmark stereosgm_benchmark.cpp)
target_link_libraries(stereo_benchmark sgm ${CUDA_LIBRARIES} ${OpenCV_LIBS})
/*
Copyright 2016 Fixstars Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http ://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <iostream>
#include <iomanip>
#include <chrono>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cuda_runtime.h>
#include <libsgm.h>
#define ASSERT_MSG(expr, msg) \
if (!(expr)) { \
std::cerr << msg << std::endl; \
std::exit(EXIT_FAILURE); \
} \
struct device_buffer
{
device_buffer() : data(nullptr) {}
device_buffer(size_t count) { allocate(count); }
void allocate(size_t count) { cudaMalloc(&data, count); }
~device_buffer() { cudaFree(data); }
void* data;
};
int main(int argc, char* argv[])
{
if (argc < 3) {
std::cout << "usage: " << argv[0] << " left_img right_img [disp_size] [out_depth] [subpixel_enable(0: false, 1:true)] [iterations]" << std::endl;
std::exit(EXIT_FAILURE);
}
cv::Mat I1 = cv::imread(argv[1], -1);
cv::Mat I2 = cv::imread(argv[2], -1);
ASSERT_MSG(!I1.empty() && !I2.empty(), "imread failed.");
ASSERT_MSG(I1.size() == I2.size() && I1.type() == I2.type(), "input images must be same size and type.");
ASSERT_MSG(I1.type() == CV_8U || I1.type() == CV_16U, "input image format must be CV_8U or CV_16U.");
const int disp_size = argc > 3 ? std::stoi(argv[3]) : 128;
const int out_depth = argc > 4 ? std::stoi(argv[4]) : 8;
const bool subpixel = argc > 5 ? std::stoi(argv[5]) != 0 : false;
ASSERT_MSG(disp_size == 64 || disp_size == 128, "disparity size must be 64 or 128.");
if (subpixel) {
ASSERT_MSG(out_depth == 16, "output depth bits must be 16 if subpixel option is enabled.");
} else {
ASSERT_MSG(out_depth == 8 || out_depth == 16, "output depth bits must be 8 or 16");
}
const int iterations = argc > 6 ? std::stoi(argv[6]) : 100;
const int width = I1.cols;
const int height = I1.rows;
const int input_depth = I1.type() == CV_8U ? 8 : 16;
const int input_bytes = input_depth * width * height / 8;
const int output_bytes = out_depth * width * height / 8;
const sgm::StereoSGM::Parameters params{10, 120, 0.95f, subpixel};
sgm::StereoSGM sgm(width, height, disp_size, input_depth, out_depth, sgm::EXECUTE_INOUT_CUDA2CUDA, params);
device_buffer d_I1(input_bytes), d_I2(input_bytes), d_disparity(output_bytes);
cudaMemcpy(d_I1.data, I1.data, input_bytes, cudaMemcpyHostToDevice);
cudaMemcpy(d_I2.data, I2.data, input_bytes, cudaMemcpyHostToDevice);
cudaDeviceProp prop;
int version;
cudaGetDeviceProperties(&prop, 0);
cudaRuntimeGetVersion(&version);
// show settings
std::cout << "# Settings" << std::endl;
std::cout << "device name : " << prop.name << std::endl;
std::cout << "CUDA runtime version: " << version << std::endl;
std::cout << "image size : " << I1.size() << std::endl;
std::cout << "disparity size : " << disp_size << std::endl;
std::cout << "output depth : " << out_depth << std::endl;
std::cout << "subpixel option : " << (subpixel ? "true" : "false") << std::endl;
std::cout << "sgm path : " << "8 path" << std::endl;
std::cout << "iterations : " << iterations << std::endl;
std::cout << std::endl;
// run benchmark
std::cout << "Running benchmark..." << std::endl;
uint64_t sum = 0;
for (int i = 0; i <= iterations; i++) {
const auto t1 = std::chrono::system_clock::now();
sgm.execute(d_I1.data, d_I2.data, d_disparity.data);
cudaDeviceSynchronize();
const auto t2 = std::chrono::system_clock::now();
if (i > 0)
sum += std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
}
std::cout << "Done." << std::endl << std::endl;
// show results
const double time_millisec = 1e-3 * sum / iterations;
const double fps = 1e3 / time_millisec;
std::cout << "# Results" << std::endl;
std::cout.setf(std::ios::fixed);
std::cout << std::setprecision(1) << "Processing Time[Milliseconds]: " << time_millisec << std::endl;
std::cout << std::setprecision(1) << "FPS : " << fps << std::endl;
std::cout << std::endl;
// save disparity image
cv::Mat disparity(height, width, out_depth == 8 ? CV_8U : CV_16U);
cudaMemcpy(disparity.data, d_disparity.data, output_bytes, cudaMemcpyDeviceToHost);
disparity *= 255. / disp_size;
cv::imwrite("disparity.png", disparity);
return 0;
}
cmake_minimum_required(VERSION 3.1)
set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-O3 -Wall")
endif()
find_package(CUDA REQUIRED)
find_package(OpenCV REQUIRED)
if (OpenCV_VERSION VERSION_LESS 3.0)
message(FATAL_ERROR "Error: OpenCV version requires at least 3.0")
endif()
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(../../include)
cuda_add_executable(stereo_test stereosgm_image.cpp)
target_link_libraries(stereo_test sgm ${CUDA_LIBRARIES} ${OpenCV_LIBS})
/*
Copyright 2016 Fixstars Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http ://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <stdlib.h>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/version.hpp>
#include <libsgm.h>
#define ASSERT_MSG(expr, msg) \
if (!(expr)) { \
std::cerr << msg << std::endl; \
std::exit(EXIT_FAILURE); \
} \
int main(int argc, char* argv[]) {
if (argc < 3) {
std::cerr << "usage: stereosgm left_img right_img [disp_size]" << std::endl;
std::exit(EXIT_FAILURE);
}
cv::Mat left = cv::imread(argv[1], -1);
cv::Mat right = cv::imread(argv[2], -1);
int disp_size = 64;
if (argc >= 4) {
disp_size = atoi(argv[3]);
}
ASSERT_MSG(left.size() == right.size() && left.type() == right.type(), "input images must be same size and type.");
//ASSERT_MSG(left.type() == CV_8U || left.type() == CV_16U, "input image format must be CV_8U or CV_16U.");
ASSERT_MSG(disp_size == 64 || disp_size == 128 || disp_size == 256, "disparity size must be 64, 128 or 256.");
cv::resize(left, left, cv::Size(left.cols/2, left.rows/2));
cv::resize(right, right, cv::Size(right.cols/2, right.rows/2));
cv::cvtColor(left, left, cv::COLOR_BGR2GRAY);
cv::cvtColor(right, right, cv::COLOR_BGR2GRAY);
int bits = 0;
switch (left.type()) {
case CV_8UC1: bits = 8; break;
case CV_16UC1: bits = 16; break;
default:
std::cerr << "invalid input image color format" << left.type() << std::endl;
std::exit(EXIT_FAILURE);
}
sgm::StereoSGM ssgm(left.cols, left.rows, disp_size, bits, 8, sgm::EXECUTE_INOUT_HOST2HOST);
cv::Mat output(cv::Size(left.cols, left.rows), CV_8UC1);
ssgm.execute(left.data, right.data, output.data);
// show image
cv::imshow("image", output * 256 / disp_size);
int key = cv::waitKey();
int mode = 0;
while (key != 27) {
if (key == 's') {
mode += 1;
if (mode >= 3) mode = 0;
switch (mode) {
case 0:
{
cv::setWindowTitle("image", "disparity");
cv::imshow("image", output * 256 / disp_size);
break;
}
case 1:
{
cv::Mat m;
cv::applyColorMap(output * 256 / disp_size, m, cv::COLORMAP_JET);
cv::setWindowTitle("image", "disparity color");
cv::imshow("image", m);
break;
}
case 2:
{
cv::setWindowTitle("image", "input");
cv::imshow("image", left);
break;
}
}
}
key = cv::waitKey();
}
return 0;
}
cmake_minimum_required(VERSION 3.1)
set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-O3 -Wall")
endif()
find_package(CUDA REQUIRED)
find_package(OpenCV REQUIRED)
if (OpenCV_VERSION VERSION_LESS 3.0)
message(FATAL_ERROR "Error: OpenCV version requires at least 3.0")
endif()
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(../../include)
cuda_add_executable(stereo_image_cv_gpumat stereosgm_image_cv_gpumat.cpp ${CUDA_SRC})
target_link_libraries(stereo_image_cv_gpumat sgm ${CUDA_LIBRARIES} ${OpenCV_LIBS})
/*
Copyright 2016 Fixstars Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http ://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <stdlib.h>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/core/cuda.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/version.hpp>
#include <libsgm.h>
#define ASSERT_MSG(expr, msg) \
if (!(expr)) { \
std::cerr << msg << std::endl; \
std::exit(EXIT_FAILURE); \
} \
static void execute(sgm::LibSGMWrapper& sgmw, const cv::Mat& h_left, const cv::Mat& h_right, cv::Mat& h_disparity) noexcept(false)
{
cv::cuda::GpuMat d_left, d_right;
d_left.upload(h_left);
d_right.upload(h_right);
cv::cuda::GpuMat d_disparity;
sgmw.execute(d_left, d_right, d_disparity);
// normalize result
cv::cuda::GpuMat d_normalized_disparity;
d_disparity.convertTo(d_normalized_disparity, CV_8UC1, 256. / sgmw.getNumDisparities());
d_normalized_disparity.download(h_disparity);
}
int main(int argc, char* argv[]) {
ASSERT_MSG(argc >= 3, "usage: stereosgm left_img right_img [disp_size]");
const cv::Mat left = cv::imread(argv[1], -1);
const cv::Mat right = cv::imread(argv[2], -1);
const int disp_size = argc > 3 ? std::atoi(argv[3]) : 128;
ASSERT_MSG(left.size() == right.size() && left.type() == right.type(), "input images must be same size and type.");
ASSERT_MSG(left.type() == CV_8U || left.type() == CV_16U, "input image format must be CV_8U or CV_16U.");
ASSERT_MSG(disp_size == 64 || disp_size == 128, "disparity size must be 64 or 128.");
sgm::LibSGMWrapper sgmw{disp_size};
cv::Mat disparity;
try {
execute(sgmw, left, right, disparity);
} catch (const cv::Exception& e) {
std::cerr << e.what() << std::endl;
if (e.code == cv::Error::GpuNotSupported) {
return 1;
} else {
return -1;
}
}
// post-process for showing image
cv::Mat colored;
cv::applyColorMap(disparity, colored, cv::COLORMAP_JET);
cv::imshow("image", disparity);
int key = cv::waitKey();
int mode = 0;
while (key != 27) {
if (key == 's') {
mode += 1;
if (mode >= 3) mode = 0;
switch (mode) {
case 0:
{
cv::setWindowTitle("image", "disparity");
cv::imshow("image", disparity);
break;
}
case 1:
{
cv::setWindowTitle("image", "disparity color");
cv::imshow("image", colored);
break;
}
case 2:
{
cv::setWindowTitle("image", "input");
cv::imshow("image", left);
break;
}
}
}
key = cv::waitKey();
}
return 0;
}
cmake_minimum_required(VERSION 3.1)
set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-O3 -Wall")
endif()
find_package(CUDA REQUIRED)
find_package(OpenCV REQUIRED)
if (OpenCV_VERSION VERSION_LESS 3.0)
message(FATAL_ERROR "Error: OpenCV version requires at least 3.0")
endif()
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(../../include)
cuda_add_executable(stereo_movie stereosgm_movie.cpp)
target_link_libraries(stereo_movie sgm ${CUDA_LIBRARIES} ${OpenCV_LIBS})
/*
Copyright 2016 Fixstars Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http ://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <iostream>
#include <iomanip>
#include <string>
#include <chrono>
#include <cuda_runtime.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/version.hpp>
#include <libsgm.h>
#define ASSERT_MSG(expr, msg) \
if (!(expr)) { \
std::cerr << msg << std::endl; \
std::exit(EXIT_FAILURE); \
} \
struct device_buffer
{
device_buffer() : data(nullptr) {}
device_buffer(size_t count) { allocate(count); }
void allocate(size_t count) { cudaMalloc(&data, count); }
~device_buffer() { cudaFree(data); }
void* data;
};
template <class... Args>
static std::string format_string(const char* fmt, Args... args)
{
const int BUF_SIZE = 1024;
char buf[BUF_SIZE];
std::snprintf(buf, BUF_SIZE, fmt, args...);
return std::string(buf);
}
int main(int argc, char* argv[])
{
if (argc < 3) {
std::cout << "usage: " << argv[0] << " left-image-format right-image-format [disp_size]" << std::endl;
std::exit(EXIT_FAILURE);
}
const int first_frame = 1;
cv::Mat I1 = cv::imread(format_string(argv[1], first_frame), -1);
cv::Mat I2 = cv::imread(format_string(argv[2], first_frame), -1);
const int disp_size = argc >= 4 ? std::stoi(argv[3]) : 128;
ASSERT_MSG(!I1.empty() && !I2.empty(), "imread failed.");
ASSERT_MSG(I1.size() == I2.size() && I1.type() == I2.type(), "input images must be same size and type.");
ASSERT_MSG(I1.type() == CV_8U || I1.type() == CV_16U, "input image format must be CV_8U or CV_16U.");
ASSERT_MSG(disp_size == 64 || disp_size == 128, "disparity size must be 64 or 128.");
const int width = I1.cols;
const int height = I1.rows;
const int input_depth = I1.type() == CV_8U ? 8 : 16;
const int input_bytes = input_depth * width * height / 8;
const int output_depth = 8;
const int output_bytes = output_depth * width * height / 8;
sgm::StereoSGM sgm(width, height, disp_size, input_depth, output_depth, sgm::EXECUTE_INOUT_CUDA2CUDA);
cv::Mat disparity(height, width, output_depth == 8 ? CV_8U : CV_16U);
cv::Mat disparity_8u, disparity_color;
device_buffer d_I1(input_bytes), d_I2(input_bytes), d_disparity(output_bytes);
for (int frame_no = first_frame;; frame_no++) {
I1 = cv::imread(format_string(argv[1], frame_no), -1);
I2 = cv::imread(format_string(argv[2], frame_no), -1);
if (I1.empty() || I2.empty()) {
frame_no = first_frame;
continue;
}
cudaMemcpy(d_I1.data, I1.data, input_bytes, cudaMemcpyHostToDevice);
cudaMemcpy(d_I2.data, I2.data, input_bytes, cudaMemcpyHostToDevice);
const auto t1 = std::chrono::system_clock::now();
sgm.execute(d_I1.data, d_I2.data, d_disparity.data);
cudaDeviceSynchronize();
const auto t2 = std::chrono::system_clock::now();
const auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
const double fps = 1e6 / duration;
cudaMemcpy(disparity.data, d_disparity.data, output_bytes, cudaMemcpyDeviceToHost);
// draw results
if (I1.type() != CV_8U) {
cv::normalize(I1, I1, 0, 255, cv::NORM_MINMAX);
I1.convertTo(I1, CV_8U);
}
disparity.convertTo(disparity_8u, CV_8U, 255. / disp_size);
cv::applyColorMap(disparity_8u, disparity_color, cv::COLORMAP_JET);
cv::putText(disparity_color, format_string("sgm execution time: %4.1f[msec] %4.1f[FPS]", 1e-3 * duration, fps),
cv::Point(50, 50), 2, 0.75, cv::Scalar(255, 255, 255));
cv::imshow("left image", I1);
cv::imshow("disparity", disparity_color);
const char c = cv::waitKey(1);
if (c == 27) // ESC
break;
}
return 0;
}
cmake_minimum_required(VERSION 3.1)
set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-O3 -Wall")
endif()
find_package(CUDA REQUIRED)
find_package(OpenCV REQUIRED)
if (OpenCV_VERSION VERSION_LESS 3.0)
message(FATAL_ERROR "Error: OpenCV version requires at least 3.0")
endif()
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(../../include)
cuda_add_executable(stereo_reprojection stereosgm_reprojection.cpp)
target_link_libraries(stereo_reprojection sgm ${CUDA_LIBRARIES} ${OpenCV_LIBS})
<?xml version="1.0"?>
<opencv_storage>
<!-- Intrinsic parameters -->
<FocalLengthX>1267.485352</FocalLengthX> <!-- focal length x (pixel) -->
<FocalLengthY>1224.548950</FocalLengthY> <!-- focal length y (pixel) -->
<CenterX>472.735474</CenterX> <!-- principal point x (pixel) -->
<CenterY>175.787781</CenterY> <!-- principal point y (pixel) -->
<!-- Extrinsic parameters -->
<BaseLine>0.214382</BaseLine> <!-- baseline (meter) -->
<Height>1.170000</Height> <!-- height position (meter) -->
<Tilt>0.081276</Tilt> <!-- tilt angle (radian) -->
</opencv_storage>
<?xml version="1.0"?>
<opencv_storage>
<FocalLengthX>1249.7700195</FocalLengthX>
<FocalLengthY>1249.7700195</FocalLengthY>
<CenterX>480.8460083</CenterX>
<CenterY>237.4100037</CenterY>
<BaseLine>0.2339240</BaseLine>
<Height>1.2000000</Height>
<Tilt>0.07</Tilt>
</opencv_storage>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment