├── legend_vertical.png
├── .gitmodules
├── class_colour_scheme.data
├── src
├── map_interface
│ ├── ElasticFusionCuda.h
│ ├── ElasticFusionCuda.cu
│ ├── ElasticFusionInterface.h
│ └── ElasticFusionInterface.cpp
├── gui
│ ├── GuiCuda.h
│ ├── Gui.h
│ ├── GuiCuda.cu
│ └── Gui.cpp
├── utilities
│ ├── Types.h
│ ├── RawLogReader.h
│ ├── LiveLogReader.h
│ ├── PNGLogReader.h
│ ├── LogReader.h
│ ├── JPEGLoader.h
│ ├── ThreadMutexObject.h
│ ├── LiveLogReader.cpp
│ ├── RawLogReader.cpp
│ ├── Array.h
│ ├── Array.cpp
│ ├── PNGLogReader.cpp
│ ├── Stopwatch.h
│ ├── OpenNI2Interface.h
│ └── OpenNI2Interface.cpp
├── cnn_interface
│ ├── CaffeInterface.h
│ └── CaffeInterface.cpp
├── semantic_fusion
│ ├── CRF
│ │ ├── util.h
│ │ ├── util.cpp
│ │ ├── fastmath.h
│ │ ├── densecrf.h
│ │ ├── densecrf.cpp
│ │ └── permutohedral.h
│ ├── SemanticFusionCuda.h
│ ├── SemanticFusionInterface.h
│ ├── SemanticFusionInterface.cpp
│ └── SemanticFusionCuda.cu
└── main.cpp
├── FindGlog.cmake
├── CMakeLists.txt
├── CudaComputeTargetFlags.cmake
├── FindOpenNI2.cmake
├── README.md
└── LICENSE.txt
/legend_vertical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ewenwan/semanticfusion/HEAD/legend_vertical.png
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "elasticfusionpublic"]
2 | path = elasticfusionpublic
3 | url = https://bitbucket.org/dysonroboticslab/elasticfusionpublic.git
4 | branch = semanticfusion
5 | [submodule "caffe_semanticfusion"]
6 | path = caffe_semanticfusion
7 | url = https://bitbucket.org/dysonroboticslab/caffe_semanticfusion.git
8 |
--------------------------------------------------------------------------------
/class_colour_scheme.data:
--------------------------------------------------------------------------------
1 | Class Name Id R G B NOTES
2 | =========================================
3 | Background 0 20 20 20 DARK GREY
4 | Bed 1 0 128 128 TEAL
5 | Bookshelf 2 250 50 50 DARK RED
6 | Ceiling 3 102 0 204 PURPLE
7 | Chair 4 50 50 250 BRIGHT BLUE
8 | Floor 5 220 220 220 LIGHT GREY
9 | Furniture 6 255 69 20 ORANGE
10 | Objects 7 255 20 127 PINK
11 | Picture 8 50 50 150 DARK BLUE
12 | Sofa 9 222 180 140 TAN
13 | Table 10 50 250 50 BRIGHT GREEN
14 | Tv 11 255 215 0 GOLD
15 | Wall 12 150 150 150 GREY
16 | Window 13 0 255 255 CYAN
17 |
--------------------------------------------------------------------------------
/src/map_interface/ElasticFusionCuda.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of SemanticFusion.
3 | *
4 | * Copyright (C) 2017 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is SemanticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #include
20 | #include
21 |
22 | void updateSurfelClasses(const int n, float* map_surfels, const float* classes, const float* probs, const float* class_colours, const float threshold);
23 |
--------------------------------------------------------------------------------
/src/gui/GuiCuda.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of SemanticFusion.
3 | *
4 | * Copyright (C) 2017 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is SemanticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #include
20 | #include
21 |
22 | void colouredArgMax(int n, float const * probabilities, const int num_classes, float const * color_lookup, float* colour, float const * map, const int map_size,cudaTextureObject_t ids, const float threshold);
23 |
--------------------------------------------------------------------------------
/src/utilities/Types.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of SemanticFusion.
3 | *
4 | * Copyright (C) 2017 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is SemanticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #ifndef TYPES_H_
20 | #define TYPES_H_
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | typedef unsigned char* ImagePtr;
28 | typedef unsigned short* DepthPtr;
29 |
30 | struct ClassColour {
31 | ClassColour()
32 | : name(""), r(0), g(0), b(0) {}
33 | ClassColour(std::string name_, int r_, int g_, int b_)
34 | : name(name_), r(r_), g(g_), b(b_) {}
35 | std::string name;
36 | int r, g, b;
37 | };
38 |
39 | #endif /* TYPES_H_ */
40 |
--------------------------------------------------------------------------------
/FindGlog.cmake:
--------------------------------------------------------------------------------
1 | # The following variables are optionally searched for defaults
2 | # GLOG_ROOT_DIR: Base directory where all GLOG components are found
3 | #
4 | # The following are set after configuration is done:
5 | # GLOG_FOUND
6 | # GLOG_INCLUDE_DIRS
7 | # GLOG_LIBRARIES
8 |
9 | include(FindPackageHandleStandardArgs)
10 |
11 | set(GLOG_ROOT_DIR "" CACHE PATH "Folder contains Google glog")
12 |
13 | if(WIN32)
14 | find_path(GLOG_INCLUDE_DIR glog/logging.h
15 | PATHS ${GLOG_ROOT_DIR}/src/windows)
16 | else()
17 | find_path(GLOG_INCLUDE_DIR glog/logging.h
18 | PATHS ${GLOG_ROOT_DIR})
19 | endif()
20 |
21 | if(MSVC)
22 | find_library(GLOG_LIBRARY_RELEASE libglog_static
23 | PATHS ${GLOG_ROOT_DIR}
24 | PATH_SUFFIXES Release)
25 |
26 | find_library(GLOG_LIBRARY_DEBUG libglog_static
27 | PATHS ${GLOG_ROOT_DIR}
28 | PATH_SUFFIXES Debug)
29 |
30 | set(GLOG_LIBRARY optimized ${GLOG_LIBRARY_RELEASE} debug ${GLOG_LIBRARY_DEBUG})
31 | else()
32 | find_library(GLOG_LIBRARY glog
33 | PATHS ${GLOG_ROOT_DIR}
34 | PATH_SUFFIXES
35 | lib
36 | lib64)
37 | endif()
38 |
39 | find_package_handle_standard_args(GLOG DEFAULT_MSG
40 | GLOG_INCLUDE_DIR GLOG_LIBRARY)
41 |
42 | if(GLOG_FOUND)
43 | set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR})
44 | set(GLOG_LIBRARIES ${GLOG_LIBRARY})
45 | endif()
46 |
--------------------------------------------------------------------------------
/src/cnn_interface/CaffeInterface.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of SemanticFusion.
3 | *
4 | * Copyright (C) 2017 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is SemanticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #ifndef CAFFE_INTERFACE_H_
20 | #define CAFFE_INTERFACE_H_
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 | #include
28 | #include
29 |
30 | class CaffeInterface {
31 | public:
32 | CaffeInterface() : initialised_(false) {}
33 | virtual ~CaffeInterface() {}
34 | bool Init(const std::string& model_path, const std::string& weights);
35 | std::shared_ptr > ProcessFrame(
36 | const ImagePtr rgb, const DepthPtr depth,
37 | const int height, const int width);
38 | int num_output_classes();
39 | private:
40 | bool initialised_;
41 | std::unique_ptr > network_;
42 | std::shared_ptr > output_probabilities_;
43 | };
44 |
45 | #endif /* CAFFE_INTERFACE_H_ */
46 |
--------------------------------------------------------------------------------
/src/utilities/RawLogReader.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of ElasticFusion.
3 | *
4 | * Copyright (C) 2015 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is ElasticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #ifndef RAWLOGREADER_H_
20 | #define RAWLOGREADER_H_
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include "LogReader.h"
27 |
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 |
35 | class RawLogReader : public LogReader
36 | {
37 | public:
38 | RawLogReader(std::string file, bool flipColors);
39 |
40 | virtual ~RawLogReader();
41 |
42 | void getNext();
43 |
44 | void getBack();
45 |
46 | int getNumFrames();
47 |
48 | bool hasMore();
49 |
50 | bool rewound();
51 |
52 | void fastForward(int frame);
53 |
54 | const std::string getFile();
55 |
56 | void setAuto(bool value);
57 |
58 | std::stack filePointers;
59 |
60 | private:
61 | void getCore();
62 | };
63 |
64 | #endif /* RAWLOGREADER_H_ */
65 |
--------------------------------------------------------------------------------
/src/semantic_fusion/CRF/util.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2011, Philipp Krähenbühl
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright
10 | notice, this list of conditions and the following disclaimer in the
11 | documentation and/or other materials provided with the distribution.
12 | * Neither the name of the Stanford University nor the
13 | names of its contributors may be used to endorse or promote products
14 | derived from this software without specific prior written permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY Philipp Krähenbühl ''AS IS'' AND ANY
17 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL Philipp Krähenbühl BE LIABLE FOR ANY
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 | */
27 |
28 | #pragma once
29 |
30 | #include "densecrf.h"
31 | #include "permutohedral.h"
32 |
33 | // Memory handling switches between SSE and new
34 | float* allocate ( size_t N ) ;
35 | void deallocate ( float *& ptr ) ;
36 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.2)
2 | if(POLICY CMP0007)
3 | cmake_policy(SET CMP0007 NEW)
4 | endif()
5 |
6 | project(SemanticFusion)
7 |
8 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}")
9 |
10 | find_package(CUDA REQUIRED)
11 | find_package(Glog REQUIRED)
12 | find_package(OpenCV REQUIRED)
13 | find_package(OpenNI2 REQUIRED)
14 |
15 | add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/elasticfusionpublic/Core/src")
16 | add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/caffe_semanticfusion")
17 |
18 | file(GLOB_RECURSE srcs src/*.cpp)
19 | file(GLOB_RECURSE cuda src/*.cu)
20 |
21 | set(CUDA_ARCH_BIN "30 35 50 52 61" CACHE STRING "Specify 'real' GPU arch to build binaries for, BIN(PTX) format is supported. Example: 1.3 2.1(1.3) or 13 21(13)")
22 | include(CudaComputeTargetFlags.cmake)
23 | APPEND_TARGET_ARCH_FLAGS()
24 |
25 | set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "--ftz=true;--prec-div=false;--prec-sqrt=false")
26 | set(CUDA_HOST_COMPILER gcc-5)
27 |
28 | set(CMAKE_CXX_FLAGS "-O3 -msse2 -msse3 -Wall -std=c++11")
29 |
30 | cuda_add_library(semantic_fusion_cuda_library SHARED ${cuda} )
31 |
32 | add_executable(${CMAKE_PROJECT_NAME}
33 | ${srcs}
34 | )
35 |
36 | target_link_libraries(${CMAKE_PROJECT_NAME}
37 | ${CUDA_LIBRARIES}
38 | ${GLOG_LIBRARY}
39 | ${OpenCV_LIBS}
40 | ${OPENNI2_LIBRARY}
41 | semantic_fusion_cuda_library
42 | efusion
43 | caffe
44 | )
45 |
46 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC
47 | $
48 | ${EIGEN_INCLUDE_DIRS}
49 | ${CUDA_INCLUDE_DIRS}
50 | ${GLOG_INCLUDE_DIR}
51 | ${OPENNI2_INCLUDE_DIR}
52 | )
53 |
--------------------------------------------------------------------------------
/src/utilities/LiveLogReader.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of ElasticFusion.
3 | *
4 | * Copyright (C) 2015 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is ElasticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #ifndef LIVELOGREADER_H_
20 | #define LIVELOGREADER_H_
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "LogReader.h"
28 | #include "OpenNI2Interface.h"
29 |
30 | class LiveLogReader : public LogReader
31 | {
32 | public:
33 | LiveLogReader(std::string file, bool flipColors);
34 |
35 | virtual ~LiveLogReader();
36 |
37 | void getNext();
38 |
39 | int getNumFrames();
40 |
41 | bool hasMore();
42 |
43 | bool rewound()
44 | {
45 | return false;
46 | }
47 |
48 | bool is_valid()
49 | {
50 | return valid;
51 | }
52 |
53 | void getBack()
54 | {
55 |
56 | }
57 |
58 | void fastForward(int frame)
59 | {
60 |
61 | }
62 |
63 | void setAuto(bool value);
64 |
65 | const std::string getFile() {
66 | return file;
67 | };
68 |
69 | OpenNI2Interface * asus;
70 |
71 | private:
72 | int64_t lastFrameTime;
73 | int lastGot;
74 | bool valid;
75 | };
76 |
77 | #endif /* LIVELOGREADER_H_ */
78 |
--------------------------------------------------------------------------------
/src/semantic_fusion/SemanticFusionCuda.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of SemanticFusion.
3 | *
4 | * Copyright (C) 2017 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is SemanticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #include
20 |
21 | void fuseSemanticProbabilities(cudaTextureObject_t ids, const int ids_width, const int ids_height,
22 | const float* probabilities, const int prob_width, const int prob_height,
23 | const int prob_channels,float* map_table, float* map_max,
24 | const int map_size);
25 |
26 | void updateProbabilityTable(int* deleted_ids, const int num_deleted, const int current_table_size,
27 | float const* probability_table, const int prob_width, const int prob_height,
28 | const int new_prob_width, float* new_probability_table,
29 | float const* map_table, float* new_map_table);
30 |
31 | void renderProbabilityMap(cudaTextureObject_t ids, const int ids_width, const int ids_height,
32 | const float* probability_table, const int prob_width, const int prob_height,
33 | float* rendered_probabilities);
34 |
35 |
36 | void updateMaxClass(const int n, const float* probabilities, const int classes,
37 | float* map_max, const int map_size);
38 |
--------------------------------------------------------------------------------
/CudaComputeTargetFlags.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Compute target flags macros by Anatoly Baksheev
3 | #
4 | # Usage in CmakeLists.txt:
5 | # include(CudaComputeTargetFlags.cmake)
6 | # APPEND_TARGET_ARCH_FLAGS()
7 |
8 | #compute flags macros
9 | MACRO(CUDA_COMPUTE_TARGET_FLAGS arch_bin arch_ptx cuda_nvcc_target_flags)
10 | string(REGEX REPLACE "\\." "" ARCH_BIN_WITHOUT_DOTS "${${arch_bin}}")
11 | string(REGEX REPLACE "\\." "" ARCH_PTX_WITHOUT_DOTS "${${arch_ptx}}")
12 |
13 | set(cuda_computer_target_flags_temp "")
14 |
15 | # Tell NVCC to add binaries for the specified GPUs
16 | string(REGEX MATCHALL "[0-9()]+" ARCH_LIST "${ARCH_BIN_WITHOUT_DOTS}")
17 | foreach(ARCH IN LISTS ARCH_LIST)
18 | if (ARCH MATCHES "([0-9]+)\\(([0-9]+)\\)")
19 | # User explicitly specified PTX for the concrete BIN
20 | set(cuda_computer_target_flags_temp ${cuda_computer_target_flags_temp} -gencode arch=compute_${CMAKE_MATCH_2},code=sm_${CMAKE_MATCH_1})
21 | else()
22 | # User didn't explicitly specify PTX for the concrete BIN, we assume PTX=BIN
23 | set(cuda_computer_target_flags_temp ${cuda_computer_target_flags_temp} -gencode arch=compute_${ARCH},code=sm_${ARCH})
24 | endif()
25 | endforeach()
26 |
27 | # Tell NVCC to add PTX intermediate code for the specified architectures
28 | string(REGEX MATCHALL "[0-9]+" ARCH_LIST "${ARCH_PTX_WITHOUT_DOTS}")
29 | foreach(ARCH IN LISTS ARCH_LIST)
30 | set(cuda_computer_target_flags_temp ${cuda_computer_target_flags_temp} -gencode arch=compute_${ARCH},code=compute_${ARCH})
31 | endforeach()
32 |
33 | set(${cuda_nvcc_target_flags} ${cuda_computer_target_flags_temp})
34 | ENDMACRO()
35 |
36 | MACRO(APPEND_TARGET_ARCH_FLAGS)
37 | set(cuda_nvcc_target_flags "")
38 | CUDA_COMPUTE_TARGET_FLAGS(CUDA_ARCH_BIN CUDA_ARCH_PTX cuda_nvcc_target_flags)
39 | if (cuda_nvcc_target_flags)
40 | message(STATUS "CUDA NVCC target flags: ${cuda_nvcc_target_flags}")
41 | list(APPEND CUDA_NVCC_FLAGS ${cuda_nvcc_target_flags})
42 | endif()
43 | ENDMACRO()
--------------------------------------------------------------------------------
/src/semantic_fusion/CRF/util.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2011, Philipp Krähenbühl
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright
10 | notice, this list of conditions and the following disclaimer in the
11 | documentation and/or other materials provided with the distribution.
12 | * Neither the name of the Stanford University nor the
13 | names of its contributors may be used to endorse or promote products
14 | derived from this software without specific prior written permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY Philipp Krähenbühl ''AS IS'' AND ANY
17 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL Philipp Krähenbühl BE LIABLE FOR ANY
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 | */
27 |
28 | #include "util.h"
29 | #include
30 |
31 | float* allocate(size_t N) {
32 | float * r = NULL;
33 | if (N>0)
34 | #ifdef SSE_DENSE_CRF
35 | r = (float*)_mm_malloc( N*sizeof(float)+16, 16 );
36 | #else
37 | r = new float[N];
38 | #endif
39 | memset( r, 0, sizeof(float)*N);
40 | return r;
41 | }
42 | void deallocate(float*& ptr) {
43 | if (ptr)
44 | #ifdef SSE_DENSE_CRF
45 | _mm_free( ptr );
46 | #else
47 | delete[] ptr;
48 | #endif
49 | ptr = NULL;
50 | }
51 |
--------------------------------------------------------------------------------
/src/utilities/PNGLogReader.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of ElasticFusion.
3 | *
4 | * Copyright (C) 2015 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is ElasticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #ifndef PNGLOGREADER_H_
20 | #define PNGLOGREADER_H_
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "LogReader.h"
28 | #include
29 | #include
30 |
31 | struct FrameInfo {
32 | int64_t timestamp;
33 | std::string depth_path;
34 | std::string rgb_path;
35 | std::string depth_id;
36 | std::string rgb_id;
37 | bool labeled_frame;
38 | std::string frame_id;
39 | };
40 |
41 | class PNGLogReader : public LogReader
42 | {
43 | public:
44 | PNGLogReader(std::string file, std::string labels_file);
45 |
46 | virtual ~PNGLogReader();
47 |
48 | void getNext();
49 |
50 | int getNumFrames();
51 |
52 | bool hasMore();
53 |
54 | bool isLabeledFrame();
55 |
56 | std::string getLabelFrameId();
57 |
58 | bool rewound() { return false; }
59 |
60 | void getBack() { }
61 |
62 | void fastForward(int frame) {}
63 |
64 | void setAuto(bool value) {}
65 |
66 | const std::string getFile() {
67 | return file;
68 | };
69 |
70 | bool hasDepthFilled() { return has_depth_filled; }
71 |
72 | private:
73 | int64_t lastFrameTime;
74 | int lastGot;
75 | std::vector frames_;
76 | Bytef * decompressionBufferDepthFilled;
77 | bool has_depth_filled;
78 | public:
79 | int num_labelled;
80 | };
81 |
82 | #endif /* PNGLOGREADER_H_ */
83 |
--------------------------------------------------------------------------------
/FindOpenNI2.cmake:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Find OpenNI2
3 | #
4 | # This sets the following variables:
5 | # OPENNI2_FOUND - True if OPENNI was found.
6 | # OPENNI2_INCLUDE_DIRS - Directories containing the OPENNI include files.
7 | # OPENNI2_LIBRARIES - Libraries needed to use OPENNI.
8 |
9 | find_package(PkgConfig)
10 | if(${CMAKE_VERSION} VERSION_LESS 2.8.2)
11 | pkg_check_modules(PC_OPENNI openni2-dev)
12 | else()
13 | pkg_check_modules(PC_OPENNI QUIET openni2-dev)
14 | endif()
15 |
16 | set(OPENNI2_DEFINITIONS ${PC_OPENNI_CFLAGS_OTHER})
17 |
18 | #add a hint so that it can find it without the pkg-config
19 | find_path(OPENNI2_INCLUDE_DIR OpenNI.h
20 | HINTS
21 | ${PC_OPENNI_INCLUDEDIR}
22 | ${PC_OPENNI_INCLUDE_DIRS}
23 | PATHS
24 | "${PROGRAM_FILES}/OpenNI2/Include"
25 | "${CMAKE_SOURCE_DIR}/../OpenNI2/Include"
26 | "${CMAKE_SOURCE_DIR}/../../OpenNI2/Include"
27 | "${CMAKE_SOURCE_DIR}/../../../OpenNI2/Include"
28 | "${CMAKE_SOURCE_DIR}/../../../code/OpenNI2/Include"
29 | /usr/include
30 | /user/include
31 | PATH_SUFFIXES openni2 ni2
32 | )
33 |
34 | if(${CMAKE_CL_64})
35 | set(OPENNI_PATH_SUFFIXES lib64)
36 | else()
37 | set(OPENNI_PATH_SUFFIXES lib)
38 | endif()
39 |
40 | #add a hint so that it can find it without the pkg-config
41 | find_library(OPENNI2_LIBRARY
42 | NAMES OpenNI2
43 | HINTS
44 | ${PC_OPENNI_LIBDIR}
45 | ${PC_OPENNI_LIBRARY_DIRS}
46 | PATHS
47 | "${PROGRAM_FILES}}/OpenNI2/Redist"
48 | "${PROGRAM_FILES}/OpenNI2"
49 | "${CMAKE_SOURCE_DIR}/../OpenNI2/Bin/x64-Release"
50 | "${CMAKE_SOURCE_DIR}/../../OpenNI2/Bin/x64-Release"
51 | "${CMAKE_SOURCE_DIR}/../../../OpenNI2/Bin/x64-Release"
52 | "${CMAKE_SOURCE_DIR}/../../../code/OpenNI2/Bin/x64-Release"
53 | /usr/lib
54 | /user/lib
55 | PATH_SUFFIXES ${OPENNI_PATH_SUFFIXES}
56 | )
57 |
58 | set(OPENNI2_INCLUDE_DIRS ${OPENNI2_INCLUDE_DIR})
59 | set(OPENNI2_LIBRARIES ${OPENNI2_LIBRARY})
60 |
61 | include(FindPackageHandleStandardArgs)
62 | find_package_handle_standard_args(OpenNI2 DEFAULT_MSG
63 | OPENNI2_LIBRARY OPENNI2_INCLUDE_DIR)
64 |
65 | mark_as_advanced(OPENNI2_LIBRARY OPENNI2_INCLUDE_DIR)
66 |
--------------------------------------------------------------------------------
/src/map_interface/ElasticFusionCuda.cu:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of SemanticFusion.
3 | *
4 | * Copyright (C) 2017 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is SemanticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #include
20 | #include
21 |
22 | #include
23 |
24 | #define gpuErrChk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
25 |
26 | inline void gpuAssert(cudaError_t code, const char *file, int line, bool
27 | abort=true) {
28 | if (code != cudaSuccess) {
29 | fprintf(stderr,"GPUassert: %s %s %d\n",
30 | cudaGetErrorString(code), file, line);
31 | if (abort) exit(code);
32 | }
33 | }
34 |
35 | __global__
36 | void updateSurfelClassesKernel(const int n, float* map_surfels, const float* classes, const float* probs, const float* class_colours, const float threshold)
37 | {
38 | const int surfel_size = 12;
39 | const int surfel_color_offset = 5;
40 | const int id = blockIdx.x * blockDim.x + threadIdx.x;
41 | if (id < n) {
42 | const int class_id = static_cast(classes[id]);
43 | const float prob = probs[id];
44 | if (class_id >= 0 && prob > threshold) {
45 | map_surfels[id * surfel_size + surfel_color_offset] = class_colours[class_id];
46 | } else {
47 | map_surfels[id * surfel_size + surfel_color_offset] = -1.0f;
48 | }
49 | }
50 | }
51 |
52 | __host__
53 | void updateSurfelClasses(const int n, float* map_surfels, const float* classes, const float* probs, const float* class_colours, const float threshold)
54 | {
55 | const int threads = 512;
56 | const int blocks = (n + threads - 1) / threads;
57 | dim3 dimGrid(blocks);
58 | dim3 dimBlock(threads);
59 | updateSurfelClassesKernel<<>>(n,map_surfels,classes,probs,class_colours,threshold);
60 | gpuErrChk(cudaGetLastError());
61 | gpuErrChk(cudaDeviceSynchronize());
62 | }
63 |
--------------------------------------------------------------------------------
/src/utilities/LogReader.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of ElasticFusion.
3 | *
4 | * Copyright (C) 2015 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is ElasticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #ifndef LOGREADER_H_
20 | #define LOGREADER_H_
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include "JPEGLoader.h"
29 |
30 | class LogReader
31 | {
32 | public:
33 | LogReader(std::string file, bool flipColors)
34 | : flipColors(flipColors),
35 | timestamp(0),
36 | depth(0),
37 | rgb(0),
38 | currentFrame(0),
39 | decompressionBufferDepth(0),
40 | decompressionBufferImage(0),
41 | file(file),
42 | width(Resolution::getInstance().width()),
43 | height(Resolution::getInstance().height()),
44 | numPixels(width * height)
45 | {}
46 |
47 | virtual ~LogReader()
48 | {}
49 |
50 | virtual void getNext() = 0;
51 |
52 | virtual int getNumFrames() = 0;
53 |
54 | virtual bool hasDepthFilled() { return false;}
55 |
56 | virtual bool hasMore() = 0;
57 |
58 | virtual bool rewound() = 0;
59 |
60 | virtual void getBack() = 0;
61 |
62 | virtual void fastForward(int frame) = 0;
63 |
64 | virtual const std::string getFile() = 0;
65 |
66 | virtual void setAuto(bool value) = 0;
67 |
68 | virtual bool isLabeledFrame() { return false; }
69 | virtual bool is_valid() { return false; }
70 | virtual std::string getLabelFrameId() { return ""; }
71 |
72 | bool flipColors;
73 | int64_t timestamp;
74 |
75 | unsigned short * depth;
76 | unsigned char * rgb;
77 | int currentFrame;
78 |
79 | unsigned short * depthfilled;
80 |
81 | protected:
82 | Bytef * decompressionBufferDepth;
83 | Bytef * decompressionBufferImage;
84 | unsigned char * depthReadBuffer;
85 | unsigned char * imageReadBuffer;
86 | int32_t depthSize;
87 | int32_t imageSize;
88 |
89 | const std::string file;
90 | FILE * fp;
91 | int32_t numFrames;
92 | int width;
93 | int height;
94 | int numPixels;
95 |
96 | JPEGLoader jpeg;
97 | };
98 |
99 | #endif /* LOGREADER_H_ */
100 |
--------------------------------------------------------------------------------
/src/gui/Gui.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of SemanticFusion.
3 | *
4 | * Copyright (C) 2017 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is SemanticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #ifndef GUI_H_
20 | #define GUI_H_
21 | #include
22 | #include
23 |
24 | #include
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | #include
32 | #include
33 |
34 | struct ClassIdInput;
35 |
36 | class Gui {
37 | public:
38 | //enum SelectProbabilityMap {Books,Chairs,Floor};
39 | Gui(bool live_capture,std::vector class_colour_lookup, const int segmentation_width, const int segmentation_height);
40 | virtual ~Gui();
41 |
42 | void preCall();
43 | void renderMap(const std::unique_ptr& map);
44 | void postCall();
45 | void displayArgMaxClassColouring(const std::string & id, float* device_ptr, int channels,const float* map, const int map_size, cudaTextureObject_t ids, const float threshold);
46 | void displayRawNetworkPredictions(const std::string & id, float* device_ptr);
47 | void displayImg(const std::string & id, GPUTexture * img);
48 |
49 | bool reset() const { return pangolin::Pushed(*reset_.get()); }
50 | bool paused() const { return *pause_.get(); }
51 | bool step() const { return pangolin::Pushed(*step_.get()); }
52 | bool tracking() const { return *tracking_.get(); }
53 | bool class_colours() const { return *class_view_.get(); }
54 |
55 | private:
56 | int width_;
57 | int height_;
58 | const int segmentation_width_;
59 | const int segmentation_height_;
60 | int panel_;
61 | std::vector class_colour_lookup_;
62 | float* class_colour_lookup_gpu_;
63 | float* segmentation_rendering_gpu_;
64 |
65 | std::unique_ptr> reset_;
66 | std::unique_ptr> pause_;
67 | std::unique_ptr> step_;
68 | std::unique_ptr> tracking_;
69 | std::unique_ptr> class_view_;
70 | std::unique_ptr> class_choice_;
71 | std::unique_ptr probability_texture_array_;
72 | std::unique_ptr rendered_segmentation_texture_array_;
73 | pangolin::GlRenderBuffer* render_buffer_;
74 | pangolin::GlFramebuffer* color_frame_buffer_;
75 | GPUTexture* color_texture_;
76 | pangolin::OpenGlRenderState s_cam_;
77 | };
78 |
79 |
80 | #endif /* GUI_H_ */
81 |
--------------------------------------------------------------------------------
/src/utilities/JPEGLoader.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of ElasticFusion.
3 | *
4 | * Copyright (C) 2015 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is ElasticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #ifndef TOOLS_JPEGLOADER_H_
20 | #define TOOLS_JPEGLOADER_H_
21 |
22 | extern "C"
23 | {
24 | #include "jpeglib.h"
25 | }
26 |
27 | #include
28 | #include
29 |
30 | static void jpegFail(j_common_ptr cinfo)
31 | {
32 | assert(false && "JPEG decoding error!");
33 | }
34 |
35 | static void doNothing(j_decompress_ptr)
36 | {
37 |
38 | }
39 |
40 | class JPEGLoader
41 | {
42 | public:
43 | JPEGLoader()
44 | {}
45 |
46 | void readData(unsigned char * src, const int numBytes, unsigned char * data)
47 | {
48 | jpeg_decompress_struct cinfo; // IJG JPEG codec structure
49 |
50 | jpeg_error_mgr errorMgr;
51 |
52 | errorMgr.error_exit = jpegFail;
53 |
54 | cinfo.err = jpeg_std_error(&errorMgr);
55 |
56 | jpeg_create_decompress(&cinfo);
57 |
58 | jpeg_source_mgr srcMgr;
59 |
60 | cinfo.src = &srcMgr;
61 |
62 | // Prepare for suspending reader
63 | srcMgr.init_source = doNothing;
64 | srcMgr.resync_to_restart = jpeg_resync_to_restart;
65 | srcMgr.term_source = doNothing;
66 | srcMgr.next_input_byte = src;
67 | srcMgr.bytes_in_buffer = numBytes;
68 |
69 | jpeg_read_header(&cinfo, TRUE);
70 |
71 | jpeg_calc_output_dimensions(&cinfo);
72 |
73 | jpeg_start_decompress(&cinfo);
74 |
75 | int width = cinfo.output_width;
76 | int height = cinfo.output_height;
77 |
78 | JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, width * 4, 1);
79 |
80 | for(; height--; data += (width * 3))
81 | {
82 | jpeg_read_scanlines(&cinfo, buffer, 1);
83 |
84 | unsigned char * bgr = (unsigned char *)buffer[0];
85 | unsigned char * rgb = (unsigned char *)data;
86 |
87 | for(int i = 0; i < width; i++, bgr += 3, rgb += 3)
88 | {
89 | unsigned char t0 = bgr[0], t1 = bgr[1], t2 = bgr[2];
90 | rgb[2] = t0; rgb[1] = t1; rgb[0] = t2;
91 | }
92 | }
93 |
94 | jpeg_finish_decompress(&cinfo);
95 |
96 | jpeg_destroy_decompress(&cinfo);
97 | }
98 | };
99 |
100 |
101 | #endif /* TOOLS_JPEGLOADER_H_ */
102 |
--------------------------------------------------------------------------------
/src/semantic_fusion/CRF/fastmath.h:
--------------------------------------------------------------------------------
1 | // This code here comes from http://www.xnoiz.co.cc/fast-exp-x/
2 |
3 | /*
4 | Copyright (c) 2011, Philipp Krähenbühl
5 | All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 | * Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 | * Redistributions in binary form must reproduce the above copyright
12 | notice, this list of conditions and the following disclaimer in the
13 | documentation and/or other materials provided with the distribution.
14 | * Neither the name of the Stanford University nor the
15 | names of its contributors may be used to endorse or promote products
16 | derived from this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY Philipp Krähenbühl ''AS IS'' AND ANY
19 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL Philipp Krähenbühl BE LIABLE FOR ANY
22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #pragma once
31 |
32 | inline float fast_log2 (float val) {
33 | int * const exp_ptr = reinterpret_cast (&val);
34 | int x = *exp_ptr;
35 | const int log_2 = ((x >> 23) & 255) - 128;
36 | x &= ~(255 << 23);
37 | x += 127 << 23;
38 | *exp_ptr = x;
39 |
40 | return (val + log_2);
41 | }
42 | inline float fast_log (const float &val) {
43 | return (fast_log2 (val) * 0.69314718f);
44 | }
45 | inline float very_fast_exp(float x) {
46 | // err <= 3e-3
47 | // return 1
48 | // -x*(0.9664
49 | // -x*(0.3536));
50 |
51 | return 1
52 | -x*(0.9999999995f
53 | -x*(0.4999999206f
54 |
55 | -x*(0.1666653019f
56 | -x*(0.0416573475f
57 | -x*(0.0083013598f
58 |
59 | -x*(0.0013298820f
60 | -x*(0.0001413161f)))))));
61 | }
62 | inline float fast_exp(float x) {
63 | bool lessZero = true;
64 | if (x < 0) {
65 |
66 | lessZero = false;
67 | x = -x;
68 |
69 | }
70 | // This diry little trick only works because of the normalization and the fact that one element in the normalization is 1
71 | if (x > 20)
72 | return 0;
73 | int mult = 0;
74 |
75 | while (x > 0.69*2*2*2) {
76 |
77 | mult+=3;
78 | x /= 8.0f;
79 | }
80 |
81 | while (x > 0.69*2*2) {
82 | mult+=2;
83 |
84 | x /= 4.0f;
85 | }
86 | while (x > 0.69) {
87 |
88 | mult++;
89 | x /= 2.0f;
90 | }
91 |
92 | x = very_fast_exp(x);
93 | while (mult) {
94 |
95 | mult--;
96 | x = x*x;
97 | }
98 |
99 | if (lessZero) {
100 | return 1 / x;
101 |
102 | } else {
103 | return x;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/map_interface/ElasticFusionInterface.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of SemanticFusion.
3 | *
4 | * Copyright (C) 2017 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is SemanticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #ifndef ELASTIC_FUSION_INTERFACE_H_
20 | #define ELASTIC_FUSION_INTERFACE_H_
21 | #include
22 | #include
23 |
24 | #include
25 |
26 | #include
27 | #include
28 |
29 | class ElasticFusionInterface {
30 | public:
31 | // NOTE this must be performed in the header to globally initialise these
32 | // variables...
33 | ElasticFusionInterface()
34 | : initialised_(false)
35 | , height_(480)
36 | , width_(640)
37 | , tracking_only_(false)
38 | {
39 | Resolution::getInstance(width_, height_);
40 | // Primesense intrinsics
41 | Intrinsics::getInstance(528, 528, width_ / 2, height_ / 2);
42 | }
43 | virtual ~ElasticFusionInterface();
44 |
45 | virtual bool Init(std::vector class_colour_lookup);
46 | virtual bool ProcessFrame(const ImagePtr rgb, const DepthPtr depth, const int64_t timestamp);
47 | int height() const { return height_; }
48 | int width() const { return width_; }
49 |
50 | const std::vector& GetSurfelIdsCpu();
51 | cudaTextureObject_t GetSurfelIdsGpu();
52 | void UpdateSurfelClass(const int surfel_id, const int class_id);
53 | void UpdateSurfelClassGpu(const int n, const float* surfelclasses, const float* surfelprobs, const float threshold);
54 |
55 | int* GetDeletedSurfelIdsGpu();
56 |
57 | float* GetMapSurfelsGpu() {
58 | if (elastic_fusion_) {
59 | return elastic_fusion_->getGlobalModel().getMapSurfelsGpu();
60 | }
61 | return nullptr;
62 | }
63 |
64 | int GetMapSurfelCount() {
65 | if (elastic_fusion_) {
66 | return elastic_fusion_->getGlobalModel().lastCount();
67 | }
68 | return 0;
69 | }
70 |
71 | int GetMapSurfelDeletedCount() {
72 | if (elastic_fusion_ && !tracking_only_) {
73 | return elastic_fusion_->getGlobalModel().deletedCount();
74 | }
75 | return 0;
76 | }
77 |
78 | void RenderMapToBoundGlBuffer(const pangolin::OpenGlRenderState& camera, const bool classes);
79 | GPUTexture* getRawImageTexture();
80 | GPUTexture* getIdsTexture();
81 |
82 | void setTrackingOnly(const bool tracking) {
83 | if (elastic_fusion_) {
84 | elastic_fusion_->setTrackingOnly(tracking);
85 | tracking_only_ = tracking;
86 | }
87 | }
88 |
89 | private:
90 | bool initialised_;
91 | int height_;
92 | int width_;
93 | std::unique_ptr elastic_fusion_;
94 | std::vector surfel_ids_;
95 | std::vector class_color_lookup_;
96 | float* class_color_lookup_gpu_;
97 | bool tracking_only_;
98 | };
99 |
100 | #endif /* ELASTIC_FUSION_INTERFACE_H_ */
101 |
--------------------------------------------------------------------------------
/src/utilities/ThreadMutexObject.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of ElasticFusion.
3 | *
4 | * Copyright (C) 2015 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is ElasticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #ifndef THREADMUTEXOBJECT_H_
20 | #define THREADMUTEXOBJECT_H_
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | template
28 | class ThreadMutexObject
29 | {
30 | public:
31 | ThreadMutexObject()
32 | {}
33 |
34 | ThreadMutexObject(T initialValue)
35 | : object(initialValue),
36 | lastCopy(initialValue)
37 | {}
38 |
39 | void assign(T newValue)
40 | {
41 | mutex.lock();
42 |
43 | object = lastCopy = newValue;
44 |
45 | mutex.unlock();
46 | }
47 |
48 | std::mutex & getMutex()
49 | {
50 | return mutex;
51 | }
52 |
53 | T & getReference()
54 | {
55 | return object;
56 | }
57 |
58 | void assignAndNotifyAll(T newValue)
59 | {
60 | mutex.lock();
61 |
62 | object = newValue;
63 |
64 | signal.notify_all();
65 |
66 | mutex.unlock();
67 | }
68 |
69 | void notifyAll()
70 | {
71 | mutex.lock();
72 |
73 | signal.notify_all();
74 |
75 | mutex.unlock();
76 | }
77 |
78 | T getValue()
79 | {
80 | mutex.lock();
81 |
82 | lastCopy = object;
83 |
84 | mutex.unlock();
85 |
86 | return lastCopy;
87 | }
88 |
89 | T waitForSignal()
90 | {
91 | mutex.lock();
92 |
93 | signal.wait(mutex);
94 |
95 | lastCopy = object;
96 |
97 | mutex.unlock();
98 |
99 | return lastCopy;
100 | }
101 |
102 | T getValueWait(int wait = 33000)
103 | {
104 | std::this_thread::sleep_for(std::chrono::microseconds(wait));
105 |
106 | mutex.lock();
107 |
108 | lastCopy = object;
109 |
110 | mutex.unlock();
111 |
112 | return lastCopy;
113 | }
114 |
115 | T & getReferenceWait(int wait = 33000)
116 | {
117 | std::this_thread::sleep_for(std::chrono::microseconds(wait));
118 |
119 | mutex.lock();
120 |
121 | lastCopy = object;
122 |
123 | mutex.unlock();
124 |
125 | return lastCopy;
126 | }
127 |
128 | void operator++(int)
129 | {
130 | mutex.lock();
131 |
132 | object++;
133 |
134 | mutex.unlock();
135 | }
136 |
137 | private:
138 | T object;
139 | T lastCopy;
140 | std::mutex mutex;
141 | std::condition_variable_any signal;
142 | };
143 |
144 | #endif /* THREADMUTEXOBJECT_H_ */
145 |
--------------------------------------------------------------------------------
/src/gui/GuiCuda.cu:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of SemanticFusion.
3 | *
4 | * Copyright (C) 2017 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is SemanticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #include
20 | #include
21 |
22 | #include
23 |
24 | #define gpuErrChk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
25 |
26 | inline void gpuAssert(cudaError_t code, const char *file, int line, bool
27 | abort=true) {
28 | if (code != cudaSuccess) {
29 | fprintf(stderr,"GPUassert: %s %s %d\n",
30 | cudaGetErrorString(code), file, line);
31 | if (abort) exit(code);
32 | }
33 | }
34 |
35 | __global__
36 | void colouredArgMaxKernel(int n, float const* probabilities, const int num_classes, float const* color_lookup, float* colour, float const* map_max, const int map_size,cudaTextureObject_t ids, const float threshold)
37 | {
38 | const int id = blockIdx.x * blockDim.x + threadIdx.x;
39 | if (id < n) {
40 | const int y = id / 640;
41 | const int x = id - (y * 640);
42 | const int start_windowx = (x - 1) > 0 ? (x - 1) : 0;
43 | const int start_windowy = (y - 1) > 0 ? (y - 1) : 0;
44 | const int end_windowx = (x + 1) < 640 ? (x + 1) : 639;
45 | const int end_windowy = (y + 1) < 480 ? (y + 1) : 479;
46 |
47 | int max_class_id = -1;
48 | float max_class_prob = threshold;
49 | for (int sx = start_windowx; sx <= end_windowx; ++sx) {
50 | for (int sy = start_windowy; sy <= end_windowy; ++sy) {
51 | const int surfel_id = tex2D(ids,sx,sy);
52 | if (surfel_id > 0) {
53 | float const* id_probabilities = map_max + surfel_id;
54 | if (id_probabilities[map_size] > max_class_prob) {
55 | max_class_id = static_cast(id_probabilities[0]);
56 | max_class_prob = id_probabilities[map_size];
57 | }
58 | }
59 | }
60 | }
61 |
62 | float* local_colour = colour + (id * 4);
63 | if (max_class_id >= 0) {
64 | local_colour[0] = color_lookup[max_class_id * 3 + 0];
65 | local_colour[1] = color_lookup[max_class_id * 3 + 1];
66 | local_colour[2] = color_lookup[max_class_id * 3 + 2];
67 | local_colour[3] = 1.0f;
68 | } else {
69 | local_colour[0] = 0.0;
70 | local_colour[1] = 0.0;
71 | local_colour[2] = 0.0;
72 | local_colour[3] = 1.0f;
73 | }
74 | }
75 | }
76 |
77 | __host__
78 | void colouredArgMax(int n, float const * probabilities, const int num_classes, float const* color_lookup, float* colour, float const * map, const int map_size,cudaTextureObject_t ids, const float threshold)
79 | {
80 | const int threads = 512;
81 | const int blocks = (n + threads - 1) / threads;
82 | dim3 dimGrid(blocks);
83 | dim3 dimBlock(threads);
84 | colouredArgMaxKernel<<>>(n,probabilities,num_classes,color_lookup,colour,map,map_size,ids,threshold);
85 | gpuErrChk(cudaGetLastError());
86 | gpuErrChk(cudaDeviceSynchronize());
87 | }
88 |
--------------------------------------------------------------------------------
/src/utilities/LiveLogReader.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of ElasticFusion.
3 | *
4 | * Copyright (C) 2015 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is ElasticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #include "LiveLogReader.h"
20 |
21 | LiveLogReader::LiveLogReader(std::string file, bool flipColors)
22 | : LogReader(file, flipColors),
23 | lastFrameTime(-1),
24 | lastGot(-1),
25 | valid(false)
26 | {
27 | std::cout << "Creating live capture... "; std::cout.flush();
28 |
29 | asus = new OpenNI2Interface(Resolution::getInstance().width(), Resolution::getInstance().height());
30 |
31 | decompressionBufferDepth = new Bytef[Resolution::getInstance().numPixels() * 2];
32 |
33 | decompressionBufferImage = new Bytef[Resolution::getInstance().numPixels() * 3];
34 |
35 | if(!asus->ok())
36 | {
37 | std::cout << "failed!" << std::endl;
38 | std::cout << asus->error();
39 | valid = false;
40 | }
41 | else
42 | {
43 | std::cout << "success!" << std::endl;
44 |
45 | std::cout << "Waiting for first frame"; std::cout.flush();
46 |
47 | int lastDepth = asus->latestDepthIndex.getValue();
48 |
49 | do
50 | {
51 | usleep(33333);
52 | std::cout << "."; std::cout.flush();
53 | lastDepth = asus->latestDepthIndex.getValue();
54 | } while(lastDepth == -1);
55 |
56 | std::cout << " got it!" << std::endl;
57 | valid = true;
58 | }
59 | }
60 |
61 | LiveLogReader::~LiveLogReader()
62 | {
63 | delete [] decompressionBufferDepth;
64 |
65 | delete [] decompressionBufferImage;
66 |
67 | delete asus;
68 | }
69 |
70 | void LiveLogReader::getNext()
71 | {
72 | int lastDepth = asus->latestDepthIndex.getValue();
73 |
74 | assert(lastDepth != -1);
75 |
76 | int bufferIndex = lastDepth % OpenNI2Interface::numBuffers;
77 |
78 | if(bufferIndex == lastGot)
79 | {
80 | return;
81 | }
82 |
83 | if(lastFrameTime == asus->frameBuffers[bufferIndex].second)
84 | {
85 | return;
86 | }
87 |
88 | memcpy(&decompressionBufferDepth[0], asus->frameBuffers[bufferIndex].first.first, Resolution::getInstance().numPixels() * 2);
89 | memcpy(&decompressionBufferImage[0], asus->frameBuffers[bufferIndex].first.second, Resolution::getInstance().numPixels() * 3);
90 |
91 | lastFrameTime = asus->frameBuffers[bufferIndex].second;
92 |
93 | timestamp = lastFrameTime;
94 |
95 | rgb = (unsigned char *)&decompressionBufferImage[0];
96 | depth = (unsigned short *)&decompressionBufferDepth[0];
97 |
98 | imageReadBuffer = 0;
99 | depthReadBuffer = 0;
100 |
101 | imageSize = Resolution::getInstance().numPixels() * 3;
102 | depthSize = Resolution::getInstance().numPixels() * 2;
103 |
104 | if(flipColors)
105 | {
106 | for(int i = 0; i < Resolution::getInstance().numPixels() * 3; i += 3)
107 | {
108 | std::swap(rgb[i + 0], rgb[i + 2]);
109 | }
110 | }
111 | }
112 |
113 | int LiveLogReader::getNumFrames()
114 | {
115 | return std::numeric_limits::max();
116 | }
117 |
118 | bool LiveLogReader::hasMore()
119 | {
120 | return true;
121 | }
122 |
123 | void LiveLogReader::setAuto(bool value)
124 | {
125 | asus->setAutoExposure(value);
126 | asus->setAutoWhiteBalance(value);
127 | }
128 |
--------------------------------------------------------------------------------
/src/semantic_fusion/SemanticFusionInterface.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of SemanticFusion.
3 | *
4 | * Copyright (C) 2017 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is SemanticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #ifndef SEMANTIC_FUSION_INTERFACE_H_
20 | #define SEMANTIC_FUSION_INTERFACE_H_
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | // This is just to get Blobs for now
28 | #include
29 | #include
30 | #include
31 |
32 | #include "CRF/densecrf.h"
33 |
34 | class SemanticFusionInterface {
35 | public:
36 | SemanticFusionInterface(const int num_classes, const int prior_sample_size,
37 | const int max_components = 3000000, const float colour_threshold = 0.0)
38 | : current_table_size_(0)
39 | , num_classes_(num_classes)
40 | , prior_sample_size_(prior_sample_size)
41 | , max_components_(max_components)
42 | , colour_threshold_(colour_threshold)
43 | {
44 | // This table contains for each component (surfel) the probability of
45 | // it being associated with each class
46 | class_probabilities_gpu_.reset(new caffe::Blob(1,1,num_classes_,max_components_));
47 | class_probabilities_gpu_buffer_.reset(new caffe::Blob(1,1,num_classes_,max_components_));
48 | // This contains two rows - one is the max class (if none then negative) the
49 | // other is the probability
50 | class_max_gpu_.reset(new caffe::Blob(1,1,3,max_components_));
51 | class_max_gpu_buffer_.reset(new caffe::Blob(1,1,3,max_components_));
52 | rendered_class_probabilities_gpu_.reset(new caffe::Blob(1,num_classes_,640,480));
53 | }
54 | virtual ~SemanticFusionInterface() {}
55 |
56 | int UpdateSurfelProbabilities(const int surfel_id, const std::vector& class_probs);
57 | void UpdateProbabilities(std::shared_ptr > probs,const std::unique_ptr& map);
58 | void UpdateProbabilityTable(const std::unique_ptr& map);
59 | void CalculateProjectedProbabilityMap(const std::unique_ptr& map);
60 |
61 | void CRFUpdate(const std::unique_ptr& map, const int iterations);
62 |
63 | void SaveArgMaxPredictions(std::string& filename,const std::unique_ptr& map);
64 | std::shared_ptr > get_rendered_probability();
65 | std::shared_ptr > get_class_max_gpu();
66 | int max_num_components() const;
67 | private:
68 |
69 | // Returns negative if the class is below the threshold - otherwise returns the class
70 | std::vector > class_probabilities_;
71 | std::shared_ptr > class_probabilities_gpu_;
72 | int current_table_size_;
73 | // This is used to store the table swap after updating
74 | std::shared_ptr > class_probabilities_gpu_buffer_;
75 | std::shared_ptr > class_max_gpu_;
76 | std::shared_ptr > class_max_gpu_buffer_;
77 | // This stores the rendered probabilities of surfels from the map
78 | std::shared_ptr > rendered_class_probabilities_gpu_;
79 | const int num_classes_;
80 | const int prior_sample_size_;
81 | const int max_components_;
82 | const float colour_threshold_;
83 | };
84 |
85 | #endif /* SEMANTIC_FUSION_INTERFACE_H_ */
86 |
--------------------------------------------------------------------------------
/src/cnn_interface/CaffeInterface.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of SemanticFusion.
3 | *
4 | * Copyright (C) 2017 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is SemanticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #include "CaffeInterface.h"
20 | #include
21 | #include
22 | #include
23 | #include
24 |
25 |
26 | bool CaffeInterface::Init(const std::string& model_path, const std::string& weights) {
27 | caffe::Caffe::SetDevice(0);
28 | caffe::Caffe::set_mode(caffe::Caffe::GPU);
29 | network_.reset(new caffe::Net(model_path, caffe::TEST));
30 | network_->CopyTrainedLayersFrom(weights);
31 | initialised_ = true;
32 | return true;
33 | }
34 |
35 | int CaffeInterface::num_output_classes() {
36 | if (!initialised_) {
37 | return 0;
38 | }
39 | return network_->output_blobs()[0]->shape()[1];
40 | }
41 |
42 | std::shared_ptr > CaffeInterface::ProcessFrame(const ImagePtr rgb, const DepthPtr depth,
43 | const int height, const int width) {
44 | if (!initialised_) {
45 | return std::shared_ptr >();
46 | }
47 | cv::Mat input_image(height,width,CV_8UC3, rgb);
48 | cv::Mat input_depth(height,width,CV_16UC1, depth);
49 | std::vector* > inputs = network_->input_blobs();
50 | CHECK_EQ(inputs.size(),1) << "Only single inputs supported";
51 | const int network_width = inputs[0]->width();
52 | const int network_height = inputs[0]->height();
53 | cv::Mat resized_image(network_height,network_width,CV_8UC3);
54 | cv::resize(input_image,resized_image,resized_image.size(),0,0);
55 | cv::Mat resized_depth(network_height,network_width,CV_16UC1);
56 | cv::resize(input_depth,resized_depth,resized_depth.size(),0,0,cv::INTER_NEAREST);
57 |
58 | // This performs inpainting of the depth map on the fly, however for NYU
59 | // experiments we used the same matlab inpainting given with the toolkit, so
60 | // the input to the CNN is the same as with the normal NYU baseline results
61 | cv::Mat depthf(network_width,network_height, CV_8UC1);
62 | resized_depth.convertTo(depthf, CV_8UC1, 25.0/1000.0);
63 | const unsigned char noDepth = 0;
64 | cv::inpaint(depthf, (depthf == noDepth), depthf, 5.0, cv::INPAINT_TELEA);
65 |
66 | float* input_data = inputs[0]->mutable_cpu_data();
67 | const float mean[] = {104.0,117.0,123.0};
68 | for (int h = 0; h < network_height; ++h) {
69 | const uchar* image_ptr = resized_image.ptr(h);
70 | const uint16_t* depth_ptr = resized_depth.ptr(h);
71 | int image_index = 0;
72 | int depth_index = 0;
73 | for (int w = 0; w < network_width; ++w) {
74 | float r = static_cast(image_ptr[image_index++]);
75 | float g = static_cast(image_ptr[image_index++]);
76 | float b = static_cast(image_ptr[image_index++]);
77 | const int b_offset = ((0 * network_height) + h) * network_width + w;
78 | const int g_offset = ((1 * network_height) + h) * network_width + w;
79 | const int r_offset = ((2 * network_height) + h) * network_width + w;
80 | input_data[b_offset] = b - mean[0];
81 | input_data[g_offset] = g - mean[1];
82 | input_data[r_offset] = r - mean[2];
83 | if (inputs[0]->channels() == 4) {
84 | //Convert to m from mm, and remove mean of 2.8m
85 | float d = static_cast(depth_ptr[depth_index++]) * (1.0f/1000.0f) ;
86 | const int d_offset = ((3 * network_height) + h) * network_width + w;
87 | input_data[d_offset] = d - 2.841;
88 | }
89 | }
90 | }
91 | float loss;
92 | const std::vector* > output = network_->Forward(inputs,&loss);
93 | if (!output_probabilities_) {
94 | output_probabilities_.reset(new caffe::Blob(output[0]->shape()));
95 | }
96 | output_probabilities_->CopyFrom(*output[0]);
97 | return output_probabilities_;
98 | }
99 |
--------------------------------------------------------------------------------
/src/utilities/RawLogReader.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of ElasticFusion.
3 | *
4 | * Copyright (C) 2015 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is ElasticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #include "RawLogReader.h"
20 |
21 | RawLogReader::RawLogReader(std::string file, bool flipColors)
22 | : LogReader(file, flipColors)
23 | {
24 | assert(pangolin::FileExists(file.c_str()));
25 |
26 | fp = fopen(file.c_str(), "rb");
27 |
28 | currentFrame = 0;
29 |
30 | assert(fread(&numFrames, sizeof(int32_t), 1, fp));
31 |
32 | depthReadBuffer = new unsigned char[numPixels * 2];
33 | imageReadBuffer = new unsigned char[numPixels * 3];
34 | decompressionBufferDepth = new Bytef[Resolution::getInstance().numPixels() * 2];
35 | decompressionBufferImage = new Bytef[Resolution::getInstance().numPixels() * 3];
36 | }
37 |
38 | RawLogReader::~RawLogReader()
39 | {
40 | delete [] depthReadBuffer;
41 | delete [] imageReadBuffer;
42 | delete [] decompressionBufferDepth;
43 | delete [] decompressionBufferImage;
44 |
45 | fclose(fp);
46 | }
47 |
48 | void RawLogReader::getBack()
49 | {
50 | assert(filePointers.size() > 0);
51 |
52 | fseek(fp, filePointers.top(), SEEK_SET);
53 |
54 | filePointers.pop();
55 |
56 | getCore();
57 | }
58 |
59 | void RawLogReader::getNext()
60 | {
61 | filePointers.push(ftell(fp));
62 |
63 | getCore();
64 | }
65 |
66 | void RawLogReader::getCore()
67 | {
68 | assert(fread(×tamp, sizeof(int64_t), 1, fp));
69 |
70 | assert(fread(&depthSize, sizeof(int32_t), 1, fp));
71 | assert(fread(&imageSize, sizeof(int32_t), 1, fp));
72 |
73 | assert(fread(depthReadBuffer, depthSize, 1, fp));
74 |
75 | if(imageSize > 0)
76 | {
77 | assert(fread(imageReadBuffer, imageSize, 1, fp));
78 | }
79 |
80 | if(depthSize == numPixels * 2)
81 | {
82 | memcpy(&decompressionBufferDepth[0], depthReadBuffer, numPixels * 2);
83 | }
84 | else
85 | {
86 | unsigned long decompLength = numPixels * 2;
87 | uncompress(&decompressionBufferDepth[0], (unsigned long *)&decompLength, (const Bytef *)depthReadBuffer, depthSize);
88 | }
89 |
90 | if(imageSize == numPixels * 3)
91 | {
92 | memcpy(&decompressionBufferImage[0], imageReadBuffer, numPixels * 3);
93 | }
94 | else if(imageSize > 0)
95 | {
96 | jpeg.readData(imageReadBuffer, imageSize, (unsigned char *)&decompressionBufferImage[0]);
97 | }
98 | else
99 | {
100 | memset(&decompressionBufferImage[0], 0, numPixels * 3);
101 | }
102 |
103 | depth = (unsigned short *)decompressionBufferDepth;
104 | rgb = (unsigned char *)&decompressionBufferImage[0];
105 |
106 | if(flipColors)
107 | {
108 | for(int i = 0; i < Resolution::getInstance().numPixels() * 3; i += 3)
109 | {
110 | std::swap(rgb[i + 0], rgb[i + 2]);
111 | }
112 | }
113 |
114 | currentFrame++;
115 | }
116 |
117 | void RawLogReader::fastForward(int frame)
118 | {
119 | while(currentFrame < frame && hasMore())
120 | {
121 | filePointers.push(ftell(fp));
122 |
123 | assert(fread(×tamp, sizeof(int64_t), 1, fp));
124 |
125 | assert(fread(&depthSize, sizeof(int32_t), 1, fp));
126 | assert(fread(&imageSize, sizeof(int32_t), 1, fp));
127 |
128 | assert(fread(depthReadBuffer, depthSize, 1, fp));
129 |
130 | if(imageSize > 0)
131 | {
132 | assert(fread(imageReadBuffer, imageSize, 1, fp));
133 | }
134 |
135 | currentFrame++;
136 | }
137 | }
138 |
139 | int RawLogReader::getNumFrames()
140 | {
141 | return numFrames;
142 | }
143 |
144 | bool RawLogReader::hasMore()
145 | {
146 | return currentFrame + 1 < numFrames;
147 | }
148 |
149 | bool RawLogReader::rewound()
150 | {
151 | if(filePointers.size() == 0)
152 | {
153 | fclose(fp);
154 | fp = fopen(file.c_str(), "rb");
155 |
156 | assert(fread(&numFrames, sizeof(int32_t), 1, fp));
157 |
158 | currentFrame = 0;
159 |
160 | return true;
161 | }
162 |
163 | return false;
164 | }
165 |
166 | const std::string RawLogReader::getFile()
167 | {
168 | return file;
169 | }
170 |
171 | void RawLogReader::setAuto(bool value)
172 | {
173 |
174 | }
175 |
--------------------------------------------------------------------------------
/src/utilities/Array.h:
--------------------------------------------------------------------------------
1 | /*
2 | * COPYRIGHT
3 | *
4 | * All contributions by the University of California:
5 | * Copyright (c) 2014, 2015, The Regents of the University of California (Regents)
6 | * All rights reserved.
7 | *
8 | * All other contributions:
9 | * Copyright (c) 2014, 2015, the respective contributors
10 | * All rights reserved.
11 | *
12 | * Caffe uses a shared copyright model: each contributor holds copyright over
13 | * their contributions to Caffe. The project versioning records all such
14 | * contribution and copyright details. If a contributor wants to further mark
15 | * their specific copyright on a particular contribution, they should indicate
16 | * their copyright solely in the commit message of the change when it is
17 | * committed.
18 | *
19 | * LICENSE
20 | *
21 | * Redistribution and use in source and binary forms, with or without
22 | * modification, are permitted provided that the following conditions are met:
23 | *
24 | * 1. Redistributions of source code must retain the above copyright notice, this
25 | * list of conditions and the following disclaimer.
26 | * 2. Redistributions in binary form must reproduce the above copyright notice,
27 | * this list of conditions and the following disclaimer in the documentation
28 | * and/or other materials provided with the distribution.
29 | *
30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
31 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
34 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 | */
41 |
42 | #ifndef ARRAY_H_
43 | #define ARRAY_H_
44 |
45 | #include
46 | #include
47 |
48 | #include
49 | #include
50 | #include
51 | #include
52 | #include
53 |
54 | #include
55 | #include
56 |
57 | inline void MallocHost(void** ptr, size_t size, bool* use_cuda) {
58 | CUDA_CHECK(cudaMallocHost(ptr, size));
59 | *use_cuda = true;
60 | return;
61 | }
62 |
63 | inline void FreeHost(void* ptr, bool use_cuda) {
64 | if (use_cuda) {
65 | CUDA_CHECK(cudaFreeHost(ptr));
66 | return;
67 | }
68 | free(ptr);
69 | }
70 |
71 |
72 | class SyncedMemory {
73 | public:
74 | SyncedMemory()
75 | : cpu_ptr_(NULL), gpu_ptr_(NULL), size_(0), head_(UNINITIALIZED),
76 | own_cpu_data_(false), cpu_malloc_use_cuda_(false), own_gpu_data_(false),
77 | gpu_device_(-1) {}
78 | explicit SyncedMemory(size_t size)
79 | : cpu_ptr_(NULL), gpu_ptr_(NULL), size_(size), head_(UNINITIALIZED),
80 | own_cpu_data_(false), cpu_malloc_use_cuda_(false), own_gpu_data_(false),
81 | gpu_device_(-1) {}
82 | ~SyncedMemory();
83 | const void* cpu_data();
84 | void set_cpu_data(void* data);
85 | const void* gpu_data();
86 | void set_gpu_data(void* data);
87 | void* mutable_cpu_data();
88 | void* mutable_gpu_data();
89 | enum SyncedHead { UNINITIALIZED, HEAD_AT_CPU, HEAD_AT_GPU, SYNCED };
90 | SyncedHead head() { return head_; }
91 | size_t size() { return size_; }
92 |
93 | void async_gpu_push(const cudaStream_t& stream);
94 |
95 | private:
96 | void to_cpu();
97 | void to_gpu();
98 | void* cpu_ptr_;
99 | void* gpu_ptr_;
100 | size_t size_;
101 | SyncedHead head_;
102 | bool own_cpu_data_;
103 | bool cpu_malloc_use_cuda_;
104 | bool own_gpu_data_;
105 | int gpu_device_;
106 | };
107 |
108 | class Array3D {
109 | public:
110 | explicit Array3D(const int channels, const int height, const int width)
111 | : data_()
112 | , capacity_(0)
113 | {
114 | Reshape(channels,height,width);
115 | }
116 |
117 | void Reshape(const int channels, const int height, const int width);
118 |
119 | inline int count() const { return height_ * width_ * channels_; }
120 | inline int channels() const { return channels_; }
121 | inline int height() const { return height_; }
122 | inline int width() const { return width_; }
123 | inline int offset(const int c, const int h, const int w) const {
124 | return ((c * height() + h) * width() + w);
125 | }
126 |
127 | const float* cpu_data() const {
128 | return (const float*) data_->cpu_data();
129 | }
130 | float* mutable_cpu_data() {
131 | return static_cast(data_->mutable_cpu_data());
132 | }
133 | const float* gpu_data() const {
134 | return (const float*)data_->gpu_data();
135 | }
136 | float* mutable_gpu_data() {
137 | return static_cast(data_->mutable_gpu_data());
138 | }
139 |
140 | protected:
141 | std::shared_ptr data_;
142 | int capacity_;
143 | int channels_;
144 | int height_;
145 | int width_;
146 | };
147 |
148 | #endif /* ARRAY_H_ */
149 |
--------------------------------------------------------------------------------
/src/map_interface/ElasticFusionInterface.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of SemanticFusion.
3 | *
4 | * Copyright (C) 2017 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is SemanticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #include "ElasticFusionInterface.h"
20 | #include "ElasticFusionCuda.h"
21 | #include
22 | #include
23 |
24 | #include
25 |
26 | float encode_colour(ClassColour rgb_colour) {
27 | int colour = rgb_colour.r;
28 | colour = (colour << 8) + rgb_colour.g;
29 | colour = (colour << 8) + rgb_colour.b;
30 | return float(colour);
31 | }
32 |
33 | bool ElasticFusionInterface::Init(std::vector class_colour_lookup) {
34 | GLXContext context = glXGetCurrentContext();
35 | if (context == nullptr) {
36 | return false;
37 | }
38 | // These are the regular elastic fusion parameters. The depthCut has been
39 | // increase to 8m. Also to prevent the white border in the NYU the ICP weight
40 | // can be turned to 100, as in the commented line below. However, the code
41 | // in elasticfusion has also been modified to ignore a 16 pixel border of the
42 | // RGB residual, which allows some RGB tracking while also ignoring the border.
43 | elastic_fusion_.reset(new ElasticFusion(200, 35000, 5e-05, 1e-05, true,
44 | false,false,115,10,8,10));
45 | //false,false,115,10,8,100));
46 | const int surfel_render_size = Resolution::getInstance().width() *
47 | Resolution::getInstance().height();
48 | surfel_ids_.resize(surfel_render_size);
49 | initialised_ = true;
50 | class_color_lookup_.clear();
51 | for (unsigned int class_id = 0; class_id < class_colour_lookup.size(); ++class_id) {
52 | class_color_lookup_.push_back(encode_colour(class_colour_lookup[class_id]));
53 | }
54 | cudaMalloc((void **)&class_color_lookup_gpu_, class_color_lookup_.size() * sizeof(float));
55 | cudaMemcpy(class_color_lookup_gpu_, class_color_lookup_.data(), class_color_lookup_.size() * sizeof(float), cudaMemcpyHostToDevice);
56 | return true;
57 | }
58 |
59 | ElasticFusionInterface::~ElasticFusionInterface() {
60 | cudaFree(class_color_lookup_gpu_);
61 | }
62 |
63 | int* ElasticFusionInterface::GetDeletedSurfelIdsGpu() {
64 | if (elastic_fusion_) {
65 | return elastic_fusion_->getGlobalModel().getDeletedSurfelsGpu();
66 | }
67 | return nullptr;
68 | }
69 |
70 | bool ElasticFusionInterface::ProcessFrame(const ImagePtr rgb, const DepthPtr depth, const int64_t timestamp) {
71 | if (elastic_fusion_) {
72 | elastic_fusion_->processFrame(rgb,depth,timestamp);
73 | if (elastic_fusion_->getLost()) {
74 | return false;
75 | }
76 | return true;
77 | }
78 | return false;
79 | }
80 |
81 | GPUTexture* ElasticFusionInterface::getRawImageTexture() {
82 | return elastic_fusion_->getTextures()[GPUTexture::RGB];
83 | }
84 |
85 | GPUTexture* ElasticFusionInterface::getIdsTexture() {
86 | return elastic_fusion_->getIndexMap().surfelIdTex();
87 | }
88 |
89 | const std::vector& ElasticFusionInterface::GetSurfelIdsCpu() {
90 | GPUTexture* id_tex = elastic_fusion_->getIndexMap().surfelIdTex();
91 | id_tex->texture->Download(surfel_ids_.data(),GL_LUMINANCE_INTEGER_EXT,GL_INT);
92 | return surfel_ids_;
93 | }
94 |
95 | cudaTextureObject_t ElasticFusionInterface::GetSurfelIdsGpu() {
96 | GPUTexture* id_tex = elastic_fusion_->getIndexMap().surfelIdTex();
97 | return id_tex->texObj;
98 | }
99 |
100 | void ElasticFusionInterface::UpdateSurfelClass(const int surfel_id, const int class_id) {
101 | elastic_fusion_->getGlobalModel().updateSurfelClass(surfel_id,class_color_lookup_[class_id]);
102 | }
103 |
104 | void ElasticFusionInterface::UpdateSurfelClassGpu(const int n, const float* surfelclasses, const float* surfelprobs, const float threshold) {
105 | if (elastic_fusion_) {
106 | float* map_surfels = elastic_fusion_->getGlobalModel().getMapSurfelsGpu();
107 | updateSurfelClasses(n, map_surfels, surfelclasses, surfelprobs, class_color_lookup_gpu_, threshold);
108 | }
109 | }
110 |
111 | void ElasticFusionInterface::RenderMapToBoundGlBuffer(const pangolin::OpenGlRenderState& camera,const bool classes) {
112 | elastic_fusion_->getGlobalModel().renderPointCloud(camera.GetProjectionModelViewMatrix(),
113 | elastic_fusion_->getConfidenceThreshold(),
114 | false,
115 | false,
116 | true,
117 | false,
118 | false,
119 | false,
120 | classes,
121 | elastic_fusion_->getTick(),
122 | elastic_fusion_->getTimeDelta());
123 | }
124 |
--------------------------------------------------------------------------------
/src/semantic_fusion/CRF/densecrf.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2011, Philipp Krähenbühl
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright
10 | notice, this list of conditions and the following disclaimer in the
11 | documentation and/or other materials provided with the distribution.
12 | * Neither the name of the Stanford University nor the
13 | names of its contributors may be used to endorse or promote products
14 | derived from this software without specific prior written permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY Philipp Krähenbühl ''AS IS'' AND ANY
17 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL Philipp Krähenbühl BE LIABLE FOR ANY
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 | */
27 |
28 | #pragma once
29 |
30 | #include
31 | #include
32 |
33 | class PairwisePotential{
34 | public:
35 | virtual ~PairwisePotential();
36 | virtual void apply( float * out_values, const float * in_values, float * tmp, int value_size ) const = 0;
37 | };
38 | class SemiMetricFunction{
39 | public:
40 | virtual ~SemiMetricFunction();
41 | // For two probabilities apply the semi metric transform: v_i = sum_j mu_ij u_j
42 | virtual void apply( float * out_values, const float * in_values, int value_size ) const = 0;
43 | };
44 |
45 |
46 | class DenseCRF {
47 | protected:
48 |
49 | // Number of variables and labels
50 | int N_, M_;
51 | float *unary_, *additional_unary_, *current_, *next_, *tmp_;
52 |
53 | // Store all pairwise potentials
54 | std::vector pairwise_;
55 |
56 |
57 | // Auxillary functions
58 | void expAndNormalize( float* out, const float* in, float scale = 1.0, float relax = 1.0 );
59 |
60 | // Don't copy this object, bad stuff will happen
61 | DenseCRF( DenseCRF & o ){}
62 | public:
63 | // Create a dense CRF model of size N with M labels
64 | DenseCRF( int N, int M );
65 | virtual ~DenseCRF();
66 | // Add a pairwise potential defined over some feature space
67 | // The potential will have the form: w*exp(-0.5*|f_i - f_j|^2)
68 | // The kernel shape should be captured by transforming the
69 | // features before passing them into this function
70 | void addPairwiseEnergy( const float * features, int D, float w=1.0f, const SemiMetricFunction * function=NULL );
71 |
72 | // Add your own favorite pairwise potential (ownwership will be transfered to this class)
73 | void addPairwiseEnergy( PairwisePotential* potential );
74 |
75 | // Set the unary potential for all variables and labels (memory order is [x0l0 x0l1 x0l2 .. x1l0 x1l1 ...])
76 | void setUnaryEnergy( const float * unary );
77 |
78 | // Run inference and return the probabilities
79 | void inference( int n_iterations, float* result, float relax=1.0 );
80 |
81 | // Run MAP inference and return the map for each pixel
82 | void map( int n_iterations, short int* result, float relax=1.0 );
83 |
84 | // Step by step inference
85 | void startInference();
86 | void stepInference( float relax = 1.0 );
87 |
88 | // Run inference and return the pointer to the result
89 | float* runInference( int n_iterations, float relax);
90 | };
91 |
92 | class DenseCRF2D:public DenseCRF{
93 | protected:
94 | // Width, height of the 2d grid
95 | int W_, H_;
96 | public:
97 | // Create a 2d dense CRF model of size W x H with M labels
98 | DenseCRF2D( int W, int H, int M );
99 | virtual ~DenseCRF2D();
100 | // Add a Gaussian pairwise potential with standard deviation sx and sy
101 | void addPairwiseGaussian( float sx, float sy, float w, const SemiMetricFunction * function=NULL );
102 |
103 | // Add a Bilateral pairwise potential with spacial standard deviations sx, sy and color standard deviations sr,sg,sb
104 | void addPairwiseBilateral( float sx, float sy, float sr, float sg, float sb, const unsigned char * im, float w, const SemiMetricFunction * function=NULL );
105 | };
106 |
107 | class DenseCRF3D:public DenseCRF{
108 | protected:
109 | const float spatial_stddev_;
110 | const float colour_stddev_;
111 | const float normal_stddev_;
112 | public:
113 | // Create a 2d dense CRF model of size W x H with M labels
114 | DenseCRF3D(int N, int M, float spatial_stddev, float colour_stddev, float normal_stddev );
115 | virtual ~DenseCRF3D();
116 | // Add a Gaussian pairwise potential with standard deviation sx and sy
117 | void addPairwiseGaussian(const float* surfel_data, float w, const std::vector& valid);
118 | // Add a Bilateral pairwise potential with spacial standard deviations sx, sy and color standard deviations sr,sg,sb
119 | void addPairwiseBilateral(const float* surfel_data, float w, const std::vector& valid);
120 | // Add a Bilateral pairwise potential with spacial standard deviations sx, sy and color standard deviations sr,sg,sb
121 | void addPairwiseNormal(const float* surfel_data, float w);
122 | };
123 |
--------------------------------------------------------------------------------
/src/utilities/Array.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * COPYRIGHT
3 | *
4 | * All contributions by the University of California:
5 | * Copyright (c) 2014, 2015, The Regents of the University of California (Regents)
6 | * All rights reserved.
7 | *
8 | * All other contributions:
9 | * Copyright (c) 2014, 2015, the respective contributors
10 | * All rights reserved.
11 | *
12 | * Caffe uses a shared copyright model: each contributor holds copyright over
13 | * their contributions to Caffe. The project versioning records all such
14 | * contribution and copyright details. If a contributor wants to further mark
15 | * their specific copyright on a particular contribution, they should indicate
16 | * their copyright solely in the commit message of the change when it is
17 | * committed.
18 | *
19 | * LICENSE
20 | *
21 | * Redistribution and use in source and binary forms, with or without
22 | * modification, are permitted provided that the following conditions are met:
23 | *
24 | * 1. Redistributions of source code must retain the above copyright notice, this
25 | * list of conditions and the following disclaimer.
26 | * 2. Redistributions in binary form must reproduce the above copyright notice,
27 | * this list of conditions and the following disclaimer in the documentation
28 | * and/or other materials provided with the distribution.
29 | *
30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
31 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
34 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 | */
41 | #include "Array.h"
42 |
43 | void Array3D::Reshape(const int channels, const int height, const int width) {
44 | channels_ = channels;
45 | height_ = height;
46 | width_ = width;
47 | if (count() > capacity_) {
48 | capacity_ = count();
49 | data_.reset(new SyncedMemory(capacity_ * sizeof(float)));
50 | }
51 | }
52 |
53 | SyncedMemory::~SyncedMemory() {
54 | if (cpu_ptr_ && own_cpu_data_) {
55 | FreeHost(cpu_ptr_, cpu_malloc_use_cuda_);
56 | }
57 | if (gpu_ptr_ && own_gpu_data_) {
58 | int initial_device;
59 | cudaGetDevice(&initial_device);
60 | if (gpu_device_ != -1) {
61 | CUDA_CHECK(cudaSetDevice(gpu_device_));
62 | }
63 | CUDA_CHECK(cudaFree(gpu_ptr_));
64 | cudaSetDevice(initial_device);
65 | }
66 | }
67 |
68 | inline void SyncedMemory::to_cpu() {
69 | switch (head_) {
70 | case UNINITIALIZED:
71 | MallocHost(&cpu_ptr_, size_, &cpu_malloc_use_cuda_);
72 | memset(cpu_ptr_, 0, size_);
73 | head_ = HEAD_AT_CPU;
74 | own_cpu_data_ = true;
75 | break;
76 | case HEAD_AT_GPU:
77 | if (cpu_ptr_ == NULL) {
78 | MallocHost(&cpu_ptr_, size_, &cpu_malloc_use_cuda_);
79 | own_cpu_data_ = true;
80 | }
81 | cudaMemcpy(cpu_ptr_, gpu_ptr_, size_, cudaMemcpyDefault);
82 | head_ = SYNCED;
83 | break;
84 | case HEAD_AT_CPU:
85 | case SYNCED:
86 | break;
87 | }
88 | }
89 |
90 | inline void SyncedMemory::to_gpu() {
91 | switch (head_) {
92 | case UNINITIALIZED:
93 | CUDA_CHECK(cudaGetDevice(&gpu_device_));
94 | CUDA_CHECK(cudaMalloc(&gpu_ptr_, size_));
95 | cudaMemset(gpu_ptr_,0,size_);
96 | head_ = HEAD_AT_GPU;
97 | own_gpu_data_ = true;
98 | break;
99 | case HEAD_AT_CPU:
100 | if (gpu_ptr_ == NULL) {
101 | CUDA_CHECK(cudaGetDevice(&gpu_device_));
102 | CUDA_CHECK(cudaMalloc(&gpu_ptr_, size_));
103 | own_gpu_data_ = true;
104 | }
105 | cudaMemcpy(gpu_ptr_, cpu_ptr_, size_, cudaMemcpyDefault);
106 | head_ = SYNCED;
107 | break;
108 | case HEAD_AT_GPU:
109 | case SYNCED:
110 | break;
111 | }
112 | }
113 |
114 | const void* SyncedMemory::cpu_data() {
115 | to_cpu();
116 | return (const void*)cpu_ptr_;
117 | }
118 |
119 | void SyncedMemory::set_cpu_data(void* data) {
120 | CHECK(data);
121 | if (own_cpu_data_) {
122 | FreeHost(cpu_ptr_, cpu_malloc_use_cuda_);
123 | }
124 | cpu_ptr_ = data;
125 | head_ = HEAD_AT_CPU;
126 | own_cpu_data_ = false;
127 | }
128 |
129 | const void* SyncedMemory::gpu_data() {
130 | to_gpu();
131 | return (const void*)gpu_ptr_;
132 | }
133 |
134 | void SyncedMemory::set_gpu_data(void* data) {
135 | CHECK(data);
136 | if (own_gpu_data_) {
137 | int initial_device;
138 | cudaGetDevice(&initial_device);
139 | if (gpu_device_ != -1) {
140 | CUDA_CHECK(cudaSetDevice(gpu_device_));
141 | }
142 | CUDA_CHECK(cudaFree(gpu_ptr_));
143 | cudaSetDevice(initial_device);
144 | }
145 | gpu_ptr_ = data;
146 | head_ = HEAD_AT_GPU;
147 | own_gpu_data_ = false;
148 | }
149 |
150 | void* SyncedMemory::mutable_cpu_data() {
151 | to_cpu();
152 | head_ = HEAD_AT_CPU;
153 | return cpu_ptr_;
154 | }
155 |
156 | void* SyncedMemory::mutable_gpu_data() {
157 | to_gpu();
158 | head_ = HEAD_AT_GPU;
159 | return gpu_ptr_;
160 | }
161 |
162 | void SyncedMemory::async_gpu_push(const cudaStream_t& stream) {
163 | CHECK(head_ == HEAD_AT_CPU);
164 | if (gpu_ptr_ == NULL) {
165 | CUDA_CHECK(cudaGetDevice(&gpu_device_));
166 | CUDA_CHECK(cudaMalloc(&gpu_ptr_, size_));
167 | own_gpu_data_ = true;
168 | }
169 | const cudaMemcpyKind put = cudaMemcpyHostToDevice;
170 | CUDA_CHECK(cudaMemcpyAsync(gpu_ptr_, cpu_ptr_, size_, put, stream));
171 | // Assume caller will synchronize on the stream before use
172 | head_ = SYNCED;
173 | }
174 |
--------------------------------------------------------------------------------
/src/utilities/PNGLogReader.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of ElasticFusion.
3 | *
4 | * Copyright (C) 2015 Imperial College London
5 | *
6 | * The use of the code within this file and all code within files that
7 | * make up the software that is ElasticFusion is permitted for
8 | * non-commercial purposes only. The full terms and conditions that
9 | * apply to the code within this file are detailed within the LICENSE.txt
10 | * file and at
11 | * unless explicitly stated. By downloading this file you agree to
12 | * comply with these terms.
13 | *
14 | * If you wish to use any of this code for commercial purposes then
15 | * please email researchcontracts.engineering@imperial.ac.uk.
16 | *
17 | */
18 |
19 | #include "PNGLogReader.h"
20 | #include
21 | #include
22 | #include
23 | #include