├── .gitignore ├── README.md ├── code └── segmentation_exporter │ ├── README │ ├── assert_log │ ├── CMakeLists.txt │ ├── assert_log.cpp │ ├── assert_log.h │ └── depend.cmake │ ├── cmake │ ├── FindOpenCV.cmake │ ├── FindProtoBuf.cmake │ ├── LibFindMacros.cmake │ └── common.cmake │ ├── segment_util │ ├── CMakeLists.txt │ ├── depend.cmake │ ├── segmentation.proto │ ├── segmentation_io.cpp │ ├── segmentation_io.h │ ├── segmentation_util.cpp │ └── segmentation_util.h │ └── segmentation_exporter │ ├── CMakeLists.txt │ ├── depend.cmake │ └── main.cpp └── data └── cars1_segment.pb /.gitignore: -------------------------------------------------------------------------------- 1 | code/segmentation_exporter/segmentation_exporter/BUILD/* 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository contains C++ code to export the video segmentations from the system described in the paper Efficient Hierarchical Graph-Based Video Segmentation. The system described in this paper returns segmentations as Protocol Buffer files. The exporter contained in this repository converts these Protocol Buffer files into image sequences. 2 | 3 | Note that most of this code was written by Matthias Grundmann and distributed on his project page. I just hacked his code to export the segmentations rather than visualize them in a GUI. 4 | 5 | ### Requirements 6 | 7 | * __OpenCV__. I used OpenCV 2.4.6.1, but any recent version of OpenCV should work. 8 | * __Protobuf__. I used ProtoBuf 2.5.0, but any recent version of Protobuf should work. 9 | * __The CMake GUI__. I used CMake 2.8.10, but any recent version of CMake should work. 10 | * http://www.cmake.org/cmake/resources/software.html 11 | 12 | On Mac OSX, OpenCV and Protobuf are easy to obtain via MacPorts. From a terminal window, simply type the following: 13 | 14 | ``` 15 | $ sudo port install opencv 16 | $ sudo port install protobuf-cpp 17 | ``` 18 | 19 | ### Build Instructions 20 | 21 | * Point the CMake GUI to the code/segmentation_exporter/segmentation_exporter folder and specify a build folder. 22 | * Hit Configure. Select the default compiler options. On Mac OSX, CMake should find all the build dependencies automatically. If CMake doesn't find these dependencies automatically, enter in the missing OpenCV and Protobuf CMake variables manually and hit Configure again. 23 | * Hit Generate. 24 | * Navigate to the build folder in a terminal window and type make. 25 | * Now you can run the segmentation_exporter executable. 26 | 27 | ### Usage 28 | 29 | * Obtain a video segmentation from here. 30 | * Run the segmentation_exporter executable from this repository as follows: 31 | 32 | ``` 33 | $ ./segmentation_exporter input_segmentation.pb output_folder 34 | ``` 35 | -------------------------------------------------------------------------------- /code/segmentation_exporter/README: -------------------------------------------------------------------------------- 1 | This is sample program to read and visualize the .pb files, obtained 2 | from our Video-Segmentation server. The contents of this package 3 | are open-source, feel free to adapt for our own research and other use. 4 | 5 | If you use, the segmentation and/or sample, please reference: 6 | 7 | @article{GrundmannKwatra2010, 8 | author = {Matthias Grundmann and Vivek Kwatra and Mei Han and Irfan Essa}, 9 | title = {Efficient Hierarchical Graph-Based Video Segmentation}, 10 | journal = {IEEE CVPR}, 11 | year = {2010}, 12 | } 13 | 14 | 15 | Version: 0.11 - 9/20/2010: Small adaptions in build process for windows and linux. 16 | Version: 0.1 - 7/1/2010: Initial release. 17 | 18 | 19 | 20 | Instructions: 21 | You will need cmake (>= 2.6), OpenCV (>= 1.0) and the protocol buffer library 22 | from Google (http://code.google.com/p/protobuf/) to build this example. 23 | 24 | To build the example: 25 | - Create a new binary directory that will contain the project files (PROJECT_DIR) 26 | - Use cmake GUI to configure the project in any project format you want, 27 | or from command prompt to configure makefiles, use: 28 | > cd PROJECT_DIR 29 | > cmake SRC_DIR/segmentation_example 30 | > make 31 | 32 | - Run with: segmentation_example YOUR_SEGMENTATION_FILE.pb 33 | 34 | 35 | Regarding protobuffers on windows: 36 | 37 | Setting up protobuffers on windows is a bit of pain, but you are probably used to it :). 38 | 39 | I recommend downloading the source, unpacking it and building it in visual studio. 40 | 1. After unpacking, go to the vsprojects subfolder, open protobuf.sln and build 41 | the whole SOLUTION in RELEASE mode. 42 | 2. Execute extract_includes.bat in the same directory. 43 | 3. Make a folder that will hold the created libraries, e.g. c:\third_party\protobuf 44 | 4. Setup a new environment variable PROTOBUF_DIR and let it to the directory you chose in 3. 45 | 5. Also add the directory you chose in 3 to your PATH variable. 46 | 5. Copy the google folder from vsprojects\include\google to the PROTOBUF_DIR 47 | 6. Copy libprotobuf.lib, libprotobuf-lite.lib, libprotoc.lib and protoc.exe from 48 | vsprojects\Release to PROTOBUF_DIR 49 | 7. That's it. 50 | 51 | For questions, email: grundmann.mattias@gmail.com 52 | 53 | 54 | 55 | 56 | Distributed under FreeBSD License: 57 | 58 | Copyright 2010 Matthias Grundmann, Vivek Kwatra, Mei Han, Irfan Essa, Georgia Institute of Technology. 59 | All rights reserved. 60 | 61 | Redistribution and use in source and binary forms, with or without modification, are 62 | permitted provided that the following conditions are met: 63 | 64 | 1. Redistributions of source code must retain the above copyright notice, this list of 65 | conditions and the following disclaimer. 66 | 67 | 2. Redistributions in binary form must reproduce the above copyright notice, this list 68 | of conditions and the following disclaimer in the documentation and/or other materials 69 | provided with the distribution. 70 | 71 | THIS SOFTWARE IS PROVIDED BY GEORGIA INSTITUTE OF TECHNOLOGY ``AS IS'' AND ANY EXPRESS OR IMPLIED 72 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 73 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OR 74 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 75 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 76 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 77 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 78 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 79 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 80 | 81 | The views and conclusions contained in the software and documentation are those of the 82 | authors and should not be interpreted as representing official policies, either expressed 83 | or implied, of Georgia Institute of Technology. 84 | -------------------------------------------------------------------------------- /code/segmentation_exporter/assert_log/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | project(assert_log) 4 | set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") 5 | include(${CMAKE_MODULE_PATH}/common.cmake) 6 | include("${CMAKE_SOURCE_DIR}/depend.cmake") 7 | 8 | set(SOURCES assert_log.cpp) 9 | headers_from_sources_cpp(HEADERS "${SOURCES}") 10 | 11 | set(SOURCES "${SOURCES}" "${HEADERS}") 12 | 13 | add_library(assert_log ${SOURCES}) 14 | 15 | apply_dependencies(assert_log) 16 | -------------------------------------------------------------------------------- /code/segmentation_exporter/assert_log/assert_log.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * assert_log.cpp 3 | * assert_log 4 | * 5 | * Created by Matthias Grundmann on 5/22/09. 6 | * Copyright 2009 Matthias Grundmann. All rights reserved. 7 | * 8 | */ 9 | 10 | #include "assert_log.h" -------------------------------------------------------------------------------- /code/segmentation_exporter/assert_log/assert_log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * assert_log.h 3 | * assert_log 4 | * 5 | * Created by Matthias Grundmann on 5/22/09. 6 | * Copyright 2009 Matthias Grundmann. All rights reserved. 7 | * 8 | * Based on: http://www.ddj.com/cpp/184403861 ('Assertions' by Andrei Alexandrescu) 9 | * Logging inspired by google testing framework. 10 | */ 11 | 12 | // Defines two macros 13 | // ASSERT_LOG 14 | // ASSURE_LOG 15 | 16 | // Usage: [ASSERT|ERROR]_LOG(condition) << {Some message} << {another message} ... 17 | // ASSERT_LOG will be ignored if NDEBUG is defined - otherwise it breaks at the current line. 18 | // ASSURE_LOG is ALWAYS evaluated. 19 | // It aborts if NDEBUG is defined otherwise breaks at the current line. 20 | 21 | 22 | 23 | #ifndef ASSERT_LOG_H__ 24 | #define ASSERT_LOG_H__ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | class AssertLog { 32 | public: 33 | 34 | AssertLog(const std::string& file, const std::string& function, int line) : 35 | file_(file), function_(function), line_(line) {} 36 | 37 | AssertLog& operator()(bool condition) { 38 | cond_ = condition; 39 | return *this; 40 | } 41 | 42 | AssertLog(const AssertLog& log) : 43 | cond_(log.cond_), file_(log.file_), function_(log.function_), line_(log.line_) { 44 | log_message_ << log.log_message_.str(); 45 | } 46 | 47 | bool evaluate_condition() const { 48 | if (cond_) 49 | return true; 50 | else { 51 | std::cerr << "\n[ERROR] " << file_ << " (" << line_ << ") " << "in " << function_ 52 | << ": " << log_message_.str() << "\n"; 53 | return false; 54 | } 55 | } 56 | 57 | template 58 | AssertLog& operator<<(const T& output) { 59 | log_message_ << output; 60 | return *this; 61 | } 62 | 63 | private: 64 | bool cond_; 65 | std::ostringstream log_message_; 66 | std::string file_; 67 | std::string function_; 68 | int line_; 69 | 70 | }; 71 | 72 | #if defined __APPLE__ 73 | #define DEBUG_BREAK { __asm {int 3} } 74 | #elif defined _WIN32 75 | #include 76 | #define DEBUG_BREAK DebugBreak() 77 | #elif defined __linux 78 | 79 | extern "C"{ 80 | #include 81 | } 82 | 83 | #define DEBUG_BREAK raise(SIGINT) 84 | #endif 85 | 86 | // ASSERT_LOG definition. 87 | 88 | #ifdef NDEBUG 89 | 90 | #define ASSERT_LOG \ 91 | if (true) ; \ 92 | else \ 93 | struct Local { \ 94 | Local(const AssertLog& assert_log) { \ 95 | if (!assert_log.evaluate_condition()) { \ 96 | DEBUG_BREAK; \ 97 | } \ 98 | } \ 99 | } local_assert = AssertLog(__FILE__, __FUNCTION__, __LINE__) 100 | 101 | #else 102 | 103 | #define ASSERT_LOG \ 104 | if (false) ; \ 105 | else \ 106 | struct Local { \ 107 | Local(const AssertLog& assert_log) { \ 108 | if (!assert_log.evaluate_condition()) { \ 109 | DEBUG_BREAK; } \ 110 | } \ 111 | } local_assert =AssertLog(__FILE__, __FUNCTION__, __LINE__) 112 | 113 | #endif // NDEBUG 114 | 115 | 116 | // ERROR_LOG definition 117 | 118 | 119 | #ifdef NDEBUG 120 | 121 | #define ASSURE_LOG \ 122 | if (false) ; \ 123 | else \ 124 | struct Local { \ 125 | Local(const AssertLog& assert_log) { \ 126 | if (!assert_log.evaluate_condition()) { \ 127 | exit(1); } \ 128 | } \ 129 | } local_assert = AssertLog(__FILE__, __FUNCTION__, __LINE__) 130 | 131 | #else 132 | 133 | #define ASSURE_LOG ASSERT_LOG 134 | 135 | #endif // NDEBUG 136 | 137 | #endif // ASSERT_LOG_H__ 138 | -------------------------------------------------------------------------------- /code/segmentation_exporter/assert_log/depend.cmake: -------------------------------------------------------------------------------- 1 | set(CREATED_PACKAGES assert_log) 2 | -------------------------------------------------------------------------------- /code/segmentation_exporter/cmake/FindOpenCV.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find OpenCV library installation 2 | # See http://sourceforge.net/projects/opencvlibrary/ 3 | # 4 | # The follwoing variables are optionally searched for defaults 5 | # OpenCV_ROOT_DIR: Base directory of OpenCv tree to use. 6 | # OpenCV_FIND_REQUIRED_COMPONENTS : FIND_PACKAGE(OpenCV COMPONENTS ..) 7 | # compatible interface. typically CV CXCORE CVAUX HIGHGUI CVCAM .. etc. 8 | # 9 | # The following are set after configuration is done: 10 | # OpenCV_FOUND 11 | # OpenCV_INCLUDE_DIR 12 | # OpenCV_LIBRARIES 13 | # OpenCV_LINK_DIRECTORIES 14 | # 15 | # 2004/05 Jan Woetzel, Friso, Daniel Grest 16 | # 2006/01 complete rewrite by Jan Woetzel 17 | # 1006/09 2nd rewrite introducing ROOT_DIR and PATH_SUFFIXES 18 | # to handle multiple installed versions gracefully by Jan Woetzel 19 | # 20 | # tested with: 21 | # -OpenCV 0.97 (beta5a): MSVS 7.1, gcc 3.3, gcc 4.1 22 | # -OpenCV 0.99 (1.0rc1): MSVS 7.1 23 | # 24 | # www.mip.informatik.uni-kiel.de/~jw 25 | # 26 | # --------------------- 27 | # 28 | # $Id: FindOpenCV.cmake 8 2009-01-04 21:13:48Z adeguet1 $ 29 | # ERC-CISST version: 30 | # 31 | # - Removed deprecated code starting with cap. OPENCV 32 | # - Removed debugging code and messages 33 | # - Removed path and options specifics to previous authors setups 34 | # 35 | # This file should be removed when CMake will provide an equivalent 36 | 37 | 38 | # required cv components with header and library if COMPONENTS unspecified 39 | IF(NOT OpenCV_FIND_COMPONENTS) 40 | # default 41 | 42 | 43 | 44 | # 45 | # fix for OpenCV 2.4.6.1 on Mac OSX 46 | # 47 | #SET(OpenCV_FIND_REQUIRED_COMPONENTS CV CXCORE HIGHGUI) 48 | SET(OpenCV_FIND_REQUIRED_COMPONENTS CORE HIGHGUI) 49 | 50 | 51 | 52 | # IF(WIN32) 53 | # LIST(APPEND OpenCV_FIND_REQUIRED_COMPONENTS CVCAM ) # WIN32 only actually 54 | # ENDIF(WIN32) 55 | ENDIF(NOT OpenCV_FIND_COMPONENTS) 56 | 57 | 58 | # typical root dirs of installations, exactly one of them is used 59 | SET(OpenCV_POSSIBLE_ROOT_DIRS 60 | "${OpenCV_ROOT_DIR}" 61 | "$ENV{OpenCV_ROOT_DIR}" 62 | "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Intel(R) Open Source Computer Vision Library_is1;Inno Setup: App Path]" 63 | "$ENV{ProgramFiles}/OpenCV" 64 | "/usr/local" 65 | "/usr" 66 | "/opt/local" 67 | ) 68 | 69 | # 70 | # select exactly ONE OpenCV base directory/tree 71 | # to avoid mixing different version headers and libs 72 | # 73 | FIND_PATH(OpenCV_ROOT_DIR 74 | NAMES 75 | cv/include/cv.h # windows 76 | include/opencv/cv.h # linux /opt/net 77 | include/cv/cv.h 78 | include/cv.h 79 | PATHS ${OpenCV_POSSIBLE_ROOT_DIRS}) 80 | 81 | # header include dir suffixes appended to OpenCV_ROOT_DIR 82 | SET(OpenCV_INCDIR_SUFFIXES 83 | include 84 | include/cv 85 | include/opencv 86 | cv/include 87 | cxcore/include 88 | cvaux/include 89 | otherlibs/cvcam 90 | otherlibs/highgui 91 | ) 92 | 93 | # library linkdir suffixes appended to OpenCV_ROOT_DIR 94 | SET(OpenCV_LIBDIR_SUFFIXES 95 | lib 96 | OpenCV/lib 97 | ) 98 | 99 | # find incdir for each lib 100 | FIND_PATH(OpenCV_CV_INCLUDE_DIR 101 | NAMES cv.h 102 | PATHS ${OpenCV_ROOT_DIR} 103 | PATH_SUFFIXES ${OpenCV_INCDIR_SUFFIXES}) 104 | 105 | FIND_PATH(OpenCV_CXCORE_INCLUDE_DIR 106 | NAMES cxcore.h 107 | PATHS ${OpenCV_ROOT_DIR} 108 | PATH_SUFFIXES ${OpenCV_INCDIR_SUFFIXES}) 109 | FIND_PATH(OpenCV_CVAUX_INCLUDE_DIR 110 | NAMES cvaux.h 111 | PATHS ${OpenCV_ROOT_DIR} 112 | PATH_SUFFIXES ${OpenCV_INCDIR_SUFFIXES}) 113 | FIND_PATH(OpenCV_HIGHGUI_INCLUDE_DIR 114 | NAMES highgui.h 115 | PATHS ${OpenCV_ROOT_DIR} 116 | PATH_SUFFIXES ${OpenCV_INCDIR_SUFFIXES}) 117 | FIND_PATH(OpenCV_CVCAM_INCLUDE_DIR 118 | NAMES cvcam.h 119 | PATHS ${OpenCV_ROOT_DIR} 120 | PATH_SUFFIXES ${OpenCV_INCDIR_SUFFIXES}) 121 | 122 | 123 | 124 | # 125 | # fix for OpenCV 2.4.6.1 on Mac OSX 126 | # 127 | FIND_PATH(OpenCV_CORE_INCLUDE_DIR 128 | NAMES cxcore.h 129 | PATHS ${OpenCV_ROOT_DIR} 130 | PATH_SUFFIXES ${OpenCV_INCDIR_SUFFIXES}) 131 | 132 | 133 | 134 | # 135 | # find sbsolute path to all libraries 136 | # some are optionally, some may not exist on Linux 137 | # 138 | FIND_LIBRARY(OpenCV_CV_LIBRARY 139 | NAMES cv opencv 140 | PATHS ${OpenCV_ROOT_DIR} 141 | PATH_SUFFIXES ${OpenCV_LIBDIR_SUFFIXES}) 142 | FIND_LIBRARY(OpenCV_CVAUX_LIBRARY 143 | NAMES cvaux 144 | PATHS ${OpenCV_ROOT_DIR} PATH_SUFFIXES ${OpenCV_LIBDIR_SUFFIXES}) 145 | FIND_LIBRARY(OpenCV_CVCAM_LIBRARY 146 | NAMES cvcam 147 | PATHS ${OpenCV_ROOT_DIR} PATH_SUFFIXES ${OpenCV_LIBDIR_SUFFIXES}) 148 | FIND_LIBRARY(OpenCV_CVHAARTRAINING_LIBRARY 149 | NAMES cvhaartraining 150 | PATHS ${OpenCV_ROOT_DIR} PATH_SUFFIXES ${OpenCV_LIBDIR_SUFFIXES}) 151 | FIND_LIBRARY(OpenCV_CXCORE_LIBRARY 152 | NAMES cxcore 153 | PATHS ${OpenCV_ROOT_DIR} PATH_SUFFIXES ${OpenCV_LIBDIR_SUFFIXES}) 154 | FIND_LIBRARY(OpenCV_CXTS_LIBRARY 155 | NAMES cxts 156 | PATHS ${OpenCV_ROOT_DIR} PATH_SUFFIXES ${OpenCV_LIBDIR_SUFFIXES}) 157 | FIND_LIBRARY(OpenCV_HIGHGUI_LIBRARY 158 | NAMES highgui 159 | PATHS ${OpenCV_ROOT_DIR} PATH_SUFFIXES ${OpenCV_LIBDIR_SUFFIXES}) 160 | FIND_LIBRARY(OpenCV_TRS_LIBRARY 161 | NAMES trs 162 | PATHS ${OpenCV_ROOT_DIR} PATH_SUFFIXES ${OpenCV_LIBDIR_SUFFIXES}) 163 | 164 | 165 | 166 | FIND_LIBRARY(OpenCV_CORE_LIBRARY 167 | NAMES opencv_core 168 | PATHS ${OpenCV_ROOT_DIR} PATH_SUFFIXES ${OpenCV_LIBDIR_SUFFIXES}) 169 | 170 | FIND_LIBRARY(OpenCV_HIGHGUI_LIBRARY 171 | NAMES opencv_highgui 172 | PATHS ${OpenCV_ROOT_DIR} PATH_SUFFIXES ${OpenCV_LIBDIR_SUFFIXES}) 173 | 174 | 175 | 176 | # Logic selecting required libs and headers 177 | SET(OpenCV_FOUND ON) 178 | FOREACH(NAME ${OpenCV_FIND_REQUIRED_COMPONENTS}) 179 | # only good if header and library both found 180 | IF(OpenCV_${NAME}_INCLUDE_DIR AND OpenCV_${NAME}_LIBRARY) 181 | LIST(APPEND OpenCV_INCLUDE_DIRS "${OpenCV_${NAME}_INCLUDE_DIR}") 182 | LIST(APPEND OpenCV_LIBRARIES "${OpenCV_${NAME}_LIBRARY}") 183 | ELSE(OpenCV_${NAME}_INCLUDE_DIR AND OpenCV_${NAME}_LIBRARY) 184 | message("Could not find OpenCV_${NAME}_INCLUDE_DIR") 185 | SET(OpenCV_FOUND OFF) 186 | ENDIF(OpenCV_${NAME}_INCLUDE_DIR AND OpenCV_${NAME}_LIBRARY) 187 | ENDFOREACH(NAME) 188 | 189 | message("Include dir: ${OpenCV_FOUND}") 190 | 191 | # get the link directory for rpath to be used with LINK_DIRECTORIES: 192 | IF(OpenCV_CV_LIBRARY) 193 | GET_FILENAME_COMPONENT(OpenCV_LINK_DIRECTORIES ${OpenCV_CV_LIBRARY} PATH) 194 | ENDIF(OpenCV_CV_LIBRARY) 195 | 196 | MARK_AS_ADVANCED( 197 | OpenCV_ROOT_DIR 198 | OpenCV_INCLUDE_DIRS 199 | OpenCV_CV_INCLUDE_DIR 200 | OpenCV_CXCORE_INCLUDE_DIR 201 | OpenCV_CVAUX_INCLUDE_DIR 202 | OpenCV_CVCAM_INCLUDE_DIR 203 | OpenCV_HIGHGUI_INCLUDE_DIR 204 | OpenCV_LIBRARIES 205 | OpenCV_CV_LIBRARY 206 | OpenCV_CXCORE_LIBRARY 207 | OpenCV_CVAUX_LIBRARY 208 | OpenCV_CVCAM_LIBRARY 209 | OpenCV_CVHAARTRAINING_LIBRARY 210 | OpenCV_CXTS_LIBRARY 211 | OpenCV_HIGHGUI_LIBRARY 212 | OpenCV_TRS_LIBRARY 213 | ) 214 | 215 | 216 | # display help message 217 | IF(NOT OpenCV_FOUND) 218 | # make FIND_PACKAGE friendly 219 | IF(OpenCV_FIND_REQUIRED) 220 | MESSAGE(FATAL_ERROR 221 | "OpenCV required but some headers or libs not found. Please specify it's location with OpenCV_ROOT_DIR env. variable.") 222 | ELSE(OpenCV_FIND_REQUIRED) 223 | MESSAGE(STATUS 224 | "ERROR: OpenCV was not found.") 225 | ENDIF(OpenCV_FIND_REQUIRED) 226 | ELSE(NOT OpenCV_FOUND) 227 | MESSAGE(STATUS 228 | "OpenCV found at ${OpenCV_ROOT_DIR}") 229 | ENDIF(NOT OpenCV_FOUND) 230 | 231 | 232 | # 233 | # $Log: FindOpenCV.cmake,v $ 234 | # Revision 1.2 2008/11/03 16:40:34 vagvoba 235 | # cmake: Proper cvcam and highgui directories added to FindOpenCV.cmake 236 | # 237 | # Revision 1.1 2007/07/12 00:22:25 anton 238 | # cmake utilities: Added FindOpenCV.cmake based on example found all over the 239 | # web. Will have to be removed when CMake provides one. 240 | # 241 | # 242 | 243 | -------------------------------------------------------------------------------- /code/segmentation_exporter/cmake/FindProtoBuf.cmake: -------------------------------------------------------------------------------- 1 | # Try to find protocol buffers (protobuf) 2 | # 3 | # Use as FIND_PACKAGE(ProtocolBuffers) 4 | # 5 | # PROTOBUF_FOUND - system has the protocol buffers library 6 | # PROTOBUF_INCLUDE_DIR - the zip include directory 7 | # PROTOBUF_LIBRARY - Link this to use the zip library 8 | # PROTOBUF_PROTOC_EXECUTABLE - executable protobuf compiler 9 | # 10 | # And the following command 11 | # 12 | # WRAP_PROTO(VAR input1 input2 input3..) 13 | # 14 | # Which will run protoc on the input files and set VAR to the names of the created .cc files, 15 | # ready to be added to ADD_EXECUTABLE/ADD_LIBRARY. E.g, 16 | # 17 | # WRAP_PROTO(PROTO_SRC myproto.proto external.proto) 18 | # ADD_EXECUTABLE(server ${server_SRC} ${PROTO_SRC}) 19 | # 20 | # Author: Esben Mose Hansen <[EMAIL PROTECTED]>, (C) Ange Optimization ApS 2008 21 | # 22 | # Redistribution and use is allowed according to the terms of the BSD license. 23 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 24 | # 25 | # Modified by Matthias Grundmann. 26 | 27 | IF (PROTOBUF_LIBRARY AND PROTOBUF_INCLUDE_DIR AND PROTOBUF_PROTOC_EXECUTABLE) 28 | # in cache already 29 | SET(PROTOBUF_FOUND TRUE) 30 | ELSE (PROTOBUF_LIBRARY AND PROTOBUF_INCLUDE_DIR AND PROTOBUF_PROTOC_EXECUTABLE) 31 | 32 | FIND_PATH(PROTOBUF_INCLUDE_DIR google/protobuf/stubs/common.h 33 | /usr/include/ 34 | /opt/local/include/ 35 | $ENV{PROTOBUF_DIR} 36 | ) 37 | 38 | FIND_LIBRARY(PROTOBUF_LIBRARY NAMES protobuf libprotobuf 39 | PATHS 40 | ${GNUWIN32_DIR}/lib 41 | $ENV{PROTOBUF_DIR} 42 | ) 43 | 44 | message("PROTO LIB: ${PROTOBUF_LIBRARY}") 45 | 46 | FIND_PROGRAM(PROTOBUF_PROTOC_EXECUTABLE protoc) 47 | 48 | INCLUDE(FindPackageHandleStandardArgs) 49 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(protobuf DEFAULT_MSG PROTOBUF_INCLUDE_DIR 50 | PROTOBUF_LIBRARY PROTOBUF_PROTOC_EXECUTABLE) 51 | 52 | # ensure that they are cached 53 | SET(PROTOBUF_INCLUDE_DIR ${PROTOBUF_INCLUDE_DIR} CACHE INTERNAL "The protocol 54 | buffers include path") 55 | SET(PROTOBUF_LIBRARY ${PROTOBUF_LIBRARY} CACHE INTERNAL "The libraries needed 56 | to use protocol buffers library") 57 | SET(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_PROTOC_EXECUTABLE} CACHE INTERNAL 58 | "The protocol buffers compiler") 59 | 60 | ENDIF (PROTOBUF_LIBRARY AND PROTOBUF_INCLUDE_DIR AND PROTOBUF_PROTOC_EXECUTABLE) 61 | 62 | IF (PROTOBUF_FOUND) 63 | # Define the WRAP_PROTO function 64 | FUNCTION(WRAP_PROTO VAR) 65 | IF (NOT ARGN) 66 | MESSAGE(SEND_ERROR "Error: WRAP PROTO called without any proto files") 67 | RETURN() 68 | ENDIF(NOT ARGN) 69 | 70 | SET(INCL) 71 | SET(${VAR}) 72 | FOREACH(FIL ${ARGN}) 73 | GET_FILENAME_COMPONENT(ABS_FIL ${FIL} ABSOLUTE) 74 | GET_FILENAME_COMPONENT(FIL_WE ${FIL} NAME_WE) 75 | LIST(APPEND ${VAR} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc") 76 | LIST(APPEND INCL "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h") 77 | 78 | ADD_CUSTOM_COMMAND( 79 | OUTPUT ${${VAR}} ${INCL} 80 | COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} 81 | ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR} ${ABS_FIL} 82 | DEPENDS ${ABS_FIL} 83 | COMMENT "Running protocol buffer compiler on ${FIL}" 84 | VERBATIM ) 85 | 86 | SET_SOURCE_FILES_PROPERTIES(${${VAR}} ${INCL} PROPERTIES GENERATED TRUE) 87 | ENDFOREACH(FIL) 88 | 89 | SET(${VAR} ${${VAR}} PARENT_SCOPE) 90 | 91 | # Add if somebody imports the pb.h. 92 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) 93 | ENDFUNCTION(WRAP_PROTO) 94 | ENDIF(PROTOBUF_FOUND) 95 | 96 | # display help message 97 | IF(NOT PROTOBUF_FOUND) 98 | # make FIND_PACKAGE friendly 99 | IF(PROTOBUF_FIND_REQUIRED) 100 | MESSAGE(FATAL_ERROR 101 | "ProtoBuf required but some headers or libs not found. Please specify it's location with PROTOBUF_DIR env. variable.") 102 | ELSE(PROTOBUF_FIND_REQUIRED) 103 | MESSAGE(STATUS 104 | "ERROR: ProtoBuf was not found. Please specify it's location with PROTOBUF_DIR env. variable.") 105 | ENDIF(PROTOBUF_FIND_REQUIRED) 106 | ENDIF(NOT PROTOBUF_FOUND) 107 | -------------------------------------------------------------------------------- /code/segmentation_exporter/cmake/LibFindMacros.cmake: -------------------------------------------------------------------------------- 1 | # Works the same as find_package, but forwards the "REQUIRED" and "QUIET" arguments 2 | # used for the current package. For this to work, the first parameter must be the 3 | # prefix of the current package, then the prefix of the new package etc, which are 4 | # passed to find_package. 5 | macro (libfind_package PREFIX) 6 | set (LIBFIND_PACKAGE_ARGS ${ARGN}) 7 | if (${PREFIX}_FIND_QUIETLY) 8 | set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET) 9 | endif (${PREFIX}_FIND_QUIETLY) 10 | if (${PREFIX}_FIND_REQUIRED) 11 | set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED) 12 | endif (${PREFIX}_FIND_REQUIRED) 13 | find_package(${LIBFIND_PACKAGE_ARGS}) 14 | endmacro (libfind_package) 15 | 16 | # CMake developers made the UsePkgConfig system deprecated in the same release (2.6) 17 | # where they added pkg_check_modules. Consequently I need to support both in my scripts 18 | # to avoid those deprecated warnings. Here's a helper that does just that. 19 | # Works identically to pkg_check_modules, except that no checks are needed prior to use. 20 | macro (libfind_pkg_check_modules PREFIX PKGNAME) 21 | if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) 22 | include(UsePkgConfig) 23 | pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS) 24 | else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) 25 | find_package(PkgConfig) 26 | if (PKG_CONFIG_FOUND) 27 | pkg_check_modules(${PREFIX} ${PKGNAME}) 28 | endif (PKG_CONFIG_FOUND) 29 | endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) 30 | endmacro (libfind_pkg_check_modules) 31 | 32 | # Do the final processing once the paths have been detected. 33 | # If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain 34 | # all the variables, each of which contain one include directory. 35 | # Ditto for ${PREFIX}_PROCESS_LIBS and library files. 36 | # Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES. 37 | # Also handles errors in case library detection was required, etc. 38 | macro (libfind_process PREFIX) 39 | # Skip processing if already processed during this run 40 | if (NOT ${PREFIX}_FOUND) 41 | # Start with the assumption that the library was found 42 | set (${PREFIX}_FOUND TRUE) 43 | 44 | # Process all includes and set _FOUND to false if any are missing 45 | foreach (i ${${PREFIX}_PROCESS_INCLUDES}) 46 | if (${i}) 47 | set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}}) 48 | mark_as_advanced(${i}) 49 | else (${i}) 50 | set (${PREFIX}_FOUND FALSE) 51 | endif (${i}) 52 | endforeach (i) 53 | 54 | # Process all libraries and set _FOUND to false if any are missing 55 | foreach (i ${${PREFIX}_PROCESS_LIBS}) 56 | if (${i}) 57 | set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}}) 58 | mark_as_advanced(${i}) 59 | else (${i}) 60 | set (${PREFIX}_FOUND FALSE) 61 | endif (${i}) 62 | endforeach (i) 63 | 64 | # Print message and/or exit on fatal error 65 | if (${PREFIX}_FOUND) 66 | if (NOT ${PREFIX}_FIND_QUIETLY) 67 | message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}") 68 | endif (NOT ${PREFIX}_FIND_QUIETLY) 69 | else (${PREFIX}_FOUND) 70 | if (${PREFIX}_FIND_REQUIRED) 71 | foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS}) 72 | message("${i}=${${i}}") 73 | endforeach (i) 74 | message (FATAL_ERROR "Required library ${PREFIX} NOT FOUND.\nInstall the library (dev version) and try again. If the library is already installed, use ccmake to set the missing variables manually.") 75 | endif (${PREFIX}_FIND_REQUIRED) 76 | endif (${PREFIX}_FOUND) 77 | endif (NOT ${PREFIX}_FOUND) 78 | endmacro (libfind_process) 79 | 80 | macro(libfind_library PREFIX basename) 81 | set(TMP "") 82 | if(MSVC80) 83 | set(TMP -vc80) 84 | endif(MSVC80) 85 | if(MSVC90) 86 | set(TMP -vc90) 87 | endif(MSVC90) 88 | set(${PREFIX}_LIBNAMES ${basename}${TMP}) 89 | if(${ARGC} GREATER 2) 90 | set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2}) 91 | string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES}) 92 | set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP}) 93 | endif(${ARGC} GREATER 2) 94 | find_library(${PREFIX}_LIBRARY 95 | NAMES ${${PREFIX}_LIBNAMES} 96 | PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS} 97 | ) 98 | endmacro(libfind_library) 99 | 100 | -------------------------------------------------------------------------------- /code/segmentation_exporter/cmake/common.cmake: -------------------------------------------------------------------------------- 1 | # BUILD system for /grundmann2 source tree. 2 | # Copyright 2009 Matthias Grundmann. All rights reserved. 3 | 4 | # Common flags for all projects 5 | if (UNIX) 6 | endif (UNIX) 7 | 8 | if (APPLE) 9 | set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64") 10 | set(CMAKE_CXX_FLAGS "-fasm-blocks") 11 | endif (APPLE) 12 | 13 | # Checks for each cpp file if header exists and adds it to HEADERS 14 | function(headers_from_sources_cpp HEADERS SOURCES) 15 | set(HEADERS) 16 | foreach(SOURCE_FILE ${SOURCES}) 17 | string(REPLACE ".cpp" ".h" HEADER_FILE ${SOURCE_FILE}) 18 | if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${HEADER_FILE}") 19 | list(APPEND HEADERS ${HEADER_FILE}) 20 | endif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${HEADER_FILE}") 21 | endforeach(SOURCE_FILE) 22 | 23 | set(HEADERS "${HEADERS}" PARENT_SCOPE) 24 | 25 | endfunction(headers_from_sources_cpp) 26 | 27 | # Reads the depend.cmake file in the current source folder and processes 28 | # dependent libraries and packages in the source tree. 29 | function(apply_dependencies TARGET) 30 | 31 | # Use property APPLY_DEPENDENCIES_CALLED to use add_subdirectory 32 | # only on the main CMakeLists.txt 33 | # This is set by the first call of apply_dependencies. 34 | get_property(CALL_PROPERTY_DEFINED 35 | GLOBAL 36 | PROPERTY APPLY_DEPENDENCIES_CALLED 37 | SET) 38 | 39 | if (${CALL_PROPERTY_DEFINED}) 40 | # Only add include and dependency 41 | if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/depend.cmake") 42 | set(DEPENDENT_PACKAGES) 43 | include("${CMAKE_CURRENT_SOURCE_DIR}/depend.cmake") 44 | if(DEPENDENT_PACKAGES) 45 | foreach(PACKAGE "${DEPENDENT_PACKAGES}") 46 | # Add package directory to include path. 47 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../${PACKAGE}) 48 | # Add package binary path to include path. 49 | # Temporary files, like protobuffer or qt's moc are placed here. 50 | include_directories("${CMAKE_BINARY_DIR}/${PACKAGE}") 51 | add_dependencies(${TARGET} ${PACKAGE}) 52 | endforeach(PACKAGE) 53 | endif(DEPENDENT_PACKAGES) 54 | 55 | include_directories(${DEPENDENT_INCLUDES}) 56 | 57 | endif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/depend.cmake") 58 | 59 | else (${CALL_PROPERTY_DEFINED}) 60 | # First call of apply_dependencies. 61 | set_property(GLOBAL PROPERTY APPLY_DEPENDENCIES_CALLED TRUE) 62 | 63 | # Get list of dependencies. 64 | if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/depend.cmake") 65 | set(DEPENDENT_PACKAGES) 66 | include("${CMAKE_CURRENT_SOURCE_DIR}/depend.cmake") 67 | 68 | # Each package is unique but can have duplicate dependent libraries. 69 | set(MY_DEPENDENT_LIBRARIES "${DEPENDENT_LIBRARIES}") 70 | set(MY_DEPENDENT_LINK_DIRECTORIES "${DEPENDENT_LINK_DIRECTORIES}") 71 | set(MY_DEPENDENT_INCLUDES "${DEPENDENT_INCLUDES}" ) 72 | 73 | if(DEPENDENT_PACKAGES) 74 | # Recursively get all dependent packages. Depth first. 75 | set(PACKAGES_TO_PROCESS "${DEPENDENT_PACKAGES}") 76 | recursive_dependency_retrieve(PACKAGES_TO_PROCESS "${PACKAGES_TO_PROCESS}") 77 | # Remove duplicates, keep first one. Does not alter the depth first property. 78 | list(REMOVE_DUPLICATES PACKAGES_TO_PROCESS) 79 | message("Adding the following dependent packages: ${PACKAGES_TO_PROCESS}") 80 | 81 | # The dependent packages binary dirs and created libraries. 82 | # We need to reverse the order before adding them. 83 | set(PACKAGE_LINK_DIRS) 84 | set(PACKAGE_LINK_LIBS) 85 | 86 | foreach(PACKAGE ${PACKAGES_TO_PROCESS}) 87 | message("Adding dependency ../${PACKAGE} ${PACKAGE}") 88 | add_subdirectory(../${PACKAGE} ${PACKAGE}) 89 | include_directories(../${PACKAGE}) 90 | # For temporary generated files like moc or protoc. 91 | include_directories("${CMAKE_BINARY_DIR}/${PACKAGE}") 92 | add_dependencies(${TARGET} ${PACKAGE}) 93 | 94 | # Add linker information 95 | set(DEPENDENT_PACKAGES) 96 | set(DEPENDENT_INCLUDES) 97 | set(DEPENDENT_LIBRARIES) 98 | set(DEPENDENT_LINK_DIRECTORIES) 99 | set(CREATED_PACKAGES) 100 | 101 | include("${CMAKE_CURRENT_SOURCE_DIR}/../${PACKAGE}/depend.cmake") 102 | 103 | if (CREATED_PACKAGES) 104 | list(APPEND PACKAGE_LINK_DIRS ${PACKAGE}) 105 | list(APPEND PACKAGE_LINK_LIBS ${CREATED_PACKAGES}) 106 | endif(CREATED_PACKAGES) 107 | 108 | if (DEPENDENT_LIBRARIES) 109 | list(APPEND MY_DEPENDENT_LIBRARIES "${DEPENDENT_LIBRARIES}") 110 | list(APPEND MY_DEPENDENT_LINK_DIRECTORIES "${DEPENDENT_LINK_DIRECTORIES}") 111 | list(APPEND MY_DEPENDENT_INCLUDES "${DEPENDENT_INCLUDES}") 112 | endif(DEPENDENT_LIBRARIES) 113 | endforeach(PACKAGE) 114 | 115 | # Add package libraries and binary directories. 116 | if (PACKAGE_LINK_DIRS) 117 | # Reverse to adhere linking order. 118 | list(REVERSE PACKAGE_LINK_DIRS) 119 | list(REVERSE PACKAGE_LINK_LIBS) 120 | 121 | foreach(LINK_DIR ${PACKAGE_LINK_DIRS}) 122 | link_directories(${LINK_DIR}) 123 | endforeach(LINK_DIR) 124 | 125 | foreach(LINK_LIB ${PACKAGE_LINK_LIBS}) 126 | target_link_libraries(${TARGET} ${LINK_LIB}) 127 | endforeach(LINK_LIB) 128 | 129 | endif(PACKAGE_LINK_DIRS) 130 | endif(DEPENDENT_PACKAGES) 131 | 132 | if (MY_DEPENDENT_LINK_DIRECTORIES) 133 | list(REMOVE_DUPLICATES MY_DEPENDENT_LINK_DIRECTORIES) 134 | link_directories(${MY_DEPENDENT_LINK_DIRECTORIES}) 135 | endif(MY_DEPENDENT_LINK_DIRECTORIES) 136 | 137 | 138 | if (MY_DEPENDENT_LIBRARIES) 139 | list(REMOVE_DUPLICATES MY_DEPENDENT_LIBRARIES) 140 | target_link_libraries(${TARGET} ${MY_DEPENDENT_LIBRARIES}) 141 | endif(MY_DEPENDENT_LIBRARIES) 142 | 143 | if (MY_DEPENDENT_INCLUDES) 144 | list(REMOVE_DUPLICATES MY_DEPENDENT_INCLUDES) 145 | include_directories(${MY_DEPENDENT_INCLUDES}) 146 | endif(MY_DEPENDENT_INCLUDES) 147 | 148 | endif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/depend.cmake") 149 | 150 | endif(${CALL_PROPERTY_DEFINED}) 151 | endfunction(apply_dependencies) 152 | 153 | # Finds recursively dependencies of packages in the source tree. 154 | # Implementation function called by apply_dependencies. 155 | function(recursive_dependency_retrieve ADD_LIST PACKAGES) 156 | set(LOCAL_LIST ${PACKAGES}) 157 | foreach(item ${PACKAGES}) 158 | if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../${item}/depend.cmake") 159 | SET(DEPENDENT_PACKAGES) 160 | include ( "${CMAKE_CURRENT_SOURCE_DIR}/../${item}/depend.cmake") 161 | if(DEPENDENT_PACKAGES) 162 | SET(MY_PACKAGES "${DEPENDENT_PACKAGES}") 163 | SET(MY_LIST) 164 | recursive_dependency_retrieve(MY_LIST "${MY_PACKAGES}") 165 | # Build order is important. This is like depth first search. 166 | list(INSERT LOCAL_LIST 0 "${MY_LIST}") 167 | endif(DEPENDENT_PACKAGES) 168 | endif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../${item}/depend.cmake") 169 | endforeach(item) 170 | set(${ADD_LIST} "${LOCAL_LIST}" PARENT_SCOPE) 171 | endfunction(recursive_dependency_retrieve) 172 | -------------------------------------------------------------------------------- /code/segmentation_exporter/segment_util/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | project(segment_util) 4 | set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") 5 | include(${CMAKE_MODULE_PATH}/common.cmake) 6 | include("${CMAKE_SOURCE_DIR}/depend.cmake") 7 | 8 | set(SOURCES segmentation_io.cpp 9 | segmentation_util.cpp) 10 | 11 | headers_from_sources_cpp(HEADERS "${SOURCES}") 12 | set(SOURCES "${SOURCES}" "${HEADERS}") 13 | 14 | # Custom build steps. 15 | WRAP_PROTO(PROTO_SOURCES segmentation.proto) 16 | 17 | add_library(segment_util ${SOURCES} ${PROTO_SOURCES}) 18 | 19 | include_directories(${PROTOBUF_INCLUDE_DIR}) 20 | 21 | apply_dependencies(segment_util) 22 | -------------------------------------------------------------------------------- /code/segmentation_exporter/segment_util/depend.cmake: -------------------------------------------------------------------------------- 1 | find_package(ProtoBuf REQUIRED) 2 | 3 | set(DEPENDENT_PACKAGES assert_log) 4 | 5 | set(DEPENDENT_INCLUDES ${PROTOBUF_INCLUDE_DIR}) 6 | 7 | set(DEPENDENT_LIBRARIES ${PROTOBUF_LIBRARY}) 8 | 9 | set(CREATED_PACKAGES segment_util) 10 | -------------------------------------------------------------------------------- /code/segmentation_exporter/segment_util/segmentation.proto: -------------------------------------------------------------------------------- 1 | package Segment; 2 | 3 | // Each spatio-temporal region is represented as a set of 2D frame-slices, 4 | // associated by a unique id that is given to each region. Therefore, there 5 | // exists one SegmentationDesc for each frame in the original video. 6 | // 2D Regions are saved similar to polygon rasterization or RLE, as set of 7 | // scanlines and the corresponding scanline intervals. 8 | // As the hierarchy of regions (super-regions, i.e. regions composed of regions) 9 | // is computed for the whole video volume, it would be redundant to store it at 10 | // every frame, it is therefore only saved for the very first frame, for all 11 | // subsequent SegmentationDesc::hierarchy is empty. 12 | 13 | message SegmentationDesc { 14 | message Region { 15 | message Scanline { 16 | message Interval { 17 | required fixed32 left_x = 1; 18 | required fixed32 right_x = 2; 19 | } 20 | 21 | // In case of holes, this can be empty! 22 | repeated Interval interval = 1; 23 | } 24 | 25 | required fixed32 id = 1; 26 | required fixed32 size = 2; 27 | repeated fixed32 neighbor_id = 3; 28 | 29 | required fixed32 top_y = 4; 30 | optional fixed32 parent_id = 5; 31 | 32 | repeated Scanline scanline = 6; 33 | } 34 | 35 | message CompoundRegion { 36 | required fixed32 id = 1; 37 | required fixed32 size = 2; 38 | repeated fixed32 neighbor_id = 3; 39 | 40 | optional fixed32 parent_id = 4; 41 | // List of child ids - references to previous level 42 | repeated fixed32 child_id = 5; 43 | } 44 | 45 | message Hierarchy { 46 | required fixed32 level = 1; 47 | required fixed32 max_id = 2; 48 | repeated CompoundRegion region = 3; 49 | } 50 | 51 | required fixed32 max_id = 1; 52 | repeated Region region = 2; 53 | 54 | // Hierarchy does not need to be present in case of flat segmentation. 55 | repeated Hierarchy hierarchy = 3; 56 | 57 | // General video information. 58 | optional int32 frame_width = 4 [default = 0]; 59 | optional int32 frame_height = 5 [default = 0]; 60 | } 61 | -------------------------------------------------------------------------------- /code/segmentation_exporter/segment_util/segmentation_io.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * segmentation_io.cpp 3 | * segmentat_util 4 | * 5 | * Created by Matthias Grundmann on 6/30/10. 6 | * Copyright 2010 Matthias Grundmann. All rights reserved. 7 | * 8 | */ 9 | 10 | #include "segmentation_io.h" 11 | 12 | #include 13 | 14 | namespace Segment { 15 | 16 | bool SegmentationWriter::OpenAndPrepareFileHeader() { 17 | // Open file to write 18 | ofs_.open(filename_.c_str(), 19 | std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); 20 | 21 | if (!ofs_) { 22 | std::cerr << "SegmentationWriter::PrepareFileHeader: " 23 | << "Could not open " << filename_ << " to write!\n"; 24 | return false; 25 | } 26 | 27 | // Write dummy header. To be filled on post process. 28 | int num_frames = 0; 29 | int64_t header_offset = 0; 30 | 31 | ofs_.write(reinterpret_cast(&num_frames), sizeof(num_frames)); 32 | ofs_.write(reinterpret_cast(&header_offset), sizeof(header_offset)); 33 | 34 | return true; 35 | } 36 | 37 | void SegmentationWriter::WriteOffsetsAndClose() { 38 | // Header information. 39 | int num_frames = file_offsets_.size(); 40 | int64_t header_offset = ofs_.tellp(); 41 | 42 | // Write file offsets to end. 43 | for (int i = 0; i < file_offsets_.size(); ++i) { 44 | ofs_.write(reinterpret_cast(&file_offsets_[i]), sizeof(file_offsets_[i])); 45 | ofs_.write(reinterpret_cast(&time_stamps_[i]), sizeof(time_stamps_[i])); 46 | } 47 | 48 | // Write header. 49 | ofs_.seekp(0); 50 | ofs_.write(reinterpret_cast(&num_frames), sizeof(num_frames)); 51 | ofs_.write(reinterpret_cast(&header_offset), sizeof(header_offset)); 52 | 53 | ofs_.close(); 54 | } 55 | 56 | void SegmentationWriter::FlushAndReopen(const string& filename) { 57 | WriteOffsetsAndClose(); 58 | filename_ = filename; 59 | file_offsets_.clear(); 60 | time_stamps_.clear(); 61 | OpenAndPrepareFileHeader(); 62 | } 63 | 64 | void SegmentationWriter::WriteSegmentation(const uchar* data, int sz, int64_t pts) { 65 | file_offsets_.push_back(ofs_.tellp()); 66 | time_stamps_.push_back(pts); 67 | 68 | ofs_.write(reinterpret_cast(&sz), sizeof(sz)); 69 | ofs_.write(reinterpret_cast(data), sz); 70 | } 71 | 72 | bool SegmentationReader::OpenFileAndReadHeader() { 73 | // Open file. 74 | ifs_.open(filename_.c_str(), std::ios_base::in | std::ios_base::binary); 75 | 76 | if (!ifs_) { 77 | std::cerr << "SegmentationReader::OpenFileAndReadHeader: " 78 | << "Could not open segmentation file " << filename_ << "\n"; 79 | return false; 80 | } 81 | 82 | // Read offset for each segmentation frame from header. 83 | int num_seg_frames; 84 | int64_t seg_header_offset; 85 | 86 | ifs_.read(reinterpret_cast(&num_seg_frames), sizeof(num_seg_frames)); 87 | ifs_.read(reinterpret_cast(&seg_header_offset), sizeof(seg_header_offset)); 88 | 89 | int64_t start_pos = ifs_.tellg(); 90 | ifs_.seekg(seg_header_offset); 91 | file_offsets_ = vector(num_seg_frames); 92 | time_stamps_ = vector(num_seg_frames); 93 | 94 | for (int i = 0; i < num_seg_frames; ++i) { 95 | int64_t pos; 96 | int64_t time_stamp; 97 | ifs_.read(reinterpret_cast(&pos), sizeof(pos)); 98 | ifs_.read(reinterpret_cast(&time_stamp), sizeof(time_stamp)); 99 | file_offsets_[i] = pos; 100 | time_stamps_[i] = time_stamp; 101 | } 102 | 103 | ifs_.seekg(start_pos); 104 | return true; 105 | } 106 | 107 | void SegmentationReader::SeekToFrame(int frame) { 108 | ifs_.seekg(file_offsets_[frame]); 109 | } 110 | 111 | int SegmentationReader::ReadFrameSize() { 112 | ifs_.read(reinterpret_cast(&frame_sz_), sizeof(frame_sz_)); 113 | return frame_sz_; 114 | } 115 | 116 | void SegmentationReader::ReadFrame(uchar* data) { 117 | ifs_.read(reinterpret_cast(data), frame_sz_); 118 | } 119 | 120 | } // namespace Segment. -------------------------------------------------------------------------------- /code/segmentation_exporter/segment_util/segmentation_io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * segmentation_io.h 3 | * segmentat_util 4 | * 5 | * Created by Matthias Grundmann on 6/30/10. 6 | * Copyright 2010 Matthias Grundmann. All rights reserved. 7 | * 8 | */ 9 | 10 | // Segmentation Reader and Writer to be used with segmentation.pb files. 11 | // Moved from segmentation_unit.h for external use. 12 | 13 | // The binary file format we use has the following form, and contains a header 14 | // at the end of the file to support random seeking. 15 | // Format: 16 | // 17 | // Number of frames : sizeof(int32) 18 | // Offset to header at end of file : sizeof(int64) 19 | // For every frame 20 | // Size of protobuffer in bytes : sizeof(int32) 21 | // Protobuffer serialized to binary format : from above member 22 | // Header, for every frame: 23 | // FileOffset in file : sizeof(int64) 24 | // TimeStamp of frame in pts : sizeof(int64) 25 | 26 | #ifndef SEGMENTATION_IO_H 27 | #define SEGMENTATION_IO_H 28 | 29 | #include 30 | #include 31 | #ifdef __linux 32 | #include 33 | #endif 34 | 35 | #include 36 | 37 | #ifdef _WIN32 38 | typedef __int64 int64_t; 39 | #endif 40 | 41 | namespace Segment { 42 | 43 | typedef unsigned char uchar; 44 | using std::string; 45 | using std::vector; 46 | 47 | class SegmentationWriter { 48 | public: 49 | SegmentationWriter(const string& filename) : filename_(filename) {} 50 | 51 | bool OpenAndPrepareFileHeader(); 52 | void WriteOffsetsAndClose(); 53 | 54 | void FlushAndReopen(const string& filename); 55 | 56 | void WriteSegmentation(const uchar* data, int sz, int64_t pts = 0); 57 | 58 | private: 59 | string filename_; 60 | std::ofstream ofs_; 61 | 62 | vector file_offsets_; 63 | vector time_stamps_; 64 | }; 65 | 66 | class SegmentationReader { 67 | public: 68 | SegmentationReader(const string& filename) : filename_(filename) {} 69 | 70 | bool OpenFileAndReadHeader(); 71 | 72 | // For each frame, first call ReadFrameSize 73 | // and subsequently ReadFrame. 74 | int ReadFrameSize(); 75 | void ReadFrame(uchar* data); 76 | 77 | const vector& TimeStamps() { return time_stamps_; } 78 | void SeekToFrame(int frame); 79 | int FrameNumber() const { return file_offsets_.size(); } 80 | void CloseFile() { ifs_.close(); } 81 | 82 | private: 83 | vector file_offsets_; 84 | vector time_stamps_; 85 | 86 | int frame_sz_; 87 | 88 | string filename_; 89 | std::ifstream ifs_; 90 | }; 91 | 92 | } // namespace Segment. 93 | 94 | #endif -------------------------------------------------------------------------------- /code/segmentation_exporter/segment_util/segmentation_util.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * segmentation_util.cpp 3 | * seamcarving 4 | * 5 | * Created by Matthias Grundmann on 6/15/09. 6 | * Copyright 2009 Matthias Grundmann. All rights reserved. 7 | * 8 | */ 9 | 10 | #include "segmentation_util.h" 11 | #include "assert_log.h" 12 | 13 | #include 14 | #include 15 | using google::protobuf::RepeatedPtrField; 16 | 17 | typedef unsigned char uchar; 18 | 19 | #ifdef _WIN32 20 | #undef min 21 | #undef max 22 | #endif 23 | 24 | // Moved from imagefilter here to remove library dependency. 25 | namespace { 26 | template 27 | T* PtrOffset(T* t, int offset) { 28 | return reinterpret_cast(reinterpret_cast(t) + offset); 29 | } 30 | 31 | template 32 | const T* PtrOffset(const T* t, int offset) { 33 | return reinterpret_cast(reinterpret_cast(t) + offset); 34 | } 35 | 36 | int ColorDiff_L1(const char* first, const char* second) { 37 | return abs((int)first[0] - (int)second[0]) + 38 | abs((int)first[1] - (int)second[1]) + 39 | abs((int)first[2] - (int)second[2]); 40 | } 41 | 42 | } 43 | 44 | namespace Segment { 45 | 46 | typedef SegmentationDesc::Region SegRegion; 47 | typedef SegmentationDesc::Region::Scanline Scanline; 48 | typedef SegmentationDesc::Region::Scanline::Interval ScanlineInterval; 49 | 50 | void SegmentationDescToIdImage(int* img, 51 | int width_step, 52 | int width, 53 | int height, 54 | int level, 55 | const SegmentationDesc& seg, 56 | const SegmentationDesc* seg_hier) { 57 | 58 | if (level > 0 && seg.hierarchy_size() != 0) { 59 | // Is a hierarchy present at the current frame? 60 | seg_hier = &seg; 61 | } 62 | 63 | if (level) 64 | level = std::min(level, seg_hier->hierarchy_size()); 65 | 66 | ASSURE_LOG(level == 0 || seg_hier) << "Hierarchy requested but not found."; 67 | ASSURE_LOG(level == 0 || level <= seg_hier->hierarchy_size()) << "Requested hierarchy exceeds" 68 | << " levels supplied in seg or seg_hier."; 69 | 70 | // Fill each region with it's id. 71 | const RepeatedPtrField& regions = seg.region(); 72 | for (RepeatedPtrField::const_iterator r = regions.begin(); 73 | r != regions.end(); 74 | ++r) { 75 | 76 | 77 | // Get id. 78 | int region_id; 79 | if (level == 0) 80 | region_id = r->id(); 81 | else { 82 | // Traverse to parent region. 83 | int parent_id = r->parent_id(); 84 | 85 | for (int l = 0; l < level - 1; ++l) { 86 | ASSERT_LOG(seg_hier->hierarchy(l).region_size() >= parent_id); 87 | parent_id = seg_hier->hierarchy(l).region(parent_id).parent_id(); 88 | } 89 | 90 | region_id = parent_id; 91 | } 92 | 93 | const RepeatedPtrField& scanlines = r->scanline(); 94 | int* dst_ptr = PtrOffset(img, r->top_y() * width_step); 95 | 96 | for(RepeatedPtrField::const_iterator s = scanlines.begin(); 97 | s != scanlines.end(); 98 | ++s) { 99 | for (int i = 0, sz = s->interval_size(); i < sz; ++i) { 100 | const ScanlineInterval& inter = s->interval(i); 101 | int* out_ptr = dst_ptr + inter.left_x(); 102 | for (int j = 0, len = inter.right_x() - inter.left_x() + 1; j < len; ++j, ++out_ptr) { 103 | *out_ptr = region_id; 104 | } 105 | } 106 | dst_ptr = PtrOffset(dst_ptr, width_step); 107 | } 108 | } 109 | } 110 | 111 | 112 | void RenderRegionsRandomColor(char* img, 113 | int width_step, 114 | int width, 115 | int height, 116 | int level, 117 | bool highlight_boundary, 118 | const SegmentationDesc& seg, 119 | const SegmentationDesc* seg_hier) { 120 | // Clear image. 121 | memset(img, 0, width_step * height); 122 | 123 | if (level > 0 && seg.hierarchy_size() != 0) { 124 | // Is a hierarchy present at the current frame? 125 | seg_hier = &seg; 126 | } 127 | 128 | if (level) 129 | level = std::min(level, seg_hier->hierarchy_size()); 130 | 131 | ASSURE_LOG(level == 0 || seg_hier) << "Hierarchy requested but not found."; 132 | 133 | // Fill each region. 134 | const RepeatedPtrField& regions = seg.region(); 135 | for(RepeatedPtrField::const_iterator r = regions.begin(); 136 | r != regions.end(); 137 | ++r) { 138 | // Get color. 139 | uchar color[3]; 140 | 141 | int region_id; 142 | 143 | if (level == 0) 144 | region_id = r->id(); 145 | else { 146 | // Traverse to parent region. 147 | int parent_id = r->parent_id(); 148 | 149 | for (int l = 1; l < level; ++l) { 150 | assert(seg_hier->hierarchy(l-1).region_size() > parent_id); 151 | parent_id = seg_hier->hierarchy(l-1).region(parent_id).parent_id(); 152 | } 153 | 154 | region_id = parent_id; 155 | } 156 | 157 | // Use region id as seed. 158 | srand(region_id); 159 | color[0] = (uchar) (rand() % 255); 160 | color[1] = (uchar) (rand() % 255); 161 | color[2] = (uchar) (rand() % 255); 162 | 163 | const RepeatedPtrField& scanlines = r->scanline(); 164 | char* dst_ptr =img + width_step * r->top_y(); 165 | 166 | for(RepeatedPtrField::const_iterator s = scanlines.begin(); 167 | s != scanlines.end(); 168 | ++s) { 169 | for (int i = 0, sz = s->interval_size(); i < sz; ++i) { 170 | const ScanlineInterval& inter = s->interval(i); 171 | char* out_ptr = dst_ptr + inter.left_x() * 3; 172 | for (int j = 0, len = inter.right_x() - inter.left_x() + 1; 173 | j < len; 174 | ++j, out_ptr += 3) { 175 | out_ptr[0] = color[0]; 176 | out_ptr[1] = color[1]; 177 | out_ptr[2] = color[2]; 178 | } 179 | } 180 | dst_ptr += width_step; 181 | } 182 | } 183 | 184 | // Edge highlight post-process. 185 | if (highlight_boundary) { 186 | for (int i = 0; i < height - 1; ++i) { 187 | char* row_ptr = img + i * width_step; 188 | for (int j = 0; j < width - 1; ++j, row_ptr += 3) { 189 | if (ColorDiff_L1(row_ptr, row_ptr + 3) != 0 || 190 | ColorDiff_L1(row_ptr, row_ptr + width_step) != 0) 191 | row_ptr[0] = row_ptr[1] = row_ptr[2] = 0; 192 | } 193 | 194 | // Last column. 195 | if (ColorDiff_L1(row_ptr, row_ptr + width_step) != 0) 196 | row_ptr[0] = row_ptr[1] = row_ptr[2] = 0; 197 | } 198 | 199 | // Last row. 200 | char* row_ptr = img + width_step * (height - 1); 201 | for (int j = 0; j < width - 1; ++j, row_ptr += 3) { 202 | if (ColorDiff_L1(row_ptr, row_ptr + 3) != 0) 203 | row_ptr[0] = row_ptr[1] = row_ptr[2] = 0; 204 | } 205 | } 206 | } 207 | 208 | int GetRegionIdFromPoint(int x, int y, int level, const SegmentationDesc& seg, 209 | const SegmentationDesc* seg_hier) { 210 | 211 | if (level > 0 && seg.hierarchy_size() != 0) { 212 | // Is a hierarchy present at the current frame? 213 | seg_hier = &seg; 214 | } 215 | 216 | if (level) 217 | level = std::min(level, seg_hier->hierarchy_size()); 218 | 219 | ASSURE_LOG(level == 0 || seg_hier) << "Hierarchy requested but not found."; 220 | ASSURE_LOG(level == 0 || level <= seg_hier->hierarchy_size()) << "Requested hierarchy exceeds" 221 | << " levels supplied in seg or seg_hier."; 222 | 223 | const RepeatedPtrField& regions = seg.region(); 224 | for(RepeatedPtrField::const_iterator r = regions.begin(); 225 | r != regions.end(); 226 | ++r) { 227 | 228 | // Is y within the regions range? 229 | if (y >= r->top_y() && y < r->top_y() + r->scanline_size()) { 230 | // Jump to specific scanline. 231 | const Scanline& s = r->scanline(y - r->top_y()); 232 | 233 | // Is x in range? 234 | for (int i = 0, sz = s.interval_size(); i < sz; ++i) { 235 | const ScanlineInterval& inter = s.interval(i); 236 | if (x >= inter.left_x() && x <= inter.right_x()) { 237 | // Get my id and return. 238 | if (level == 0) 239 | return r->id(); 240 | else { 241 | int parent_id = r->parent_id(); 242 | 243 | for (int l = 0; l < level-1; ++l) { 244 | ASSERT_LOG(seg_hier->hierarchy(l).region_size() > parent_id); 245 | parent_id = seg_hier->hierarchy(l).region(parent_id).parent_id(); 246 | } 247 | 248 | return parent_id; 249 | } 250 | } 251 | } 252 | } 253 | } 254 | return -1; 255 | } 256 | 257 | 258 | void RenderRegions(const vector& region_ids, 259 | uchar color, 260 | uchar* img, 261 | int width_step, 262 | int width, 263 | int height, 264 | int num_colors, 265 | int level, 266 | const SegmentationDesc& seg, 267 | const SegmentationDesc* seg_hier) { 268 | 269 | // Make sure region_ids is sorted. 270 | vector region_ids_sorted(region_ids); 271 | std::sort(region_ids_sorted.begin(), region_ids_sorted.end()); 272 | 273 | if (level > 0 && seg.hierarchy_size() != 0) { 274 | // Is a hierarchy present at the current frame? 275 | seg_hier = &seg; 276 | } 277 | 278 | if (level) 279 | level = std::min(level, seg_hier->hierarchy_size()); 280 | 281 | ASSURE_LOG(level == 0 || seg_hier) << "Hierarchy requested but not found."; 282 | ASSURE_LOG(level == 0 || level <= seg_hier->hierarchy_size()) << "Requested hierarchy exceeds" 283 | << " levels supplied in seg or seg_hier."; 284 | 285 | 286 | // Mark each region found in region_ids with color. 287 | const RepeatedPtrField& regions = seg.region(); 288 | for(RepeatedPtrField::const_iterator r = regions.begin(); 289 | r != regions.end(); 290 | ++r) { 291 | 292 | // Get id. 293 | int region_id; 294 | if (level == 0) 295 | region_id = r->id(); 296 | else { 297 | // Traverse to parent region. 298 | int parent_id = r->parent_id(); 299 | 300 | for (int l = 0; l < level-1; ++l) { 301 | ASSERT_LOG(seg_hier->hierarchy(l).region_size() > parent_id); 302 | parent_id = seg_hier->hierarchy(l).region(parent_id).parent_id(); 303 | } 304 | 305 | region_id = parent_id; 306 | } 307 | 308 | vector::const_iterator pos = std::lower_bound(region_ids_sorted.begin(), 309 | region_ids_sorted.end(), region_id); 310 | if (pos != region_ids_sorted.end() && *pos == region_id) { 311 | 312 | const RepeatedPtrField& scanlines = r->scanline(); 313 | uchar* dst_ptr = PtrOffset(img, r->top_y() * width_step); 314 | 315 | for(RepeatedPtrField::const_iterator s = scanlines.begin(); 316 | s != scanlines.end(); 317 | ++s) { 318 | for (int i = 0, sz = s->interval_size(); i < sz; ++i) { 319 | const ScanlineInterval& inter = s->interval(i); 320 | uchar* out_ptr = dst_ptr + inter.left_x() * num_colors; 321 | for (int j = 0, len = inter.right_x() - inter.left_x() + 1; 322 | j < len; 323 | ++j, out_ptr+=num_colors) { 324 | *out_ptr = color; 325 | } 326 | } 327 | 328 | dst_ptr = PtrOffset(dst_ptr, width_step); 329 | } 330 | } 331 | } 332 | } 333 | 334 | typedef std::pair RegionColor; 335 | struct RegionColorComp : public std::binary_function { 336 | 337 | bool operator()(const RegionColor& r1, const RegionColor& r2) { 338 | return r1.first < r2.first; 339 | } 340 | 341 | }; 342 | 343 | void RenderRegions(const vector >& region_color_pairs, 344 | uchar* img, 345 | int width_step, 346 | int width, 347 | int height, 348 | int num_colors, 349 | int level, 350 | const SegmentationDesc& seg, 351 | const SegmentationDesc* seg_hier) { 352 | 353 | // Make sure region_ids is sorted. 354 | vector region_ids_sorted(region_color_pairs); 355 | std::sort(region_ids_sorted.begin(), region_ids_sorted.end(), RegionColorComp()); 356 | 357 | if (level > 0 && seg.hierarchy_size() != 0) { 358 | // Is a hierarchy present at the current frame? 359 | seg_hier = &seg; 360 | } 361 | 362 | if (level) 363 | level = std::min(level, seg_hier->hierarchy_size()); 364 | 365 | ASSURE_LOG(level == 0 || seg_hier) << "Hierarchy requested but not found."; 366 | ASSURE_LOG(level == 0 || level <= seg_hier->hierarchy_size()) << "Requested hierarchy exceeds" 367 | << " levels supplied in seg or seg_hier."; 368 | 369 | 370 | // Mark each region found in region_ids with color. 371 | const RepeatedPtrField& regions = seg.region(); 372 | for(RepeatedPtrField::const_iterator r = regions.begin(); 373 | r != regions.end(); 374 | ++r) { 375 | 376 | // Get id. 377 | int region_id; 378 | if (level == 0) 379 | region_id = r->id(); 380 | else { 381 | // Traverse to parent region. 382 | int parent_id = r->parent_id(); 383 | 384 | for (int l = 0; l < level - 1; ++l) { 385 | ASSERT_LOG(seg_hier->hierarchy(l).region_size() > parent_id); 386 | parent_id = seg_hier->hierarchy(l).region(parent_id).parent_id(); 387 | } 388 | 389 | region_id = parent_id; 390 | } 391 | 392 | vector >::const_iterator pos = 393 | std::lower_bound(region_ids_sorted.begin(), region_ids_sorted.end(), 394 | std::make_pair(region_id, 0), RegionColorComp()); 395 | if (pos != region_ids_sorted.end() && pos->first == region_id) { 396 | uchar color = pos->second; 397 | const RepeatedPtrField& scanlines = r->scanline(); 398 | uchar* dst_ptr = PtrOffset(img, r->top_y() * width_step); 399 | 400 | for(RepeatedPtrField::const_iterator s = scanlines.begin(); 401 | s != scanlines.end(); 402 | ++s) { 403 | for (int i = 0, sz = s->interval_size(); i < sz; ++i) { 404 | const ScanlineInterval& inter = s->interval(i); 405 | uchar* out_ptr = dst_ptr + inter.left_x() * num_colors; 406 | for (int j = 0, len = inter.right_x() - inter.left_x() + 1; 407 | j < len; 408 | ++j, out_ptr+=num_colors) { 409 | *out_ptr = color; 410 | } 411 | } 412 | 413 | dst_ptr = PtrOffset(dst_ptr, width_step); 414 | } 415 | } 416 | } 417 | } 418 | } -------------------------------------------------------------------------------- /code/segmentation_exporter/segment_util/segmentation_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * segmentation_util.h 3 | * seamcarving 4 | * 5 | * Created by Matthias Grundmann on 6/15/09. 6 | * Copyright 2009 Matthias Grundmann. All rights reserved. 7 | * 8 | */ 9 | 10 | #ifndef SEGMENTATION_UTIL_H__ 11 | #define SEGMENTATION_UTIL_H__ 12 | 13 | #include "segmentation.pb.h" 14 | #include 15 | 16 | #ifdef _WIN32 17 | #include 18 | #else 19 | #include 20 | #endif 21 | 22 | namespace Segment { 23 | typedef unsigned char uchar; 24 | using std::vector; 25 | #ifndef _WIN32 26 | using __gnu_cxx::hash_map; 27 | #else 28 | using stdext::hash_map; 29 | #endif 30 | 31 | // Common usage for all functions: 32 | // The level of the hierarchy is passed in hierarchy_level. 33 | // 0: denotes the over-segmentation. 34 | // >1 : denotes a hierarchical level which is saved in the protobuffer at hierarchy_level - 1. 35 | // 36 | // Functions will threshold the passed level to max. level present in the hierarchy. 37 | // 38 | // The pixel level segmentation in SegmentationDesc and the actual hierarchy can 39 | // be separated, as the hierarchy is saved only ONCE for the whole video volume. 40 | // If a hierarchy is not specified in seg_hier, it is assumed that if 41 | // hierarchy_level > 0, desc contains a valid hierarchy. 42 | 43 | // Converts Segmentation description to image by assigning each pixel its 44 | // corresponding region id. 45 | void SegmentationDescToIdImage(int* img, 46 | int width_step, 47 | int width, 48 | int height, 49 | int hierarchy_level, 50 | const SegmentationDesc& desc, 51 | const SegmentationDesc* seg_hier = 0); 52 | 53 | // Renders each region with a random color for 3-channel 8-bit input image. 54 | // If highlight_boundary is set, region boundary will be colored black. 55 | void RenderRegionsRandomColor(char* img, 56 | int width_step, 57 | int width, 58 | int height, 59 | int hierarchy_level, 60 | bool highlight_boundary, 61 | const SegmentationDesc& desc, 62 | const SegmentationDesc* seg_hier = 0); 63 | 64 | // Returns region_id at corresponding (x, y) location in image, 65 | // return value -1 indicates error. 66 | int GetRegionIdFromPoint(int x, 67 | int y, 68 | int hierarchy_level, 69 | const SegmentationDesc& seg, 70 | const SegmentationDesc* seg_hier = 0); 71 | 72 | // DEPRECATED 73 | // Render the specified region_ids with 1 channel color in multi-channel image. 74 | void RenderRegions(const vector& region_ids, 75 | uchar color, 76 | uchar* img, 77 | int width_step, 78 | int width, 79 | int height, 80 | int num_colors, 81 | int hierarchy_level, 82 | const SegmentationDesc& desc, 83 | const SegmentationDesc* seg_hier = 0); 84 | // DEPRECATED 85 | // Render the specified regions region_ids with associated 1 channel color. 86 | void RenderRegions(const vector >& region_color_pairs, 87 | uchar* img, 88 | int width_step, 89 | int width, 90 | int height, 91 | int num_colors, 92 | int hierarchy_level, 93 | const SegmentationDesc& desc, 94 | const SegmentationDesc* seg_hier = 0); 95 | 96 | } // namespace Segment. 97 | 98 | #endif // SEGMENTATION_UTIL_H__ -------------------------------------------------------------------------------- /code/segmentation_exporter/segmentation_exporter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | project(segmentation_exporter) 4 | set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") 5 | include(${CMAKE_MODULE_PATH}/common.cmake) 6 | include("${CMAKE_SOURCE_DIR}/depend.cmake") 7 | 8 | set(SOURCES main.cpp) 9 | headers_from_sources_cpp(HEADERS "${SOURCES}") 10 | set(SOURCES "${SOURCES}" "${HEADERS}") 11 | 12 | add_executable(segmentation_exporter ${SOURCES}) 13 | 14 | apply_dependencies(segmentation_exporter) 15 | -------------------------------------------------------------------------------- /code/segmentation_exporter/segmentation_exporter/depend.cmake: -------------------------------------------------------------------------------- 1 | find_package(OpenCV REQUIRED) 2 | 3 | set(DEPENDENT_INCLUDES ${OpenCV_INCLUDE_DIRS}) 4 | set(DEPENDENT_LIBRARIES ${OpenCV_LIBRARIES}) 5 | set(DEPENDENT_LINK_DIRECTORIES ${OpenCV_LINK_DIRECTORIES}) 6 | set(DEPENDENT_PACKAGES assert_log segment_util) 7 | -------------------------------------------------------------------------------- /code/segmentation_exporter/segmentation_exporter/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * main.cpp 3 | * segmentation_sample 4 | * 5 | * Created by Matthias Grundmann on 6/17/2010. 6 | * Copyright 2010 Matthias Grundmann. All rights reserved. 7 | * 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #include "assert_log.h" 21 | #include "segmentation_io.h" 22 | #include "segmentation_util.h" 23 | 24 | using namespace Segment; 25 | 26 | // Slider positions. 27 | int g_hierarchy_level; 28 | int g_frame_pos; 29 | 30 | // Frame width and height. 31 | //int g_frame_num_; 32 | int g_frame_width; 33 | int g_frame_height; 34 | 35 | // This should be scoped_ptr's. Removed to remove boost dependency. 36 | SegmentationReader* g_segment_reader; 37 | SegmentationDesc* g_seg_hierarchy; 38 | 39 | // Render target. 40 | IplImage* g_frame_buffer = 0; 41 | 42 | // Indicates if automatic playing is set. 43 | //bool g_playing; 44 | 45 | // Returns number of hierarchy_levels. 46 | void RenderCurrentFrame(int frame_number) { 47 | g_segment_reader->SeekToFrame(frame_number); 48 | 49 | // Read from file. 50 | vector data_buffer(g_segment_reader->ReadFrameSize()); 51 | g_segment_reader->ReadFrame(&data_buffer[0]); 52 | 53 | SegmentationDesc segmentation; 54 | segmentation.ParseFromArray(&data_buffer[0], data_buffer.size()); 55 | 56 | // Allocate frame_buffer if necessary 57 | if (g_frame_buffer == NULL) { 58 | g_frame_buffer = cvCreateImage(cvSize(g_frame_width, 59 | g_frame_height), IPL_DEPTH_8U, 3); 60 | } 61 | 62 | // Render segmentation at specified level. 63 | RenderRegionsRandomColor(g_frame_buffer->imageData, 64 | g_frame_buffer->widthStep, 65 | g_frame_buffer->width, 66 | g_frame_buffer->height, 67 | g_hierarchy_level, 68 | true, 69 | segmentation, 70 | g_seg_hierarchy); 71 | } 72 | 73 | //void FramePosChanged(int pos) { 74 | // g_frame_pos = pos; 75 | // RenderCurrentFrame(g_frame_pos); 76 | // cvShowImage("main_window", g_frame_buffer); 77 | //} 78 | 79 | //void HierarchyLevelChanged(int level) { 80 | // g_hierarchy_level = level; 81 | // RenderCurrentFrame(g_frame_pos); 82 | // cvShowImage("main_window", g_frame_buffer); 83 | //} 84 | 85 | int main(int argc, char** argv) { 86 | // Get filename from command prompt. 87 | if (argc != 3) { 88 | std::cout << "Usage: segmentation_exporter INPUT_FILE_NAME OUTPUT_DIRECTORY_ROOT\n"; 89 | return 1; 90 | } 91 | 92 | std::string input_filename( argv[ 1 ] ); 93 | std::string output_directory_root( argv[ 2 ] ); 94 | 95 | std::string mkdir_command = "mkdir " + output_directory_root; 96 | std::cout << mkdir_command << std::endl; 97 | system( mkdir_command.c_str() ); 98 | 99 | //g_playing = false; 100 | 101 | // Read segmentation file. 102 | g_segment_reader = new SegmentationReader( input_filename ); 103 | g_segment_reader->OpenFileAndReadHeader(); 104 | g_frame_pos = 0; 105 | 106 | std::cout << "Segmentation file " << input_filename << " contains " 107 | << g_segment_reader->FrameNumber() << " frames.\n"; 108 | 109 | // Read first frame, it contains the hierarchy. 110 | vector data_buffer(g_segment_reader->ReadFrameSize()); 111 | g_segment_reader->ReadFrame(&data_buffer[0]); 112 | 113 | // Save hierarchy for all frames. 114 | g_seg_hierarchy = new SegmentationDesc; 115 | g_seg_hierarchy->ParseFromArray(&data_buffer[0], data_buffer.size()); 116 | 117 | //g_frame_num_ = g_segment_reader->FrameNumber(); 118 | g_frame_width = g_seg_hierarchy->frame_width(); 119 | g_frame_height = g_seg_hierarchy->frame_height(); 120 | 121 | std::cout << "Video resolution: " << g_frame_width << "x" << g_frame_height << "\n"; 122 | 123 | // Create OpenCV window. 124 | //cvNamedWindow("main_window"); 125 | 126 | RenderCurrentFrame(0); 127 | 128 | for ( int j = 0; j < g_seg_hierarchy->hierarchy_size() + 2; j++ ) { 129 | std::stringstream directory_name_stream; 130 | #ifdef _WIN32 // works for both 32 and 64 bit 131 | directory_name_stream << output_directory_root << "\\" << "hierarchy_level_" << std::setfill( '0' ) << std::setw( 2 ) << j; 132 | #else 133 | directory_name_stream << output_directory_root << "/" << "hierarchy_level_" << std::setfill( '0' ) << std::setw( 2 ) << j; 134 | #endif 135 | std::string directory_name = directory_name_stream.str(); 136 | 137 | std::string mkdir_command = "mkdir " + directory_name; 138 | std::cout << mkdir_command << std::endl; 139 | system( mkdir_command.c_str() ); 140 | 141 | for ( int i = 0; i < g_segment_reader->FrameNumber(); i++ ) { 142 | g_frame_pos = i; 143 | g_hierarchy_level = j; 144 | RenderCurrentFrame(g_frame_pos); 145 | 146 | std::stringstream file_name_stream; 147 | file_name_stream << directory_name << "/" << std::setfill( '0' ) << std::setw( 6 ) << i + 1 << ".png"; 148 | std::string file_name = file_name_stream.str(); 149 | 150 | std::cout << file_name << std::endl; 151 | cvSaveImage( file_name.c_str(), g_frame_buffer ); 152 | } 153 | } 154 | 155 | //cvShowImage("main_window", g_frame_buffer); 156 | 157 | //cvCreateTrackbar("frame_pos", 158 | // "main_window", 159 | // &g_frame_pos, 160 | // g_segment_reader->FrameNumber() - 1, 161 | // &FramePosChanged); 162 | 163 | //cvCreateTrackbar("hier_level", 164 | // "main_window", 165 | // &g_hierarchy_level, 166 | // g_seg_hierarchy->hierarchy_size(), 167 | // &HierarchyLevelChanged); 168 | 169 | 170 | //int key_value = 0; 171 | 172 | //// Yotam Doron recommended this kind of loop. 173 | //while (1) { 174 | // key_value = cvWaitKey(30) & 0xFF; 175 | // if (key_value == 27) { 176 | // break; 177 | // } 178 | 179 | // if (g_playing) { 180 | // FramePosChanged((g_frame_pos + 1) % g_frame_num_); 181 | // } 182 | // 183 | // switch (key_value) { 184 | // case 110: 185 | // FramePosChanged((g_frame_pos + 1) % g_frame_num_); 186 | // break; 187 | // case 112: 188 | // FramePosChanged((g_frame_pos - 1 + g_frame_num_) % g_frame_num_); 189 | // break; 190 | // case 32: 191 | // g_playing = !g_playing; 192 | // default: 193 | // break; 194 | // } 195 | //} 196 | 197 | g_segment_reader->CloseFile(); 198 | delete g_segment_reader; 199 | 200 | cvReleaseImage(&g_frame_buffer); 201 | delete g_seg_hierarchy; 202 | 203 | return 0; 204 | } 205 | -------------------------------------------------------------------------------- /data/cars1_segment.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikeroberts3000/EfficientHierarchicalGraphBasedVideoSegmentationExporter/71bbf64b4bed4b22fc206e400c8b33b473f7a2f2/data/cars1_segment.pb --------------------------------------------------------------------------------