diff --git a/.github/generate_gh_pages.sh b/.github/generate_gh_pages.sh new file mode 100644 index 0000000000000000000000000000000000000000..b8799da175258f5616afba16c4bcf070e076d367 --- /dev/null +++ b/.github/generate_gh_pages.sh @@ -0,0 +1,106 @@ +#!/bin/sh +################################################################################ +# Title : generate_gh_pages.sh +# Date created : 2016/02/22 +# Notes : +__AUTHOR__="openpose" +# Preconditions: +# - Packages doxygen doxygen-doc doxygen-latex doxygen-gui graphviz +# must be installed. +# - Doxygen configuration file must have the destination directory empty and +# source code directory with a $(TRAVIS_BUILD_DIR) prefix. +# - An gh-pages branch should already exist. See below for mor info on hoe to +# create a gh-pages branch. +# +# Required global variables: +# - TRAVIS_BUILD_NUMBER : The number of the current build. +# - TRAVIS_COMMIT : The commit that the current build is testing. +# - DOXYFILE : The Doxygen configuration file. +# - GH_REPO_NAME : The name of the repository. +# - GH_REPO_REF : The GitHub reference to the repository. +# - GH_REPO_TOKEN : Secure token to the github repository. +# +# For information on how to encrypt variables for Travis CI please go to +# https://docs.travis-ci.com/user/environment-variables/#Encrypted-Variables +# or https://gist.github.com/vidavidorra/7ed6166a46c537d3cbd2 +# For information on how to create a clean gh-pages branch from the master +# branch, please go to https://gist.github.com/vidavidorra/846a2fc7dd51f4fe56a0 +# +# This script will generate Doxygen documentation and push the documentation to +# the gh-pages branch of a repository specified by GH_REPO_REF. +# Before this script is used there should already be a gh-pages branch in the +# repository. +# +################################################################################ + +################################################################################ +##### Setup this script and get the current gh-pages branch. ##### +echo 'Setting up the script...' +# Exit with nonzero exit code if anything fails +set -e + +# Create a clean working directory for this script. +mkdir code_docs +cd code_docs + +# Get the current gh-pages branch +git clone -b gh-pages https://git@$GH_REPO_REF +cd $GH_REPO_NAME + +##### Configure git. +# Set the push default to simple i.e. push only the current branch. +git config --global push.default simple +# Pretend to be an user called Travis CI. +git config user.name "Travis CI" +git config user.email "travis@travis-ci.org" + +# Remove everything currently in the gh-pages branch. +# GitHub is smart enough to know which files have changed and which files have +# stayed the same and will only update the changed files. So the gh-pages branch +# can be safely cleaned, and it is sure that everything pushed later is the new +# documentation. +rm -rf * + +# Need to create a .nojekyll file to allow filenames starting with an underscore +# to be seen on the gh-pages site. Therefore creating an empty .nojekyll file. +# Presumably this is only needed when the SHORT_NAMES option in Doxygen is set +# to NO, which it is by default. So creating the file just in case. +echo "" > .nojekyll + +################################################################################ +##### Generate the Doxygen code documentation and log the output. ##### +echo 'Generating Doxygen code documentation...' +# Redirect both stderr and stdout to the log file AND the console. +echo "INPUT = ${TRAVIS_BUILD_DIR}/README.md ${TRAVIS_BUILD_DIR}/include/openpose/" >> $DOXYFILE +echo "USE_MDFILE_AS_MAINPAGE = ${TRAVIS_BUILD_DIR}/README.md" >> $DOXYFILE +echo "OUTPUT_DIRECTORY = " >> $DOXYFILE +doxygen $DOXYFILE 2>&1 | tee doxygen.log + +################################################################################ +##### Upload the documentation to the gh-pages branch of the repository. ##### +# Only upload if Doxygen successfully created the documentation. +# Check this by verifying that the html directory and the file html/index.html +# both exist. This is a good indication that Doxygen did it's work. +if [ -d "html" ] && [ -f "html/index.html" ]; then + + echo 'Uploading documentation to the gh-pages branch...' + # Add everything in this directory (the Doxygen code documentation) to the + # gh-pages branch. + # GitHub is smart enough to know which files have changed and which files have + # stayed the same and will only update the changed files. + git add --all + + # Commit the added files with a title and description containing the Travis CI + # build number and the GitHub commit reference that issued this build. + git commit -m "Deploy code docs to GitHub Pages Travis build: ${TRAVIS_BUILD_NUMBER}" -m "Commit: ${TRAVIS_COMMIT}" + + # Force push to the remote gh-pages branch. + # The ouput is redirected to /dev/null to hide any sensitive credential data + # that might otherwise be exposed. + git push --force "https://${GH_REPO_TOKEN}@${GH_REPO_REF}" > /dev/null 2>&1 +else + echo '' >&2 + echo 'Warning: No documentation (html) files have been found!' >&2 + echo 'Warning: Not going to push the documentation to GitHub!' >&2 + exit 1 +fi diff --git a/.gitignore b/.gitignore index ddff342da701656f708a48a20dd0b13168e75ffb..9e74905ae01536bded61b78bb8f625ad70ad0e48 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,12 @@ MANIFEST-* # OSX dir files .DS_Store +# Vim files +cscope.* +tags +.clang_complete +.vim + ######################### Windows (Visual Studio) Files ######################### *.db *.deps diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..2dec08e4b7b1d9ff615664dc30b6849b5dc80a01 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,46 @@ +# This will run on Travis' 'new' container-based infrastructure + +# Blacklist +branches: + only: + - master + +# OS +dist: trusty +sudo: required + +# Environment variables +env: + global: + - GH_REPO_NAME: openpose + - DOXYFILE: $TRAVIS_BUILD_DIR/doc/doc_autogeneration.doxygen + # Set this in Environment Variables on travis-ci.org + # - GH_REPO_REF: github.com//openpose.git + +# Install dependencies +addons: + apt: + packages: + - doxygen + - doxygen-doc + - doxygen-latex + - doxygen-gui + - graphviz + +# Build your code e.g. by calling make +script: + - ./ubuntu/install_cmake.sh + - sudo apt-get -y install libatlas-base-dev + - sudo apt-get -y install libopencv-dev + - pip install --upgrade numpy + - mkdir build + - cd build + - cmake -DBUILD_CAFFE=ON .. + - no_cores=`cat /proc/cpuinfo | grep processor | wc -l` + - make -j${no_cores} + +# Generate and deploy documentation +after_success: + - cd $TRAVIS_BUILD_DIR + - chmod +x .github/generate_gh_pages.sh + - ./.github/generate_gh_pages.sh diff --git a/3rdparty/caffe/cmake/Dependencies.cmake b/3rdparty/caffe/cmake/Dependencies.cmake index 4a5bac471b463538df752ef03a3ad8a5d67528b0..c48255c89f2b68d35d6373593229f39605330ad6 100644 --- a/3rdparty/caffe/cmake/Dependencies.cmake +++ b/3rdparty/caffe/cmake/Dependencies.cmake @@ -5,7 +5,7 @@ set(Caffe_DEFINITIONS "") set(Caffe_COMPILE_OPTIONS "") # ---[ Boost -find_package(Boost 1.55 REQUIRED COMPONENTS system thread filesystem) +find_package(Boost 1.54 REQUIRED COMPONENTS system thread filesystem) list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${Boost_INCLUDE_DIRS}) list(APPEND Caffe_LINKER_LIBS PUBLIC ${Boost_LIBRARIES}) diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f67364c9c0a9f81e7eece7c8e0cb00c2171223f6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,244 @@ +project(openpose) +cmake_minimum_required(VERSION 2.8.7 FATAL_ERROR) # min. cmake version recommmended by Caffe + +### FIND THE OS + +if (WIN32) # OS is Windows + message(FATAL_ERROR "Windows OS is not currently supported.") +elseif (APPLE) # OS is Apple + message(FATAL_ERROR "Apple OS is not currently supported.") +elseif (UNIX AND NOT APPLE) # OS is a Linux distribution (it assumes Ubuntu) + set(EXECUTE_COMMAND lsb_release -rs) + execute_process(COMMAND ${EXECUTE_COMMAND} OUTPUT_VARIABLE UBUNTU_VERSION) + string(SUBSTRING ${UBUNTU_VERSION} 0 2 UBUNTU_MAJOR_VERSION) + if (${UBUNTU_MAJOR_VERSION} MATCHES "16") # if 16 + set(IS_UBUNTU_16 TRUE) + set(IS_UBUNTU_14_OR_LESS FALSE) + else (${UBUNTU_MAJOR_VERSION MATCHES "16") # if 14 or less + set(IS_UBUNTU_16 FALSE) + set(IS_UBUNTU_14_OR_LESS TRUE) + endif (${UBUNTU_MAJOR_VERSION} MATCHES "16") +endif () + +### FLAGS + +# Build as shared library +set(BUILD_SHARED_LIBS ON) + +# Turn on C++11 +add_definitions(-std=c++11) + +# OpenPose flags +add_definitions(-DUSE_CAFFE) + +# C++ additional flags +set(OP_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp -Wpedantic -Wall -Wextra -Wfatal-errors") + +### PROJECT OPTIONS + +# Select the DL Framework +set(DL_FRAMEWORK CAFFE CACHE STRING "Select Deep Learning Framework.") +set_property(CACHE DL_FRAMEWORK PROPERTY STRINGS CAFFE) +# set_property(CACHE DL_FRAMEWORK PROPERTY STRINGS CAFFE CAFFE2 TENSORFLOW) + +# Suboptions for Caffe DL Framework +include(CMakeDependentOption) +if (${DL_FRAMEWORK} MATCHES "CAFFE") + CMAKE_DEPENDENT_OPTION(BUILD_CAFFE "Build Caffe as part of OpenPose." ON + "DL_FRAMEWORK" ON) +endif (${DL_FRAMEWORK} MATCHES "CAFFE") + +# Set the acceleration library +set(GPU_MODE CUDA CACHE STRING "Select the acceleration GPU library or CPU otherwise.") +set_property(CACHE GPU_MODE PROPERTY STRINGS CUDA) +# set_property(CACHE GPU_MODE PROPERTY STRINGS CUDA OPENCL CPU_ONLY) + +# Suboptions for GPU architectures +if (${GPU_MODE} MATCHES "CUDA") + set(CUDA_ARCH Auto CACHE STRING "Select target NVIDIA GPU achitecture.") + set_property(CACHE CUDA_ARCH PROPERTY STRINGS Auto All Manual) +endif (${GPU_MODE} MATCHES "CUDA") + +# Suboptions for acceleration library +if (${GPU_MODE} MATCHES "CUDA") + option(USE_CUDNN "Build OpenPose with cuDNN library support." ON) +endif (${GPU_MODE} MATCHES "CUDA") + +# Download the models +option(DOWNLOAD_COCO_MODEL "Download COCO model." ON) +option(DOWNLOAD_MPI_MODEL "Download MPI model." OFF) +option(DOWNLOAD_HAND_MODEL "Download hand model." ON) +option(DOWNLOAD_FACE_MODEL "Download face model." ON) + +# More options +option(BUILD_EXAMPLES "Build OpenPose examples." ON) +option(BUILD_DOCS "Build OpenPose documentation." OFF) + +### FIND REQUIRED PACKAGES + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") +include(cmake/Cuda.cmake) +# find_package(CUDA) +find_package(Boost COMPONENTS system filesystem) +find_package(CuDNN) +find_package(GFlags) +find_package(Glog) +find_package(OpenCV) + +if (NOT Boost_FOUND) + message(FATAL_ERROR "Boost not found. Install Boost from the command line using the command(s) --\ + sudo apt-get install libboost-all-dev") +endif (NOT Boost_FOUND) + +if (NOT CUDA_FOUND) + message(STATUS "CUDA not found.") + execute_process(COMMAND cat install_cuda.sh WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/ubuntu) + message(FATAL_ERROR "Install CUDA using the above commands.") +endif (NOT CUDA_FOUND) + +if (USE_CUDNN AND NOT CUDNN_FOUND) + message(STATUS "cuDNN not found.") + execute_process(COMMAND cat install_cudnn.sh WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/ubuntu) + message(FATAL_ERROR "Install cuDNN using the above commands. or turn off cuDNN by setting USE_CUDNN to OFF.") +endif (USE_CUDNN AND NOT CUDNN_FOUND) + +if (NOT GLOG_FOUND) + message(FATAL_ERROR "Glog not found. Install Glog from the command line using the command(s) -\ + sudo apt-get install libgoogle-glog-dev") +endif (NOT GLOG_FOUND) + +if (NOT GFLAGS_FOUND) + message(FATAL_ERROR "GFlags not found. Install GFlags from the command line using the command(s) --\ + sudo apt-get install libgflags-dev") +endif (NOT GFLAGS_FOUND) + +if (NOT OpenCV_FOUND) + message(FATAL_ERROR "OpenCV not found. Install OpenCV from the command line using the command(s) --\ + sudo apt-get install libopencv-dev") +endif (NOT OpenCV_FOUND) + +# Set CUDA Flags + +set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -std=c++11") + +### CAFFE + +if (${DL_FRAMEWORK} MATCHES "CAFFE") + + # Check if the user specified caffe paths + if (Caffe_INCLUDE_DIRS AND Caffe_LIBS AND NOT BUILD_CAFFE) + message(STATUS "\${Caffe_INCLUDE_DIRS} set by the user to " ${Caffe_INCLUDE_DIRS}) + message(STATUS "\${Caffe_LIBS} set by the user to " ${Caffe_LIBS}) + set(Caffe_FOUND 1) + endif (Caffe_INCLUDE_DIRS AND Caffe_LIBS AND NOT BUILD_CAFFE) + + # Check if caffe is installed in known paths + if (NOT Caffe_FOUND AND NOT BUILD_CAFFE) + message(STATUS "Looking for caffe around in expected paths.") + find_package(Caffe) + endif (NOT Caffe_FOUND AND NOT BUILD_CAFFE) + + # Else build from scratch + if (BUILD_CAFFE) + message(STATUS "Caffe will be build from source now.") + + # Build Caffe + include(ExternalProject) + set(BUILD_CAFFE ON) + set(CAFFE_PREFIX caffe) + set(CAFFE_URL ${CMAKE_SOURCE_DIR}/3rdparty/caffe) + + ExternalProject_Add(${CAFFE_PREFIX} + SOURCE_DIR ${CAFFE_URL} + PREFIX ${CAFFE_PREFIX} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= + -DUSE_CUDNN=${USE_CUDNN} + -DOpenCV_DIR=${OpenCV_DIR}) + + ExternalProject_Get_Property(caffe install_dir) + + set(Caffe_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/build/caffe/include) + # TODO -- Find a better soln. + set(Caffe_LIBS ${CMAKE_SOURCE_DIR}/build/caffe/lib/libcaffe.so) + + endif (BUILD_CAFFE) + + if (NOT Caffe_FOUND AND NOT BUILD_CAFFE) + message(FATAL_ERROR "Caffe not found. Either turn on the BUILD_CAFFE option or specify the path of Caffe includes + and libs using -DCaffe_INCLUDE_DIRS and -DCaffe_LIBS") + endif (NOT Caffe_FOUND AND NOT BUILD_CAFFE) + +endif (${DL_FRAMEWORK} MATCHES "CAFFE") + +### PROJECT INCLUDES + +# Specify the include directories +include_directories( + ${CMAKE_SOURCE_DIR}/include + ${CUDA_INCLUDE_DIRS} + ${GFLAGS_INCLUDE_DIR} + ${GLOG_INCLUDE_DIR} + ${Caffe_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS}) + +### ADD SUBDIRECTORIES + +add_subdirectory(src) +if (BUILD_EXAMPLES) + add_subdirectory(examples) +endif (BUILD_EXAMPLES) + +### GENERATE DOCUMENTATION + +if (BUILD_DOCS) + find_package(Doxygen) + if (DOXYGEN_FOUND) + # Set input and output files + set(DOXYGEN_FILE ${CMAKE_SOURCE_DIR}/doc/doc_autogeneration.doxygen) + + # Custom target to build the documentation + add_custom_target(doc_doxygen ALL + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_FILE} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/doc + COMMENT "Generating API documentation with Doxygen" + VERBATIM ) + else (DOXYGEN_FOUND) + message("Doxygen need to be installed to generate the doxygen documentation") + endif (DOXYGEN_FOUND) +endif (BUILD_DOCS) + +### DOWNLOAD MODELS + +# Download the models if flag is set +# TODO -- remove hardcoded ubuntu paths +include(cmake/Utils.cmake) +message(STATUS "Download the models.") + +# URL to the models +set(OPENPOSE_URL "http://posefs1.perception.cs.cmu.edu/OpenPose/models/") + +# Body (COCO) +if (DOWNLOAD_COCO_MODEL) + download_model("body (COCO)" ${DOWNLOAD_COCO_MODEL} pose/coco/pose_iter_440000.caffemodel + 5156d31f670511fce9b4e28b403f2939) +endif (DOWNLOAD_COCO_MODEL) + +# Body (MPI) +if (DOWNLOAD_MPI_MODEL) + download_model("body (MPI)" ${DOWNLOAD_MPI_MODEL} pose/mpi/pose_iter_160000.caffemodel + 2ca0990c7562bd7ae03f3f54afa96e00) +endif (DOWNLOAD_MPI_MODEL) + +# Face +if (DOWNLOAD_FACE_MODEL) + download_model("face" ${DOWNLOAD_FACE_MODEL} face/pose_iter_116000.caffemodel + e747180d728fa4e4418c465828384333) +endif (DOWNLOAD_FACE_MODEL) + +# Hand +if (DOWNLOAD_HAND_MODEL) + download_model("hand" ${DOWNLOAD_HAND_MODEL} hand/pose_iter_102000.caffemodel + a82cfc3fea7c62f159e11bd3674c1531) +endif (DOWNLOAD_HAND_MODEL) + +message(STATUS "Models Downloaded.") diff --git a/README.md b/README.md index 4e09125f8801f41bd19336d3c90783a87461e752..d29cb65b8267e9bd884f7783f621dae7ef3f70d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ OpenPose ==================================== +[![Build Status](https://travis-ci.org/CMU-Perceptual-Computing-Lab/openpose.svg?branch=master)](https://travis-ci.org/CMU-Perceptual-Computing-Lab/openpose) + OpenPose is a **library for real-time multi-person keypoint detection and multi-threading written in C++** using OpenCV and Caffe.

diff --git a/cmake/Cuda.cmake b/cmake/Cuda.cmake new file mode 100644 index 0000000000000000000000000000000000000000..0685689a74d8a22e88141bddc2a0234610083c98 --- /dev/null +++ b/cmake/Cuda.cmake @@ -0,0 +1,305 @@ +# Copied from Caffe + +if(CPU_ONLY) + return() +endif() + +################################################################################################ +# Remove duplicates from list(s) +# Usage: +# op_list_unique( [] [...]) +macro(op_list_unique) + foreach(__lst ${ARGN}) + if(${__lst}) + list(REMOVE_DUPLICATES ${__lst}) + endif() + endforeach() +endmacro() + +# This list will be used for CUDA_ARCH = All option +set(Caffe_known_gpu_archs "20 21(20) 30 35 50 52 60 61") + +################################################################################################ +# A function for automatic detection of GPUs installed (if autodetection is enabled) +# Usage: +# op_detect_installed_gpus(out_variable) +function(op_detect_installed_gpus out_variable) + if(NOT CUDA_gpu_detect_output) + set(__cufile ${PROJECT_BINARY_DIR}/detect_cuda_archs.cu) + + file(WRITE ${__cufile} "" + "#include \n" + "int main()\n" + "{\n" + " int count = 0;\n" + " if (cudaSuccess != cudaGetDeviceCount(&count)) return -1;\n" + " if (count == 0) return -1;\n" + " for (int device = 0; device < count; ++device)\n" + " {\n" + " cudaDeviceProp prop;\n" + " if (cudaSuccess == cudaGetDeviceProperties(&prop, device))\n" + " std::printf(\"%d.%d \", prop.major, prop.minor);\n" + " }\n" + " return 0;\n" + "}\n") + + execute_process(COMMAND "${CUDA_NVCC_EXECUTABLE}" "--run" "${__cufile}" + WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/CMakeFiles/" + RESULT_VARIABLE __nvcc_res OUTPUT_VARIABLE __nvcc_out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(__nvcc_res EQUAL 0) + string(REPLACE "2.1" "2.1(2.0)" __nvcc_out "${__nvcc_out}") + set(CUDA_gpu_detect_output ${__nvcc_out} CACHE INTERNAL "Returned GPU architetures from op_detect_gpus tool" FORCE) + endif() + endif() + + if(NOT CUDA_gpu_detect_output) + message(STATUS "Automatic GPU detection failed. Building for all known architectures.") + set(${out_variable} ${Caffe_known_gpu_archs} PARENT_SCOPE) + else() + set(${out_variable} ${CUDA_gpu_detect_output} PARENT_SCOPE) + endif() +endfunction() + + +################################################################################################ +# Function for selecting GPU arch flags for nvcc based on CUDA_ARCH +# Usage: +# op_select_nvcc_arch_flags(out_variable) +function(op_select_nvcc_arch_flags out_variable) + # List of arch names + set(__archs_names "Fermi" "Kepler" "Maxwell" "Pascal" "All" "Manual") + set(__archs_name_default "All") + if(NOT CMAKE_CROSSCOMPILING) + list(APPEND __archs_names "Auto") + set(__archs_name_default "Auto") + endif() + + # set CUDA_ARCH strings (so it will be seen as dropbox in CMake-Gui) + # set(CUDA_ARCH ${__archs_name_default} CACHE STRING "Select target NVIDIA GPU achitecture.") + # set_property( CACHE CUDA_ARCH PROPERTY STRINGS "" ${__archs_names} ) + # mark_as_advanced(CUDA_ARCH) + + # verify CUDA_ARCH value + if(NOT ";${__archs_names};" MATCHES ";${CUDA_ARCH};") + string(REPLACE ";" ", " __archs_names "${__archs_names}") + message(FATAL_ERROR "Only ${__archs_names} architeture names are supported.") + endif() + + if(${CUDA_ARCH} STREQUAL "Manual") + set(CUDA_ARCH_BIN ${Caffe_known_gpu_archs} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported") + set(CUDA_ARCH_PTX "50" CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for") + # mark_as_advanced(CUDA_ARCH_BIN CUDA_ARCH_PTX) + else() + unset(CUDA_ARCH_BIN CACHE) + unset(CUDA_ARCH_PTX CACHE) + endif() + + if(${CUDA_ARCH} STREQUAL "Fermi") + set(__cuda_arch_bin "20 21(20)") + elseif(${CUDA_ARCH} STREQUAL "Kepler") + set(__cuda_arch_bin "30 35") + elseif(${CUDA_ARCH} STREQUAL "Maxwell") + set(__cuda_arch_bin "50 52") + elseif(${CUDA_ARCH} STREQUAL "Pascal") + set(__cuda_arch_bin "60 61") + elseif(${CUDA_ARCH} STREQUAL "All") + set(__cuda_arch_bin ${Caffe_known_gpu_archs}) + elseif(${CUDA_ARCH} STREQUAL "Auto") + op_detect_installed_gpus(__cuda_arch_bin) + else() # (${CUDA_ARCH} STREQUAL "Manual") + set(__cuda_arch_bin ${CUDA_ARCH_BIN}) + endif() + + # remove dots and convert to lists + string(REGEX REPLACE "\\." "" __cuda_arch_bin "${__cuda_arch_bin}") + string(REGEX REPLACE "\\." "" __cuda_arch_ptx "${CUDA_ARCH_PTX}") + string(REGEX MATCHALL "[0-9()]+" __cuda_arch_bin "${__cuda_arch_bin}") + string(REGEX MATCHALL "[0-9]+" __cuda_arch_ptx "${__cuda_arch_ptx}") + op_list_unique(__cuda_arch_bin __cuda_arch_ptx) + + set(__nvcc_flags "") + set(__nvcc_archs_readable "") + + # Tell NVCC to add binaries for the specified GPUs + foreach(__arch ${__cuda_arch_bin}) + if(__arch MATCHES "([0-9]+)\\(([0-9]+)\\)") + # User explicitly specified PTX for the concrete BIN + list(APPEND __nvcc_flags -gencode arch=compute_${CMAKE_MATCH_2},code=sm_${CMAKE_MATCH_1}) + list(APPEND __nvcc_archs_readable sm_${CMAKE_MATCH_1}) + else() + # User didn't explicitly specify PTX for the concrete BIN, we assume PTX=BIN + list(APPEND __nvcc_flags -gencode arch=compute_${__arch},code=sm_${__arch}) + list(APPEND __nvcc_archs_readable sm_${__arch}) + endif() + endforeach() + + # Tell NVCC to add PTX intermediate code for the specified architectures + foreach(__arch ${__cuda_arch_ptx}) + list(APPEND __nvcc_flags -gencode arch=compute_${__arch},code=compute_${__arch}) + list(APPEND __nvcc_archs_readable compute_${__arch}) + endforeach() + + string(REPLACE ";" " " __nvcc_archs_readable "${__nvcc_archs_readable}") + set(${out_variable} ${__nvcc_flags} PARENT_SCOPE) + set(${out_variable}_readable ${__nvcc_archs_readable} PARENT_SCOPE) +endfunction() + +################################################################################################ +# Short command for cuda compilation +# Usage: +# op_cuda_compile( ) +macro(op_cuda_compile objlist_variable) + foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG) + set(${var}_backup_in_cuda_compile_ "${${var}}") + + # we remove /EHa as it generates warnings under windows + string(REPLACE "/EHa" "" ${var} "${${var}}") + + endforeach() + + if(UNIX OR APPLE) + list(APPEND CUDA_NVCC_FLAGS -Xcompiler -fPIC) + endif() + + if(APPLE) + list(APPEND CUDA_NVCC_FLAGS -Xcompiler -Wno-unused-function) + endif() + + cuda_compile(cuda_objcs ${ARGN}) + + foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG) + set(${var} "${${var}_backup_in_cuda_compile_}") + unset(${var}_backup_in_cuda_compile_) + endforeach() + + set(${objlist_variable} ${cuda_objcs}) +endmacro() + +################################################################################################ +# Short command for cuDNN detection. Believe it soon will be a part of CUDA toolkit distribution. +# That's why not FindcuDNN.cmake file, but just the macro +# Usage: +# detect_cuDNN() +function(detect_cuDNN) + set(CUDNN_ROOT "" CACHE PATH "CUDNN root folder") + + find_path(CUDNN_INCLUDE cudnn.h + PATHS ${CUDNN_ROOT} $ENV{CUDNN_ROOT} ${CUDA_TOOLKIT_INCLUDE} + DOC "Path to cuDNN include directory." ) + + # dynamic libs have different suffix in mac and linux + if(APPLE) + set(CUDNN_LIB_NAME "libcudnn.dylib") + else() + set(CUDNN_LIB_NAME "libcudnn.so") + endif() + + get_filename_component(__libpath_hist ${CUDA_CUDART_LIBRARY} PATH) + find_library(CUDNN_LIBRARY NAMES ${CUDNN_LIB_NAME} + PATHS ${CUDNN_ROOT} $ENV{CUDNN_ROOT} ${CUDNN_INCLUDE} ${__libpath_hist} ${__libpath_hist}/../lib + DOC "Path to cuDNN library.") + + if(CUDNN_INCLUDE AND CUDNN_LIBRARY) + set(HAVE_CUDNN TRUE PARENT_SCOPE) + set(CUDNN_FOUND TRUE PARENT_SCOPE) + + file(READ ${CUDNN_INCLUDE}/cudnn.h CUDNN_VERSION_FILE_CONTENTS) + + # cuDNN v3 and beyond + string(REGEX MATCH "define CUDNN_MAJOR * +([0-9]+)" + CUDNN_VERSION_MAJOR "${CUDNN_VERSION_FILE_CONTENTS}") + string(REGEX REPLACE "define CUDNN_MAJOR * +([0-9]+)" "\\1" + CUDNN_VERSION_MAJOR "${CUDNN_VERSION_MAJOR}") + string(REGEX MATCH "define CUDNN_MINOR * +([0-9]+)" + CUDNN_VERSION_MINOR "${CUDNN_VERSION_FILE_CONTENTS}") + string(REGEX REPLACE "define CUDNN_MINOR * +([0-9]+)" "\\1" + CUDNN_VERSION_MINOR "${CUDNN_VERSION_MINOR}") + string(REGEX MATCH "define CUDNN_PATCHLEVEL * +([0-9]+)" + CUDNN_VERSION_PATCH "${CUDNN_VERSION_FILE_CONTENTS}") + string(REGEX REPLACE "define CUDNN_PATCHLEVEL * +([0-9]+)" "\\1" + CUDNN_VERSION_PATCH "${CUDNN_VERSION_PATCH}") + + if(NOT CUDNN_VERSION_MAJOR) + set(CUDNN_VERSION "???") + else() + set(CUDNN_VERSION "${CUDNN_VERSION_MAJOR}.${CUDNN_VERSION_MINOR}.${CUDNN_VERSION_PATCH}") + endif() + + message(STATUS "Found cuDNN: ver. ${CUDNN_VERSION} found (include: ${CUDNN_INCLUDE}, library: ${CUDNN_LIBRARY})") + + string(COMPARE LESS "${CUDNN_VERSION_MAJOR}" 3 cuDNNVersionIncompatible) + if(cuDNNVersionIncompatible) + message(FATAL_ERROR "cuDNN version >3 is required.") + endif() + + set(CUDNN_VERSION "${CUDNN_VERSION}" PARENT_SCOPE) + mark_as_advanced(CUDNN_INCLUDE CUDNN_LIBRARY CUDNN_ROOT) + + endif() +endfunction() + +################################################################################################ +### Non macro section +################################################################################################ + +find_package(CUDA 5.5 QUIET) +find_cuda_helper_libs(curand) # cmake 2.8.7 compartibility which doesn't search for curand + +if(NOT CUDA_FOUND) + return() +endif() + +set(HAVE_CUDA TRUE) +message(STATUS "CUDA detected: " ${CUDA_VERSION}) +list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${CUDA_INCLUDE_DIRS}) +list(APPEND Caffe_LINKER_LIBS PUBLIC ${CUDA_CUDART_LIBRARY} + ${CUDA_curand_LIBRARY} ${CUDA_CUBLAS_LIBRARIES}) + +# cudnn detection +if(USE_CUDNN) + detect_cuDNN() + if(HAVE_CUDNN) + list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_CUDNN) + list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${CUDNN_INCLUDE}) + list(APPEND Caffe_LINKER_LIBS PUBLIC ${CUDNN_LIBRARY}) + endif() +endif() + +# setting nvcc arch flags +op_select_nvcc_arch_flags(NVCC_FLAGS_EXTRA) +list(APPEND CUDA_NVCC_FLAGS ${NVCC_FLAGS_EXTRA}) +message(STATUS "Added CUDA NVCC flags for: ${NVCC_FLAGS_EXTRA_readable}") + +# Boost 1.55 workaround, see https://svn.boost.org/trac/boost/ticket/9392 or +# https://github.com/ComputationalRadiationPhysics/picongpu/blob/master/src/picongpu/CMakeLists.txt +if(Boost_VERSION EQUAL 105500) + message(STATUS "Cuda + Boost 1.55: Applying noinline work around") + # avoid warning for CMake >= 2.8.12 + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} \"-DBOOST_NOINLINE=__attribute__((noinline))\" ") +endif() + +# disable some nvcc diagnostic that apears in boost, glog, glags, opencv, etc. +foreach(diag cc_clobber_ignored integer_sign_change useless_using_declaration set_but_not_used) + list(APPEND CUDA_NVCC_FLAGS -Xcudafe --diag_suppress=${diag}) +endforeach() + +# setting default testing device +if(NOT CUDA_TEST_DEVICE) + set(CUDA_TEST_DEVICE -1) +endif() + +mark_as_advanced(CUDA_BUILD_CUBIN CUDA_BUILD_EMULATION CUDA_VERBOSE_BUILD) +mark_as_advanced(CUDA_SDK_ROOT_DIR CUDA_SEPARABLE_COMPILATION) + +# Handle clang/libc++ issue +if(APPLE) + op_detect_darwin_version(OSX_VERSION) + + # OSX 10.9 and higher uses clang/libc++ by default which is incompatible with old CUDA toolkits + if(OSX_VERSION VERSION_GREATER 10.8) + # enabled by default if and only if CUDA version is less than 7.0 + op_option(USE_libstdcpp "Use libstdc++ instead of libc++" (CUDA_VERSION VERSION_LESS 7.0)) + endif() +endif() diff --git a/cmake/Modules/FindCaffe.cmake b/cmake/Modules/FindCaffe.cmake new file mode 100644 index 0000000000000000000000000000000000000000..eca5ccb53fbfeeb73952825ecb6219830d5b76ec --- /dev/null +++ b/cmake/Modules/FindCaffe.cmake @@ -0,0 +1,23 @@ +# Copied from +# https://raw.githubusercontent.com/opencv/opencv_contrib/master/modules/cnn_3dobj/FindCaffe.cmake + +unset(Caffe_FOUND) +unset(Caffe_INCLUDE_DIRS) +unset(Caffe_LIBS) + +find_path(Caffe_INCLUDE_DIRS NAMES + caffe/caffe.hpp + caffe/common.hpp + caffe/net.hpp + caffe/proto/caffe.pb.h + caffe/util/io.hpp + HINTS + /usr/local/include) + +find_library(Caffe_LIBS NAMES caffe + HINTS + /usr/local/lib) + +if(CAFFE_LIBS AND Caffe_INCLUDE_DIRS) + set(Caffe_FOUND 1) +endif(CAFFE_LIBS AND Caffe_INCLUDE_DIRS) diff --git a/cmake/Modules/FindCuDNN.cmake b/cmake/Modules/FindCuDNN.cmake new file mode 100644 index 0000000000000000000000000000000000000000..011e5f7cdbb306132156722f6372ca316f5f2d51 --- /dev/null +++ b/cmake/Modules/FindCuDNN.cmake @@ -0,0 +1,50 @@ +set(CUDNN_ROOT "" CACHE PATH "CUDNN root folder") +set(CUDNN_LIB_NAME "libcudnn.so") + +find_path(CUDNN_INCLUDE cudnn.h + PATHS ${CUDNN_ROOT} $ENV{CUDNN_ROOT} ${CUDA_TOOLKIT_INCLUDE} + DOC "Path to cuDNN include directory." ) + +get_filename_component(__libpath_hist ${CUDA_CUDART_LIBRARY} PATH) +find_library(CUDNN_LIBRARY NAMES ${CUDNN_LIB_NAME} + PATHS ${CUDNN_ROOT} $ENV{CUDNN_ROOT} ${CUDNN_INCLUDE} ${__libpath_hist} ${__libpath_hist}/../lib + DOC "Path to cuDNN library.") + +if(CUDNN_INCLUDE AND CUDNN_LIBRARY) + set(HAVE_CUDNN TRUE) + set(CUDNN_FOUND TRUE) + + file(READ ${CUDNN_INCLUDE}/cudnn.h CUDNN_VERSION_FILE_CONTENTS) + + # cuDNN v3 and beyond + string(REGEX MATCH "define CUDNN_MAJOR * +([0-9]+)" + CUDNN_VERSION_MAJOR "${CUDNN_VERSION_FILE_CONTENTS}") + string(REGEX REPLACE "define CUDNN_MAJOR * +([0-9]+)" "\\1" + CUDNN_VERSION_MAJOR "${CUDNN_VERSION_MAJOR}") + string(REGEX MATCH "define CUDNN_MINOR * +([0-9]+)" + CUDNN_VERSION_MINOR "${CUDNN_VERSION_FILE_CONTENTS}") + string(REGEX REPLACE "define CUDNN_MINOR * +([0-9]+)" "\\1" + CUDNN_VERSION_MINOR "${CUDNN_VERSION_MINOR}") + string(REGEX MATCH "define CUDNN_PATCHLEVEL * +([0-9]+)" + CUDNN_VERSION_PATCH "${CUDNN_VERSION_FILE_CONTENTS}") + string(REGEX REPLACE "define CUDNN_PATCHLEVEL * +([0-9]+)" "\\1" + CUDNN_VERSION_PATCH "${CUDNN_VERSION_PATCH}") + + if(NOT CUDNN_VERSION_MAJOR) + set(CUDNN_VERSION "???") + else() + set(CUDNN_VERSION "${CUDNN_VERSION_MAJOR}.${CUDNN_VERSION_MINOR}.${CUDNN_VERSION_PATCH}") + endif() + + message(STATUS "Found cuDNN: ver. ${CUDNN_VERSION} found (include: ${CUDNN_INCLUDE}, library: ${CUDNN_LIBRARY})") + + string(COMPARE LESS "${CUDNN_VERSION_MAJOR}" 3 cuDNNVersionIncompatible) + if(cuDNNVersionIncompatible) + message(FATAL_ERROR "cuDNN version >3 is required.") + endif() + + set(CUDNN_VERSION "${CUDNN_VERSION}") + mark_as_advanced(CUDNN_INCLUDE CUDNN_LIBRARY CUDNN_ROOT) +else(CUDNN_INCLUDE AND CUDNN_LIBRARY) + message(STATUS "cuDNN not found") +endif() diff --git a/cmake/Modules/FindGFlags.cmake b/cmake/Modules/FindGFlags.cmake new file mode 100644 index 0000000000000000000000000000000000000000..29b60f05037bf2257b44eb191306d000dc64900f --- /dev/null +++ b/cmake/Modules/FindGFlags.cmake @@ -0,0 +1,50 @@ +# - Try to find GFLAGS +# +# The following variables are optionally searched for defaults +# GFLAGS_ROOT_DIR: Base directory where all GFLAGS components are found +# +# The following are set after configuration is done: +# GFLAGS_FOUND +# GFLAGS_INCLUDE_DIRS +# GFLAGS_LIBRARIES +# GFLAGS_LIBRARYRARY_DIRS + +include(FindPackageHandleStandardArgs) + +set(GFLAGS_ROOT_DIR "" CACHE PATH "Folder contains Gflags") + +# We are testing only a couple of files in the include directories +if(WIN32) + find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h + PATHS ${GFLAGS_ROOT_DIR}/src/windows) +else() + find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h + PATHS ${GFLAGS_ROOT_DIR}) +endif() + +if(MSVC) + find_library(GFLAGS_LIBRARY_RELEASE + NAMES libgflags + PATHS ${GFLAGS_ROOT_DIR} + PATH_SUFFIXES Release) + + find_library(GFLAGS_LIBRARY_DEBUG + NAMES libgflags-debug + PATHS ${GFLAGS_ROOT_DIR} + PATH_SUFFIXES Debug) + + set(GFLAGS_LIBRARY optimized ${GFLAGS_LIBRARY_RELEASE} debug ${GFLAGS_LIBRARY_DEBUG}) +else() + find_library(GFLAGS_LIBRARY gflags) +endif() + +find_package_handle_standard_args(GFlags DEFAULT_MSG GFLAGS_INCLUDE_DIR GFLAGS_LIBRARY) + + +if(GFLAGS_FOUND) + set(GFLAGS_INCLUDE_DIRS ${GFLAGS_INCLUDE_DIR}) + set(GFLAGS_LIBRARIES ${GFLAGS_LIBRARY}) + message(STATUS "Found gflags (include: ${GFLAGS_INCLUDE_DIR}, library: ${GFLAGS_LIBRARY})") + mark_as_advanced(GFLAGS_LIBRARY_DEBUG GFLAGS_LIBRARY_RELEASE + GFLAGS_LIBRARY GFLAGS_INCLUDE_DIR GFLAGS_ROOT_DIR) +endif() diff --git a/cmake/Modules/FindGlog.cmake b/cmake/Modules/FindGlog.cmake new file mode 100644 index 0000000000000000000000000000000000000000..99abbe478a02b452326be8c6a4f6dba6a328352c --- /dev/null +++ b/cmake/Modules/FindGlog.cmake @@ -0,0 +1,48 @@ +# - Try to find Glog +# +# The following variables are optionally searched for defaults +# GLOG_ROOT_DIR: Base directory where all GLOG components are found +# +# The following are set after configuration is done: +# GLOG_FOUND +# GLOG_INCLUDE_DIRS +# GLOG_LIBRARIES +# GLOG_LIBRARYRARY_DIRS + +include(FindPackageHandleStandardArgs) + +set(GLOG_ROOT_DIR "" CACHE PATH "Folder contains Google glog") + +if(WIN32) + find_path(GLOG_INCLUDE_DIR glog/logging.h + PATHS ${GLOG_ROOT_DIR}/src/windows) +else() + find_path(GLOG_INCLUDE_DIR glog/logging.h + PATHS ${GLOG_ROOT_DIR}) +endif() + +if(MSVC) + find_library(GLOG_LIBRARY_RELEASE libglog_static + PATHS ${GLOG_ROOT_DIR} + PATH_SUFFIXES Release) + + find_library(GLOG_LIBRARY_DEBUG libglog_static + PATHS ${GLOG_ROOT_DIR} + PATH_SUFFIXES Debug) + + set(GLOG_LIBRARY optimized ${GLOG_LIBRARY_RELEASE} debug ${GLOG_LIBRARY_DEBUG}) +else() + find_library(GLOG_LIBRARY glog + PATHS ${GLOG_ROOT_DIR} + PATH_SUFFIXES lib lib64) +endif() + +find_package_handle_standard_args(Glog DEFAULT_MSG GLOG_INCLUDE_DIR GLOG_LIBRARY) + +if(GLOG_FOUND) + set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR}) + set(GLOG_LIBRARIES ${GLOG_LIBRARY}) + message(STATUS "Found glog (include: ${GLOG_INCLUDE_DIR}, library: ${GLOG_LIBRARY})") + mark_as_advanced(GLOG_ROOT_DIR GLOG_LIBRARY_RELEASE GLOG_LIBRARY_DEBUG + GLOG_LIBRARY GLOG_INCLUDE_DIR) +endif() diff --git a/cmake/Utils.cmake b/cmake/Utils.cmake new file mode 100644 index 0000000000000000000000000000000000000000..ee8f119185c2fadca3cef16fe59062b7c41bd183 --- /dev/null +++ b/cmake/Utils.cmake @@ -0,0 +1,16 @@ +# Function to download models +function (download_model MODEL_NAME MODEL_DOWNLOAD_FLAG MODEL_RELATIVE_PATH CHECKSUM) + if (MODEL_DOWNLOAD_FLAG) + message(STATUS "Downloading ${MODEL_NAME} model...") + set(MODEL_FILENAME ${CMAKE_SOURCE_DIR}/models/${MODEL_RELATIVE_PATH}) + if (NOT EXISTS ${MODEL_FILENAME}) + message(STATUS "NOTE: This process might take several minutes depending on your internet connection.") + file(DOWNLOAD ${OPENPOSE_URL}${MODEL_RELATIVE_PATH} ${MODEL_FILENAME} + EXPECTED_MD5 ${CHECKSUM}) # SHOW_PROGRESS) + else (NOT EXISTS ${MODEL_FILENAME}) + message(STATUS "Model already exists.") + endif (NOT EXISTS ${MODEL_FILENAME}) + else (DOWNLOAD_MPI_MODEL) + message(STATUS "Not downloading ${MODEL_NAME} model") + endif (MODEL_DOWNLOAD_FLAG) +endfunction (download_model) diff --git a/doc/doc_autogeneration.doxygen b/doc/doc_autogeneration.doxygen index e0f6ae4cd3cbd09eb4ab69b94126d4cc2d699480..3e3677ff262ddda46d6b41d566d4959a4371784a 100644 --- a/doc/doc_autogeneration.doxygen +++ b/doc/doc_autogeneration.doxygen @@ -781,7 +781,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = ../include/openpose/ +INPUT = ../README.md ../include/openpose/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -972,7 +972,7 @@ FILTER_SOURCE_PATTERNS = # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = +USE_MDFILE_AS_MAINPAGE = ../README.md #--------------------------------------------------------------------------- # Configuration options related to source browsing diff --git a/doc/installation_cmake.md b/doc/installation_cmake.md new file mode 100644 index 0000000000000000000000000000000000000000..44eb773dee13fbfda48e12c0174ad346d4b23939 --- /dev/null +++ b/doc/installation_cmake.md @@ -0,0 +1,166 @@ +OpenPose - Installation using CMake +==================================== + +The CMake installation is experimental. It will eventually replace the standard and current installation system, but at the moment it is a beta version. + +## Contents +1. [Requirements](#requirements) +2. [Clone and Update the Repository](#clone-and-update-the-repository) +3. [Installation](#installation) + 1. [Caffe Prerequisites (Ubuntu Only)](#caffe-prerequisites-ubuntu-only) + 2. [OpenPose Configuration](#openpose-configuration) + 3. [OpenPose Building](#openpose-building) + 4. [Run OpenPose](#run-openpose) +5. [Reinstallation](#reinstallation) +6. [Optional Settings](#optional-settings) + 1. [Custom Caffe](#custom-caffe) + 2. [Custom OpenCV](#custom-opencv) + 3. [MPI Model](#mpi-model) + 4. [CMake Command Line Configuration](#cmake-command-line-configuration) + + + +## Requirements +- Ubuntu (tested on 14 and 16). Windows CMake version will come soon. +- NVIDIA graphics card with at least 1.6 GB available (the `nvidia-smi` command checks the available GPU memory in Ubuntu). +- At least 2 GB of free RAM memory. +- Highly recommended: A CPU with at least 8 cores. + +Note: These requirements assume the default configuration (i.e. `--net_resolution "656x368"` and `scale_number 1`). You might need more (with a greater net resolution and/or number of scales) or less resources (with smaller net resolution and/or using the MPI and MPI_4 models). + + + +## Clone and Update the Repository +The first step is to clone the OpenPose repository. It might be done with [GitHub Desktop](https://desktop.github.com/) in Windows and from the terminal in Ubuntu: +```bash +git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose +``` + +OpenPose can be easily updated by clicking the `synchronization` button at the top-right part in GitHub Desktop in Windows, or by running `git pull origin master` in Ubuntu. After OpenPose has been updated, just run the [Reinstallation](#reinstallation) section described below for your specific Operating System. + + + +## Installation +The instructions in this section describe the steps to build OpenPose using CMake (GUI). There are 3 main steps: + +1. [Caffe Prerequisites (Ubuntu Only)](#caffe-prerequisites-ubuntu-only) +2. [OpenPose Configuration](#openpose-configuration) +3. [OpenPose Building](#openpose-building) + + + +### Caffe Prerequisites (Ubuntu Only) +By default, OpenPose uses Caffe under the hood. If you have not used Caffe previously, install its dependencies by running: +```bash +bash ./ubuntu/install_cmake.sh +``` + + + +### OpenPose Configuration +Note: If you prefer to use CMake though the command line, see [Cmake Command Line Build](#cmake-command-line-build). + +1. Install CMake GUI. + 1. Ubuntu: run `sudo apt-get install cmake-qt-gui`. + 2. Windows: download and install the latest Windows win64-x64 msi installer from the [CMake website](https://cmake.org/download/). + +2. Open CMake GUI and select the project source directory and a sub-directory where the Makefiles will +be generated. We will first select the openpose directory and then we will select a `build` directory in the project root directory as shown in the image below (See the red rectangle). If the `build` directory does not exists, CMake will create it. +

+ +

+ +3. Next press the `Configure` button in the GUI. It will first ask you to create the `build` directory, if it already did not exist. Press `Yes`. +

+ +

+ +4. Next a new dialog box will appear, press the `Finish` button here. +

+ +

+ +5. If this step is successful, in the bottom box it will show "Configuring done" (in the last line) as shown below. +

+ +

+ +6. Press the `Generate` button and proceed to [OpenPose Building](#openpose-building). + +Note: If you prefer to use your own custom Caffe or OpenCV versions, see [Custom Caffe](#custom-caffe) or [Custom OpenCV](#custom-opencv) respectively. + + + +### OpenPose Building +Finally, build the project by running the following commands. +``` +cd build/ +no_cores=`cat /proc/cpuinfo | grep processor | wc -l` +make -j${no_cores} +``` + + + +### Run OpenPose +Check OpenPose was properly installed by running it on the default images, video or webcam: [doc/quick_start.md#quick-start](./quick_start.md#quick-start). + + + +## Reinstallation +In order to re-install OpenPose: +1. Delete the `build/` folder. +2. In CMake GUI, click on `File` --> `Delete Cache`. +3. Follow the [Installation](#installation) steps again. + + + +### Optional Settings +#### Custom Caffe +We only modified some Caffe compilation flags and minor details. You can use your own Caffe distribution, simply specify the Caffe include path and the library as shown below. You will also need to turn off the `BUILD_CAFFE` variable. +

+ +

+ + + +#### Custom OpenCV +If you have built OpenCV from source and OpenPose cannot find it automatically, you can set the `OPENCV_DIR` variable to the directory where you build OpenCV. + + + +#### MPI Model +By default, the body MPI model is not downloaded. You can download it by turning on the `DOWNLOAD_MPI_MODEL`. + + + +#### CMake Command Line Configuration +Note that this step is unnecessary if you already used the CMake GUI alternative. + +Create a `build` folder in the root openpose folder, where you will build the library -- +```bash +cd openpose +mkdir build +cd build +``` + +The next step is to generate the Makefiles. Now there can be multiple scenarios based on what the user already has e.x. Caffe might be already installed and the user might be interested in building OpenPose against that version of Caffe instead of requiring OpenPose to build Caffe from scratch. + +##### SCENARIO 1 -- Caffe not installed and OpenCV installed using `apt-get` +In the build directory, run the below command -- +```bash +cmake .. +``` + +##### SCENARIO 2 -- Caffe installed and OpenCV build from source +In this example, we assume that Caffe and OpenCV are already present. The user needs to supply the paths of the library to CMake. For OpenCV, specify the `OpenCV_DIR` which is where the user build OpenCV. For Caffe, specify the include directory and library using the `Caffe_INCLUDE_DIRS` and `Caffe_LIBS` variables. This will be where you installed Caffe. Below is an example of the same. +```bash +cmake -DOpenCV_DIR=/home/"${USER}"/softwares/opencv/build \ + -DCaffe_INCLUDE_DIRS=/home/"${USER}"/softwares/caffe/build/install/include \ + -DCaffe_LIBS=/home/"${USER}"/softwares/caffe/build/install/lib/libcaffe.so -DBUILD_CAFFE=OFF .. +``` + +##### SCENARIO 3 -- OpenCV already installed +If Caffe is not already present but OpenCV is, then use the below command. +```bash +cmake -DOpenCV_DIR=/home/"${USER}"/softwares/opencv/build +``` diff --git a/doc/media/cmake_installation/im_1.png b/doc/media/cmake_installation/im_1.png new file mode 100644 index 0000000000000000000000000000000000000000..66fff4520193d763dc4d142f784714c559920221 Binary files /dev/null and b/doc/media/cmake_installation/im_1.png differ diff --git a/doc/media/cmake_installation/im_2.png b/doc/media/cmake_installation/im_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4299adc9bcac546ff8640754dc8a140250becc07 Binary files /dev/null and b/doc/media/cmake_installation/im_2.png differ diff --git a/doc/media/cmake_installation/im_3.png b/doc/media/cmake_installation/im_3.png new file mode 100644 index 0000000000000000000000000000000000000000..0b5135607a993155a3bfe06b55f724af7701af33 Binary files /dev/null and b/doc/media/cmake_installation/im_3.png differ diff --git a/doc/media/cmake_installation/im_4.png b/doc/media/cmake_installation/im_4.png new file mode 100644 index 0000000000000000000000000000000000000000..447443daaf7103a04647c8c7b696a86f1dfe8098 Binary files /dev/null and b/doc/media/cmake_installation/im_4.png differ diff --git a/doc/media/cmake_installation/im_5.png b/doc/media/cmake_installation/im_5.png new file mode 100644 index 0000000000000000000000000000000000000000..959f19d6ea5cd7e6177a3af69bbf30fecfdbf61f Binary files /dev/null and b/doc/media/cmake_installation/im_5.png differ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3aa49d58b2855f2f25cb2ea298c284c40549486c --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,5 @@ +add_subdirectory(openpose) +add_subdirectory(tutorial_pose) +add_subdirectory(tutorial_thread) +add_subdirectory(tutorial_wrapper) +add_subdirectory(tests) diff --git a/examples/openpose/CMakeLists.txt b/examples/openpose/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2036fe1c53ad51bee2383d11f4a5302d7ed578b1 --- /dev/null +++ b/examples/openpose/CMakeLists.txt @@ -0,0 +1,13 @@ +set(EXAMPLE_FILES + openpose.cpp) + +foreach(EXAMPLE_FILE ${EXAMPLE_FILES}) + + get_filename_component(SOURCE_NAME ${EXAMPLE_FILE} NAME_WE) + message(STATUS "Adding Example ${SOURCE_NAME}") + add_executable(${SOURCE_NAME}.bin ${EXAMPLE_FILE}) + target_link_libraries( ${SOURCE_NAME}.bin + wrapper utilities ${GLOG_LIBRARY} ${GFLAGS_LIBRARY} ${Caffe_LIBS} + ) + +endforeach() \ No newline at end of file diff --git a/examples/tests/CMakeLists.txt b/examples/tests/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..79aa266f45709599c7068bd2412741b7b294cfa5 --- /dev/null +++ b/examples/tests/CMakeLists.txt @@ -0,0 +1,14 @@ +set(EXAMPLE_FILES + handFromJsonTest.cpp) + +foreach(EXAMPLE_FILE ${EXAMPLE_FILES}) + + get_filename_component(SOURCE_NAME ${EXAMPLE_FILE} NAME_WE) + message(STATUS "Adding Example ${SOURCE_NAME}") + add_executable(${SOURCE_NAME}.bin ${EXAMPLE_FILE}) + target_link_libraries( ${SOURCE_NAME}.bin + wrapper utilities ${GLOG_LIBRARY} ${GFLAGS_LIBRARY} ${Caffe_LIBS} + ) + +endforeach() + diff --git a/examples/tutorial_pose/CMakeLists.txt b/examples/tutorial_pose/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..defb47b292b9595521534ecc013f8f897b10a53e --- /dev/null +++ b/examples/tutorial_pose/CMakeLists.txt @@ -0,0 +1,14 @@ +set(EXAMPLE_FILES + 1_extract_from_image.cpp + 2_extract_pose_or_heatmat_from_image.cpp) + +foreach(EXAMPLE_FILE ${EXAMPLE_FILES}) + + get_filename_component(SOURCE_NAME ${EXAMPLE_FILE} NAME_WE) + message(STATUS "Adding Example ${SOURCE_NAME}") + add_executable(${SOURCE_NAME}.bin ${EXAMPLE_FILE}) + target_link_libraries( ${SOURCE_NAME}.bin + wrapper utilities ${GLOG_LIBRARY} ${GFLAGS_LIBRARY} ${Caffe_LIBS} + ) + +endforeach() diff --git a/examples/tutorial_thread/CMakeLists.txt b/examples/tutorial_thread/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..25e537145dcf031895e40357395b8834bb5ddb6e --- /dev/null +++ b/examples/tutorial_thread/CMakeLists.txt @@ -0,0 +1,16 @@ +set(EXAMPLE_FILES + 1_openpose_read_and_display.cpp + 2_user_processing_function.cpp + 3_user_input_processing_and_output.cpp + 4_user_input_processing_output_and_datum.cpp) + +foreach(EXAMPLE_FILE ${EXAMPLE_FILES}) + + get_filename_component(SOURCE_NAME ${EXAMPLE_FILE} NAME_WE) + message(STATUS "Adding Example ${SOURCE_NAME}") + add_executable(${SOURCE_NAME}.bin ${EXAMPLE_FILE}) + target_link_libraries( ${SOURCE_NAME}.bin + wrapper utilities ${GLOG_LIBRARY} ${GFLAGS_LIBRARY} ${Caffe_LIBS} + ) + +endforeach() diff --git a/examples/tutorial_wrapper/CMakeLists.txt b/examples/tutorial_wrapper/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..931c894bc71080ea95dd7a99756ea02c9e775749 --- /dev/null +++ b/examples/tutorial_wrapper/CMakeLists.txt @@ -0,0 +1,14 @@ +set(EXAMPLE_FILES + 1_user_asynchronous.cpp + 2_user_synchronous.cpp) + +foreach(EXAMPLE_FILE ${EXAMPLE_FILES}) + + get_filename_component(SOURCE_NAME ${EXAMPLE_FILE} NAME_WE) + message(STATUS "Adding Example ${SOURCE_NAME}") + add_executable(${SOURCE_NAME}.bin ${EXAMPLE_FILE}) + target_link_libraries( ${SOURCE_NAME}.bin + wrapper utilities ${GLOG_LIBRARY} ${GFLAGS_LIBRARY} ${Caffe_LIBS} + ) + +endforeach() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c59c40b4c883576d1df7b947f86449dbbc85d325 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(openpose) diff --git a/src/openpose/CMakeLists.txt b/src/openpose/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2a4babbe13724e2f635655e62c80226ed7be5dce --- /dev/null +++ b/src/openpose/CMakeLists.txt @@ -0,0 +1,13 @@ +add_subdirectory(core) +add_subdirectory(filestream) +add_subdirectory(gui) +add_subdirectory(pose) +add_subdirectory(utilities) +add_subdirectory(producer) +add_subdirectory(thread) +add_subdirectory(face) +add_subdirectory(hand) +add_subdirectory(wrapper) +set_target_properties(core filestream gui pose utilities producer thread face hand wrapper + PROPERTIES COMPILE_FLAGS ${OP_CXX_FLAGS}) + diff --git a/src/openpose/core/CMakeLists.txt b/src/openpose/core/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..217951fea024965ce5f250d0f469557ee0794215 --- /dev/null +++ b/src/openpose/core/CMakeLists.txt @@ -0,0 +1,26 @@ +cuda_add_library(core + array.cpp + cvMatToOpInput.cpp + cvMatToOpOutput.cpp + datum.cpp + defineTemplates.cpp + keypointScaler.cpp + maximumBase.cpp + maximumBase.cu + maximumCaffe.cpp + netCaffe.cpp + nmsBase.cpp + nmsBase.cu + nmsCaffe.cpp + opOutputToCvMat.cpp + point.cpp + rectangle.cpp + renderer.cpp + resizeAndMergeBase.cpp + resizeAndMergeBase.cu + resizeAndMergeCaffe.cpp) + +target_link_libraries(core ${Caffe_LIBS}) +if (BUILD_CAFFE) + add_dependencies(core caffe) +endif (BUILD_CAFFE) diff --git a/src/openpose/face/CMakeLists.txt b/src/openpose/face/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..54037cdd9fd99518de8dfadfc08f245bdd2aeb3e --- /dev/null +++ b/src/openpose/face/CMakeLists.txt @@ -0,0 +1,13 @@ +set(SOURCES + defineTemplates.cpp + faceDetector.cpp + faceExtractor.cpp + faceRenderer.cpp + renderFace.cpp + renderFace.cu +) + +cuda_add_library(face ${SOURCES}) +if (BUILD_CAFFE) + add_dependencies(face caffe) +endif (BUILD_CAFFE) diff --git a/src/openpose/filestream/CMakeLists.txt b/src/openpose/filestream/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..80ebfe5ad8ebb19bed75d2310f4c41c3598c42dd --- /dev/null +++ b/src/openpose/filestream/CMakeLists.txt @@ -0,0 +1,12 @@ +set(SOURCES cocoJsonSaver.cpp + defineTemplates.cpp + fileSaver.cpp + fileStream.cpp + heatMapSaver.cpp + imageSaver.cpp + jsonOfstream.cpp + keypointJsonSaver.cpp + keypointSaver.cpp + videoSaver.cpp) + +add_library(filestream ${SOURCES}) diff --git a/src/openpose/gui/CMakeLists.txt b/src/openpose/gui/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e1446e0fccc5c08aebca9591b6e7cd7c0d8707a4 --- /dev/null +++ b/src/openpose/gui/CMakeLists.txt @@ -0,0 +1,10 @@ +set(SOURCES + CMakeLists.txt + defineTemplates.cpp + frameDisplayer.cpp + gui.cpp + guiInfoAdder.cpp +) + +add_library(gui ${SOURCES}) +target_link_libraries(gui pose ${OpenCV_LIBS}) diff --git a/src/openpose/hand/CMakeLists.txt b/src/openpose/hand/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..4cdcb4a21062a5209fe4ae913e044b0c1e0182bb --- /dev/null +++ b/src/openpose/hand/CMakeLists.txt @@ -0,0 +1,13 @@ +set(SOURCES + defineTemplates.cpp + handDetector.cpp + handDetectorFromTxt.cpp + handExtractor.cpp + handRenderer.cpp + renderHand.cpp + renderHand.cu) + +cuda_add_library(hand ${SOURCES}) +if (BUILD_CAFFE) + add_dependencies(hand caffe) +endif (BUILD_CAFFE) diff --git a/src/openpose/pose/CMakeLists.txt b/src/openpose/pose/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b1ec9e3c8ed223cb68e54fe70c0aefeaebeae7c3 --- /dev/null +++ b/src/openpose/pose/CMakeLists.txt @@ -0,0 +1,16 @@ +set(SOURCES + bodyPartConnectorBase.cpp + bodyPartConnectorBase.cu + bodyPartConnectorCaffe.cpp + defineTemplates.cpp + poseExtractor.cpp + poseExtractorCaffe.cpp + poseParameters.cpp + poseRenderer.cpp + renderPose.cpp + renderPose.cu) + +cuda_add_library(pose ${SOURCES}) +if (BUILD_CAFFE) + add_dependencies(pose caffe) +endif (BUILD_CAFFE) diff --git a/src/openpose/producer/CMakeLists.txt b/src/openpose/producer/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5ae0a65f97a2373392ac7e139fad0d98bb1a7b15 --- /dev/null +++ b/src/openpose/producer/CMakeLists.txt @@ -0,0 +1,10 @@ +set(SOURCES + defineTemplates.cpp + imageDirectoryReader.cpp + producer.cpp + videoCaptureReader.cpp + videoReader.cpp + webcamReader.cpp) + +add_library(producer ${SOURCES}) +target_link_libraries(producer ${OpenCV_LIBS} core thread filestream) diff --git a/src/openpose/thread/CMakeLists.txt b/src/openpose/thread/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5061dda51da89e4b8ca65940abf8411ca138433e --- /dev/null +++ b/src/openpose/thread/CMakeLists.txt @@ -0,0 +1,4 @@ +set(SOURCES + defineTemplates.cpp) + +add_library(thread ${SOURCES}) diff --git a/src/openpose/utilities/CMakeLists.txt b/src/openpose/utilities/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..87dcfad899f09d2072ccbb9dafd071cf1342ba36 --- /dev/null +++ b/src/openpose/utilities/CMakeLists.txt @@ -0,0 +1,15 @@ +set(SOURCES + cuda.cpp + errorAndLog.cpp + fileSystem.cpp + flagsToOpenPose.cpp + keypoint.cpp + openCv.cpp + profiler.cpp + string.cpp) + +find_package(Boost COMPONENTS system filesystem REQUIRED) + +cuda_add_library(utilities ${SOURCES}) +target_link_libraries(utilities producer filestream + ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY}) diff --git a/src/openpose/wrapper/CMakeLists.txt b/src/openpose/wrapper/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c4dce701002fa741c94521c1a623af496d1e9472 --- /dev/null +++ b/src/openpose/wrapper/CMakeLists.txt @@ -0,0 +1,10 @@ +set(SOURCES + defineTemplates.cpp + wrapperStructFace.cpp + wrapperStructHand.cpp + wrapperStructInput.cpp + wrapperStructOutput.cpp + wrapperStructPose.cpp) + +add_library(wrapper ${SOURCES}) +target_link_libraries(wrapper thread pose hand core face filestream gui producer utilities) diff --git a/ubuntu/install_cmake.sh b/ubuntu/install_cmake.sh new file mode 100755 index 0000000000000000000000000000000000000000..e70e133ba2e062f314e5ae23e77c02331b3e80bb --- /dev/null +++ b/ubuntu/install_cmake.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +### INSTALL PREREQUISITES + +ubuntu_version="$(lsb_release -r)" +sudo apt-get update && sudo apt-get install wget -y --no-install-recommends +if [[ $ubuntu_version == *"14."* ]]; then + wget -c "https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1404-8-0-local-ga2_8.0.61-1_amd64-deb" + sudo dpkg --install cuda-repo-ubuntu1404-8-0-local-ga2_8.0.61-1_amd64-deb +elif [[ $ubuntu_version == *"16."* ]]; then + wget -c "https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb" + sudo dpkg --install cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb +fi +sudo apt-get update +sudo apt-get install cuda + +# Install cuDNN 5.1 +CUDNN_URL="http://developer.download.nvidia.com/compute/redist/cudnn/v5.1/cudnn-8.0-linux-x64-v5.1.tgz" +wget -c ${CUDNN_URL} +sudo tar -xzf cudnn-8.0-linux-x64-v5.1.tgz -C /usr/local +rm cudnn-8.0-linux-x64-v5.1.tgz && sudo ldconfig + +# Basic +sudo apt-get --assume-yes update +sudo apt-get --assume-yes install build-essential +# General dependencies +sudo apt-get --assume-yes install libprotobuf-dev libleveldb-dev libsnappy-dev libhdf5-serial-dev protobuf-compiler +sudo apt-get --assume-yes install --no-install-recommends libboost-all-dev +# Remaining dependencies, 14.04 +sudo apt-get --assume-yes install libgflags-dev libgoogle-glog-dev liblmdb-dev +# Python libs +sudo -H pip install --upgrade numpy protobuf +# OpenCV 2.4 -> Added as option +# sudo apt-get --assume-yes install libopencv-dev diff --git a/ubuntu/install_cuda.sh b/ubuntu/install_cuda.sh new file mode 100755 index 0000000000000000000000000000000000000000..3b0dc6723e17e0fdff291f51f9f2435d194f3b55 --- /dev/null +++ b/ubuntu/install_cuda.sh @@ -0,0 +1,11 @@ +ubuntu_version="$(lsb_release -r)" +sudo apt-get update && sudo apt-get install wget -y --no-install-recommends +if [[ $ubuntu_version == *"14."* ]]; then + wget -c "https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1404-8-0-local-ga2_8.0.61-1_amd64-deb" + sudo dpkg --install cuda-repo-ubuntu1404-8-0-local-ga2_8.0.61-1_amd64-deb +elif [[ $ubuntu_version == *"16."* ]]; then + wget -c "https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb" + sudo dpkg --install cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb +fi +sudo apt-get update +sudo apt-get install cuda diff --git a/ubuntu/install_cudnn.sh b/ubuntu/install_cudnn.sh new file mode 100755 index 0000000000000000000000000000000000000000..ea379492f5ac53d1cf773b66727b835d59630834 --- /dev/null +++ b/ubuntu/install_cudnn.sh @@ -0,0 +1,6 @@ +# Install cuDNN 5.1 +ubuntu_version="$(lsb_release -r)" +CUDNN_URL="http://developer.download.nvidia.com/compute/redist/cudnn/v5.1/cudnn-8.0-linux-x64-v5.1.tgz" +wget -c ${CUDNN_URL} +sudo tar -xzf cudnn-8.0-linux-x64-v5.1.tgz -C /usr/local +rm cudnn-8.0-linux-x64-v5.1.tgz && sudo ldconfig