merged catkin build into master branch
This commit is contained in:
parent
a4ef95a3bf
commit
84cf6280ac
451
CMakeLists.txt
451
CMakeLists.txt
@ -1,87 +1,33 @@
|
|||||||
# Top-Level CmakeLists.txt
|
cmake_minimum_required(VERSION 2.8.3)
|
||||||
cmake_minimum_required(VERSION 2.8.2)
|
|
||||||
PROJECT( Find-Object )
|
|
||||||
SET(PROJECT_PREFIX find_object)
|
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DPROJECT_PREFIX="${PROJECT_PREFIX}")
|
IF(NOT CATKIN_BUILD)
|
||||||
ADD_DEFINITIONS(-DPROJECT_NAME="${PROJECT_NAME}")
|
#Standalone build
|
||||||
IF(WIN32 AND NOT MINGW)
|
PROJECT( Find-Object )
|
||||||
ADD_DEFINITIONS("-wd4251")
|
ELSE()
|
||||||
ELSE ()
|
#Standalone build
|
||||||
ADD_DEFINITIONS( "-Wall" )
|
PROJECT( find_object_2d )
|
||||||
ENDIF()
|
ENDIF()
|
||||||
#ADD_DEFINITIONS("-DUNICODE") # to test with UNICODE projects
|
|
||||||
|
|
||||||
####### local cmake modules #######
|
OPTION(CATKIN_BUILD "Set to ON to build in a Catkin workspace (ROS)" OFF)
|
||||||
SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
|
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
# VERSION
|
# VERSION
|
||||||
#######################
|
#######################
|
||||||
SET(PROJECT_VERSION "0.5.1")
|
SET(PROJECT_VERSION “0.5.1”)
|
||||||
ADD_DEFINITIONS(-DPROJECT_VERSION="${PROJECT_VERSION}")
|
SET(PROJECT_PREFIX find_object)
|
||||||
|
|
||||||
STRING(REGEX MATCHALL "[0-9]" PROJECT_VERSION_PARTS "${PROJECT_VERSION}")
|
STRING(REGEX MATCHALL "[0-9]" PROJECT_VERSION_PARTS "${PROJECT_VERSION}")
|
||||||
|
|
||||||
LIST(GET PROJECT_VERSION_PARTS 0 PROJECT_VERSION_MAJOR)
|
LIST(GET PROJECT_VERSION_PARTS 0 PROJECT_VERSION_MAJOR)
|
||||||
LIST(GET PROJECT_VERSION_PARTS 1 PROJECT_VERSION_MINOR)
|
LIST(GET PROJECT_VERSION_PARTS 1 PROJECT_VERSION_MINOR)
|
||||||
LIST(GET PROJECT_VERSION_PARTS 2 PROJECT_VERSION_PATCH)
|
LIST(GET PROJECT_VERSION_PARTS 2 PROJECT_VERSION_PATCH)
|
||||||
|
|
||||||
SET(PROJECT_SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
ADD_DEFINITIONS(-DPROJECT_PREFIX="${PROJECT_PREFIX}")
|
||||||
|
ADD_DEFINITIONS(-DPROJECT_VERSION="${PROJECT_VERSION}")
|
||||||
####### COMPILATION PARAMS #######
|
ADD_DEFINITIONS(-DPROJECT_NAME="${PROJECT_NAME}")
|
||||||
# In case of Makefiles if the user does not setup CMAKE_BUILD_TYPE, assume it's Release:
|
|
||||||
IF(${CMAKE_GENERATOR} MATCHES ".*Makefiles")
|
|
||||||
IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
|
||||||
ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
|
||||||
ENDIF(${CMAKE_GENERATOR} MATCHES ".*Makefiles")
|
|
||||||
|
|
||||||
SET(CMAKE_DEBUG_POSTFIX "d")
|
|
||||||
|
|
||||||
####### Build libraries as shared or static #######
|
|
||||||
OPTION( BUILD_SHARED_LIBS "Set to OFF to build static libraries" ON )
|
|
||||||
|
|
||||||
####### SET RPATH #########
|
|
||||||
# When RPATH is activated (supported on most UNIX systems),
|
|
||||||
# the user doesn't need to change LD_LIBRARY_PATH
|
|
||||||
|
|
||||||
# use, i.e. don't skip the full RPATH for the build tree
|
|
||||||
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
|
|
||||||
|
|
||||||
# when building, don't use the install RPATH already
|
|
||||||
# (but later on when installing)
|
|
||||||
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
|
||||||
|
|
||||||
# the RPATH to be used when installing
|
|
||||||
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/${PROJECT_PREFIX}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
|
||||||
|
|
||||||
# add the automatically determined parts of the RPATH
|
|
||||||
# which point to directories outside the build tree to the install RPATH
|
|
||||||
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
|
||||||
|
|
||||||
####### OUTPUT DIR #######
|
|
||||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
|
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
|
|
||||||
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
|
|
||||||
|
|
||||||
####### INSTALL DIR #######
|
|
||||||
# Offer the user the choice of overriding the installation directories
|
|
||||||
set(INSTALL_LIB_DIR lib/${PROJECT_PREFIX}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} CACHE PATH "Installation directory for libraries")
|
|
||||||
set(INSTALL_BIN_DIR bin CACHE PATH "Installation directory for executables")
|
|
||||||
set(INSTALL_INCLUDE_DIR include/${PROJECT_PREFIX}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} CACHE PATH
|
|
||||||
"Installation directory for header files")
|
|
||||||
if(WIN32 AND NOT CYGWIN)
|
|
||||||
set(DEF_INSTALL_CMAKE_DIR CMake)
|
|
||||||
else()
|
|
||||||
set(DEF_INSTALL_CMAKE_DIR lib/${PROJECT_PREFIX}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR})
|
|
||||||
endif()
|
|
||||||
set(INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH
|
|
||||||
"Installation directory for CMake files")
|
|
||||||
|
|
||||||
####### DEPENDENCIES #######
|
####### DEPENDENCIES #######
|
||||||
FIND_PACKAGE(OpenCV REQUIRED) # tested on 2.3.1
|
FIND_PACKAGE(OpenCV REQUIRED) # tested on 2.3.1
|
||||||
FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED) # tested on Qt4.8
|
FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED)
|
||||||
ADD_DEFINITIONS(-DQT_NO_KEYWORDS) # To avoid conflicts with boost signals used in ROS
|
ADD_DEFINITIONS(-DQT_NO_KEYWORDS) # To avoid conflicts with boost signals used in ROS
|
||||||
|
|
||||||
IF(OPENCV_NONFREE_FOUND)
|
IF(OPENCV_NONFREE_FOUND)
|
||||||
@ -91,146 +37,271 @@ ELSE()
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
CONFIGURE_FILE(Version.h.in ${PROJECT_SOURCE_DIR}/include/${PROJECT_PREFIX}/Version.h)
|
CONFIGURE_FILE(Version.h.in ${PROJECT_SOURCE_DIR}/include/${PROJECT_PREFIX}/Version.h)
|
||||||
|
|
||||||
####### OSX BUNDLE CMAKE_INSTALL_PREFIX #######
|
IF(NOT CATKIN_BUILD)
|
||||||
IF(APPLE)
|
#Standalone build
|
||||||
OPTION(BUILD_AS_BUNDLE "Set to ON to build as bundle (DragNDrop)" OFF)
|
IF(WIN32 AND NOT MINGW)
|
||||||
ENDIF(APPLE)
|
ADD_DEFINITIONS("-wd4251")
|
||||||
IF(APPLE AND BUILD_AS_BUNDLE)
|
ELSE ()
|
||||||
# Required when packaging, and set CMAKE_INSTALL_PREFIX to "/".
|
ADD_DEFINITIONS( "-Wall" )
|
||||||
SET(CPACK_SET_DESTDIR TRUE)
|
ENDIF()
|
||||||
|
#ADD_DEFINITIONS("-DUNICODE") # to test with UNICODE projects
|
||||||
|
|
||||||
SET(CMAKE_BUNDLE_NAME
|
####### COMPILATION PARAMS #######
|
||||||
"${PROJECT_NAME}")
|
# In case of Makefiles if the user does not setup CMAKE_BUILD_TYPE, assume it's Release:
|
||||||
SET(CMAKE_BUNDLE_LOCATION "/")
|
IF(${CMAKE_GENERATOR} MATCHES ".*Makefiles")
|
||||||
|
IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||||
|
set(CMAKE_BUILD_TYPE Release)
|
||||||
|
ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||||
|
ENDIF(${CMAKE_GENERATOR} MATCHES ".*Makefiles")
|
||||||
|
|
||||||
# make sure CMAKE_INSTALL_PREFIX ends in /
|
SET(CMAKE_DEBUG_POSTFIX "d")
|
||||||
SET(CMAKE_INSTALL_PREFIX
|
|
||||||
"/${CMAKE_BUNDLE_NAME}.app/Contents")
|
|
||||||
ENDIF(APPLE AND BUILD_AS_BUNDLE)
|
|
||||||
|
|
||||||
####### SOURCES (Projects) #######
|
####### Build libraries as shared or static #######
|
||||||
ADD_SUBDIRECTORY( src )
|
OPTION( BUILD_SHARED_LIBS "Set to OFF to build static libraries" ON )
|
||||||
ADD_SUBDIRECTORY( app )
|
|
||||||
ADD_SUBDIRECTORY( example )
|
####### SET RPATH #########
|
||||||
ADD_SUBDIRECTORY( tools )
|
# When RPATH is activated (supported on most UNIX systems),
|
||||||
|
# the user doesn't need to change LD_LIBRARY_PATH
|
||||||
|
|
||||||
|
# use, i.e. don't skip the full RPATH for the build tree
|
||||||
|
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||||
|
|
||||||
|
# when building, don't use the install RPATH already
|
||||||
|
# (but later on when installing)
|
||||||
|
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||||
|
|
||||||
|
# the RPATH to be used when installing
|
||||||
|
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/${PROJECT_PREFIX}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
||||||
|
|
||||||
|
# add the automatically determined parts of the RPATH
|
||||||
|
# which point to directories outside the build tree to the install RPATH
|
||||||
|
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
|
|
||||||
|
####### OUTPUT DIR #######
|
||||||
|
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
|
||||||
|
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
|
||||||
|
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
|
||||||
|
|
||||||
|
####### INSTALL DIR #######
|
||||||
|
# Offer the user the choice of overriding the installation directories
|
||||||
|
set(INSTALL_LIB_DIR lib/${PROJECT_PREFIX}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} CACHE PATH "Installation directory for libraries")
|
||||||
|
set(INSTALL_BIN_DIR bin CACHE PATH "Installation directory for executables")
|
||||||
|
set(INSTALL_INCLUDE_DIR include/${PROJECT_PREFIX}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} CACHE PATH
|
||||||
|
"Installation directory for header files")
|
||||||
|
if(WIN32 AND NOT CYGWIN)
|
||||||
|
set(DEF_INSTALL_CMAKE_DIR CMake)
|
||||||
|
else()
|
||||||
|
set(DEF_INSTALL_CMAKE_DIR lib/${PROJECT_PREFIX}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR})
|
||||||
|
endif()
|
||||||
|
set(INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH
|
||||||
|
"Installation directory for CMake files")
|
||||||
|
|
||||||
|
|
||||||
|
####### OSX BUNDLE CMAKE_INSTALL_PREFIX #######
|
||||||
|
IF(APPLE)
|
||||||
|
OPTION(BUILD_AS_BUNDLE "Set to ON to build as bundle (DragNDrop)" OFF)
|
||||||
|
ENDIF(APPLE)
|
||||||
|
IF(APPLE AND BUILD_AS_BUNDLE)
|
||||||
|
# Required when packaging, and set CMAKE_INSTALL_PREFIX to "/".
|
||||||
|
SET(CPACK_SET_DESTDIR TRUE)
|
||||||
|
|
||||||
#######################
|
SET(CMAKE_BUNDLE_NAME
|
||||||
# Uninstall target, for "make uninstall"
|
"${PROJECT_NAME}")
|
||||||
#######################
|
SET(CMAKE_BUNDLE_LOCATION "/")
|
||||||
CONFIGURE_FILE(
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
|
||||||
IMMEDIATE @ONLY)
|
|
||||||
|
|
||||||
ADD_CUSTOM_TARGET(uninstall
|
# make sure CMAKE_INSTALL_PREFIX ends in /
|
||||||
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
SET(CMAKE_INSTALL_PREFIX
|
||||||
|
"/${CMAKE_BUNDLE_NAME}.app/Contents")
|
||||||
|
ENDIF(APPLE AND BUILD_AS_BUNDLE)
|
||||||
|
|
||||||
#######################
|
####### SOURCES (Projects) #######
|
||||||
# Setup FindObjectConfig.cmake
|
ADD_SUBDIRECTORY( src )
|
||||||
#######################
|
ADD_SUBDIRECTORY( app )
|
||||||
# Create the FindObjectConfig.cmake and FindObjectConfigVersion files
|
ADD_SUBDIRECTORY( tools )
|
||||||
file(RELATIVE_PATH REL_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}" "${CMAKE_INSTALL_PREFIX}/${INSTALL_INCLUDE_DIR}")
|
IF(NONFREE)
|
||||||
file(RELATIVE_PATH REL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}" "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR}")
|
ADD_SUBDIRECTORY( example )
|
||||||
|
ENDIF(NONFREE)
|
||||||
|
|
||||||
# ... for the build tree
|
#######################
|
||||||
set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include")
|
# Uninstall target, for "make uninstall"
|
||||||
set(CONF_LIB_DIR "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}")
|
#######################
|
||||||
configure_file(FindObjectConfig.cmake.in
|
CONFIGURE_FILE(
|
||||||
"${PROJECT_BINARY_DIR}/FindObjectConfig.cmake" @ONLY)
|
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||||
|
IMMEDIATE @ONLY)
|
||||||
|
|
||||||
# ... for the install tree
|
ADD_CUSTOM_TARGET(uninstall
|
||||||
set(CONF_INCLUDE_DIRS "\${FindObject_CMAKE_DIR}/${REL_INCLUDE_DIR}")
|
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||||
set(CONF_LIB_DIR "\${FindObject_CMAKE_DIR}/${REL_LIB_DIR}")
|
|
||||||
configure_file(FindObjectConfig.cmake.in
|
|
||||||
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindObjectConfig.cmake" @ONLY)
|
|
||||||
|
|
||||||
# ... for both
|
#######################
|
||||||
configure_file(FindObjectConfigVersion.cmake.in
|
# Setup FindObjectConfig.cmake
|
||||||
"${PROJECT_BINARY_DIR}/FindObjectConfigVersion.cmake" @ONLY)
|
#######################
|
||||||
|
# Create the FindObjectConfig.cmake and FindObjectConfigVersion files
|
||||||
|
file(RELATIVE_PATH REL_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}" "${CMAKE_INSTALL_PREFIX}/${INSTALL_INCLUDE_DIR}")
|
||||||
|
file(RELATIVE_PATH REL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}" "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR}")
|
||||||
|
|
||||||
# Install the FindObjectConfig.cmake and FindObjectConfigVersion.cmake
|
# ... for the build tree
|
||||||
install(FILES
|
set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include")
|
||||||
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindObjectConfig.cmake"
|
set(CONF_LIB_DIR "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}")
|
||||||
"${PROJECT_BINARY_DIR}/FindObjectConfigVersion.cmake"
|
configure_file(FindObjectConfig.cmake.in
|
||||||
DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT devel)
|
"${PROJECT_BINARY_DIR}/FindObjectConfig.cmake" @ONLY)
|
||||||
####
|
|
||||||
|
|
||||||
#######################
|
# ... for the install tree
|
||||||
# CPACK (Packaging)
|
set(CONF_INCLUDE_DIRS "\${FindObject_CMAKE_DIR}/${REL_INCLUDE_DIR}")
|
||||||
#######################
|
set(CONF_LIB_DIR "\${FindObject_CMAKE_DIR}/${REL_LIB_DIR}")
|
||||||
INCLUDE(InstallRequiredSystemLibraries)
|
configure_file(FindObjectConfig.cmake.in
|
||||||
|
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindObjectConfig.cmake" @ONLY)
|
||||||
|
|
||||||
SET(CPACK_PACKAGE_NAME "${PROJECT_NAME}")
|
# ... for both
|
||||||
SET(CPACK_PACKAGE_VENDOR "${PROJECT_NAME} project")
|
configure_file(FindObjectConfigVersion.cmake.in
|
||||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Find-Object")
|
"${PROJECT_BINARY_DIR}/FindObjectConfigVersion.cmake" @ONLY)
|
||||||
SET(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
|
||||||
SET(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
|
||||||
SET(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
|
|
||||||
SET(CPACK_PACKAGE_CONTACT "matlabbe@gmail.com")
|
|
||||||
|
|
||||||
set(CPACK_SOURCE_IGNORE_FILES
|
# Install the FindObjectConfig.cmake and FindObjectConfigVersion.cmake
|
||||||
"\\\\.svn/"
|
install(FILES
|
||||||
"${PROJECT_SOURCE_DIR}/build/[a-zA-Z0-9_]+"
|
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindObjectConfig.cmake"
|
||||||
"~$"
|
"${PROJECT_BINARY_DIR}/FindObjectConfigVersion.cmake"
|
||||||
"${PROJECT_SOURCE_DIR}/bin/.*${PROJECT_PREFIX}"
|
DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT devel)
|
||||||
"${PROJECT_SOURCE_DIR}/bin/.*${PROJECT_NAME}"
|
####
|
||||||
"\\\\.DS_Store"
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(WIN32)
|
#######################
|
||||||
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
# CPACK (Packaging)
|
||||||
IF(CMAKE_CL_64)
|
#######################
|
||||||
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
|
INCLUDE(InstallRequiredSystemLibraries)
|
||||||
ELSE()
|
|
||||||
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
|
|
||||||
ENDIF()
|
|
||||||
SET(CPACK_GENERATOR "ZIP;NSIS")
|
|
||||||
SET(CPACK_SOURCE_GENERATOR "ZIP")
|
|
||||||
SET(CPACK_NSIS_PACKAGE_NAME "${PROJECT_NAME}")
|
|
||||||
SET(ICON_PATH "${PROJECT_SOURCE_DIR}/app/${PROJECT_NAME}.ico")
|
|
||||||
SET(CPACK_NSIS_MUI_ICON ${ICON_PATH})
|
|
||||||
SET(CPACK_NSIS_MUI_UNIICON ${ICON_PATH})
|
|
||||||
SET(CPACK_NSIS_DISPLAY_NAME "${PROJECT_NAME}")
|
|
||||||
SET(CPACK_NSIS_CONTACT ${CPACK_PACKAGE_CONTACT})
|
|
||||||
# Set the icon used for the Windows "Add or Remove Programs" tool.
|
|
||||||
SET(CPACK_NSIS_INSTALLED_ICON_NAME bin\\\\${PROJECT_NAME}.exe)
|
|
||||||
SET(CPACK_PACKAGE_EXECUTABLES "${PROJECT_NAME}" "${PROJECT_NAME}" ${CPACK_PACKAGE_EXECUTABLES})
|
|
||||||
SET(CPACK_CREATE_DESKTOP_LINKS "${PROJECT_NAME}" ${CPACK_CREATE_DESKTOP_LINKS})
|
|
||||||
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}")
|
|
||||||
ELSEIF(APPLE)
|
|
||||||
IF(BUILD_AS_BUNDLE)
|
|
||||||
# On APPLE and if BUILD_AS_BUNDLE=ON, the project is created as a bundle
|
|
||||||
# over the main app (see ./src).Here we package only this bundle. Note
|
|
||||||
# that we set CMAKE_INSTALL_PREFIX to "/" when packaging to DragNDrop...
|
|
||||||
SET(CPACK_GENERATOR "DragNDrop")
|
|
||||||
ELSE()
|
|
||||||
SET(CPACK_GENERATOR "PackageMaker;TBZ2")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
SET(CPACK_SOURCE_GENERATOR "TBZ2")
|
SET(CPACK_PACKAGE_NAME "${PROJECT_NAME}")
|
||||||
|
SET(CPACK_PACKAGE_VENDOR "${PROJECT_NAME} project")
|
||||||
|
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Find-Object")
|
||||||
|
SET(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
||||||
|
SET(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
||||||
|
SET(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
|
||||||
|
SET(CPACK_PACKAGE_CONTACT "matlabbe@gmail.com")
|
||||||
|
|
||||||
|
set(CPACK_SOURCE_IGNORE_FILES
|
||||||
|
"\\\\.svn/"
|
||||||
|
"${PROJECT_SOURCE_DIR}/build/[a-zA-Z0-9_]+"
|
||||||
|
"~$"
|
||||||
|
"${PROJECT_SOURCE_DIR}/bin/.*${PROJECT_PREFIX}"
|
||||||
|
"${PROJECT_SOURCE_DIR}/bin/.*${PROJECT_NAME}"
|
||||||
|
"\\\\.DS_Store"
|
||||||
|
)
|
||||||
|
|
||||||
|
IF(WIN32)
|
||||||
|
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
||||||
|
IF(CMAKE_CL_64)
|
||||||
|
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
|
||||||
|
ELSE()
|
||||||
|
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
|
||||||
|
ENDIF()
|
||||||
|
SET(CPACK_GENERATOR "ZIP;NSIS")
|
||||||
|
SET(CPACK_SOURCE_GENERATOR "ZIP")
|
||||||
|
SET(CPACK_NSIS_PACKAGE_NAME "${PROJECT_NAME}")
|
||||||
|
SET(ICON_PATH "${PROJECT_SOURCE_DIR}/app/${PROJECT_NAME}.ico")
|
||||||
|
SET(CPACK_NSIS_MUI_ICON ${ICON_PATH})
|
||||||
|
SET(CPACK_NSIS_MUI_UNIICON ${ICON_PATH})
|
||||||
|
SET(CPACK_NSIS_DISPLAY_NAME "${PROJECT_NAME}")
|
||||||
|
SET(CPACK_NSIS_CONTACT ${CPACK_PACKAGE_CONTACT})
|
||||||
|
# Set the icon used for the Windows "Add or Remove Programs" tool.
|
||||||
|
SET(CPACK_NSIS_INSTALLED_ICON_NAME bin\\\\${PROJECT_NAME}.exe)
|
||||||
|
SET(CPACK_PACKAGE_EXECUTABLES "${PROJECT_NAME}" "${PROJECT_NAME}" ${CPACK_PACKAGE_EXECUTABLES})
|
||||||
|
SET(CPACK_CREATE_DESKTOP_LINKS "${PROJECT_NAME}" ${CPACK_CREATE_DESKTOP_LINKS})
|
||||||
|
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}")
|
||||||
|
ELSEIF(APPLE)
|
||||||
|
IF(BUILD_AS_BUNDLE)
|
||||||
|
# On APPLE and if BUILD_AS_BUNDLE=ON, the project is created as a bundle
|
||||||
|
# over the main app (see ./src).Here we package only this bundle. Note
|
||||||
|
# that we set CMAKE_INSTALL_PREFIX to "/" when packaging to DragNDrop...
|
||||||
|
SET(CPACK_GENERATOR "DragNDrop")
|
||||||
|
ELSE()
|
||||||
|
SET(CPACK_GENERATOR "PackageMaker;TBZ2")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
SET(CPACK_SOURCE_GENERATOR "TBZ2")
|
||||||
|
|
||||||
|
SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/app/${PROJECT_NAME}.icns")
|
||||||
|
ELSE()
|
||||||
|
SET(CPACK_SOURCE_GENERATOR "ZIP")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
INCLUDE(CPack)
|
||||||
|
|
||||||
|
#######################
|
||||||
|
# OUTPUT INFO
|
||||||
|
#######################
|
||||||
|
MESSAGE(STATUS "--------------------------------------------")
|
||||||
|
MESSAGE(STATUS "Info :")
|
||||||
|
MESSAGE(STATUS " CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}")
|
||||||
|
MESSAGE(STATUS " CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
|
||||||
|
IF(OPENCV_NONFREE_FOUND)
|
||||||
|
MESSAGE(STATUS " With OpenCV nonfree module (SIFT/SURF) = YES")
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(STATUS " With OpenCV nonfree module (SIFT/SURF) = NO (not found)")
|
||||||
|
ENDIF()
|
||||||
|
IF(APPLE)
|
||||||
|
MESSAGE(STATUS " BUILD_AS_BUNDLE = ${BUILD_AS_BUNDLE}")
|
||||||
|
ENDIF(APPLE)
|
||||||
|
MESSAGE(STATUS "--------------------------------------------")
|
||||||
|
|
||||||
SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/app/${PROJECT_NAME}.icns")
|
|
||||||
ELSE()
|
ELSE()
|
||||||
SET(CPACK_SOURCE_GENERATOR "ZIP")
|
#ROS Catkin build
|
||||||
|
|
||||||
|
## Find catkin macros and libraries
|
||||||
|
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
|
||||||
|
## is used, also find other catkin packages
|
||||||
|
find_package(catkin REQUIRED COMPONENTS
|
||||||
|
cv_bridge roscpp rospy sensor_msgs std_msgs image_transport genmsg message_filters pcl_ros tf
|
||||||
|
)
|
||||||
|
|
||||||
|
## Generate messages in the 'msg' folder
|
||||||
|
add_message_files(
|
||||||
|
FILES
|
||||||
|
ObjectsStamped.msg
|
||||||
|
)
|
||||||
|
|
||||||
|
## Generate added messages and services with any dependencies listed here
|
||||||
|
generate_messages(
|
||||||
|
DEPENDENCIES
|
||||||
|
std_msgs
|
||||||
|
sensor_msgs
|
||||||
|
)
|
||||||
|
|
||||||
|
###################################
|
||||||
|
## catkin specific configuration ##
|
||||||
|
###################################
|
||||||
|
## The catkin_package macro generates cmake config files for your package
|
||||||
|
## Declare things to be passed to dependent projects
|
||||||
|
## INCLUDE_DIRS: uncomment this if you package contains header files
|
||||||
|
## LIBRARIES: libraries you create in this project that dependent projects also need
|
||||||
|
## CATKIN_DEPENDS: catkin_packages dependent projects also need
|
||||||
|
## DEPENDS: system dependencies of this project that dependent projects also need
|
||||||
|
catkin_package(
|
||||||
|
CATKIN_DEPENDS cv_bridge roscpp rospy sensor_msgs std_msgs image_transport message_filters pcl_ros tf
|
||||||
|
)
|
||||||
|
|
||||||
|
###########
|
||||||
|
## Build ##
|
||||||
|
###########
|
||||||
|
ADD_SUBDIRECTORY( src )
|
||||||
|
|
||||||
|
#############
|
||||||
|
## Install ##
|
||||||
|
#############
|
||||||
|
## Mark executables and/or libraries for installation
|
||||||
|
install(TARGETS
|
||||||
|
find_object
|
||||||
|
find_object_2d
|
||||||
|
print_objects_detected
|
||||||
|
tf_example
|
||||||
|
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||||
|
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||||
|
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||||
|
)
|
||||||
|
|
||||||
|
## Mark other files for installation (e.g. launch and bag files, etc.)
|
||||||
|
install(FILES
|
||||||
|
launch/find_object_2d_gui.launch
|
||||||
|
launch/find_object_2d.launch
|
||||||
|
launch/find_object_3d.launch
|
||||||
|
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
|
||||||
|
)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
INCLUDE(CPack)
|
|
||||||
|
|
||||||
#######################
|
|
||||||
# OUTPUT INFO
|
|
||||||
#######################
|
|
||||||
MESSAGE(STATUS "--------------------------------------------")
|
|
||||||
MESSAGE(STATUS "Info :")
|
|
||||||
MESSAGE(STATUS " CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}")
|
|
||||||
MESSAGE(STATUS " CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
|
|
||||||
IF(OPENCV_NONFREE_FOUND)
|
|
||||||
MESSAGE(STATUS " With OpenCV nonfree module (SIFT/SURF) = YES")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS " With OpenCV nonfree module (SIFT/SURF) = NO (not found)")
|
|
||||||
ENDIF()
|
|
||||||
IF(APPLE)
|
|
||||||
MESSAGE(STATUS " BUILD_AS_BUNDLE = ${BUILD_AS_BUNDLE}")
|
|
||||||
ENDIF(APPLE)
|
|
||||||
MESSAGE(STATUS "--------------------------------------------")
|
|
||||||
|
|||||||
27
README.md
27
README.md
@ -1,2 +1,25 @@
|
|||||||
# find-object
|
## find-object (standalone)
|
||||||
Find-Object project, visit the [home page](http://introlab.github.io/find-object/) for more information. For the ROS package, select the find_object_2d branch.
|
Find-Object project, visit the [home page](http://introlab.github.io/find-object/) for more information.
|
||||||
|
|
||||||
|
## find_object_2d (ROS package)
|
||||||
|
|
||||||
|
### Install
|
||||||
|
```bash
|
||||||
|
# Install ROS Groovy/Hydro/Indigo/Jade (catkin build):
|
||||||
|
$ cd ~/catkin_ws
|
||||||
|
$ git clone -b find_object_2d https://github.com/introlab/find-object.git src/find_object_2d
|
||||||
|
$ catkin_make
|
||||||
|
|
||||||
|
# Install ROS Fuerte (in a directory of your "ROS_PACKAGE_PATH"):
|
||||||
|
$ svn checkout -r176 http://find-object.googlecode.com/svn/trunk/ros-pkg/find_object_2d
|
||||||
|
$ rosmake find_object_2d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run
|
||||||
|
```bash
|
||||||
|
$ roscore &
|
||||||
|
# Launch your preferred ubs camera driver
|
||||||
|
$ rosrun uvc_camera uvc_camera_node &
|
||||||
|
$ rosrun find_object_2d find_object_2d image:=image_raw
|
||||||
|
```
|
||||||
|
See [find_object_2d](http://wiki.ros.org/find_object_2d) for more information.
|
||||||
|
|||||||
9
launch/find_object_2d.launch
Normal file
9
launch/find_object_2d.launch
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<launch>
|
||||||
|
<!-- Nodes -->
|
||||||
|
<node name="find_object_2d" pkg="find_object_2d" type="find_object_2d" output="screen">
|
||||||
|
<remap from="image" to="image"/>
|
||||||
|
<param name="gui" value="false" type="bool"/>
|
||||||
|
<param name="objects_path" value="~/objects" type="str"/>
|
||||||
|
<param name="settings_path" value="~/.ros/find_object_2d.ini" type="str"/>
|
||||||
|
</node>
|
||||||
|
</launch>
|
||||||
9
launch/find_object_2d_gui.launch
Normal file
9
launch/find_object_2d_gui.launch
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<launch>
|
||||||
|
<!-- Nodes -->
|
||||||
|
<node name="find_object_2d" pkg="find_object_2d" type="find_object_2d" output="screen">
|
||||||
|
<remap from="image" to="image"/>
|
||||||
|
<param name="gui" value="true" type="bool"/>
|
||||||
|
<param name="objects_path" value="~/objects" type="str"/>
|
||||||
|
<param name="settings_path" value="~/.ros/find_object_2d.ini" type="str"/>
|
||||||
|
</node>
|
||||||
|
</launch>
|
||||||
29
launch/find_object_3d.launch
Normal file
29
launch/find_object_3d.launch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<launch>
|
||||||
|
<!-- Example finding 3D poses of the objects detected -->
|
||||||
|
<!-- $roslaunch openni_launch openni.launch depth_registration:=true -->
|
||||||
|
|
||||||
|
<node name="find_object_3d" pkg="find_object_2d" type="find_object_2d" output="screen">
|
||||||
|
<param name="gui" value="true" type="bool"/>
|
||||||
|
<param name="settings_path" value="~/.ros/find_object_2d.ini" type="str"/>
|
||||||
|
<param name="subscribe_depth" value="true" type="bool"/>
|
||||||
|
<param name="objects_path" value="" type="str"/>
|
||||||
|
<param name="object_prefix" value="object" type="str"/>
|
||||||
|
|
||||||
|
<remap from="rgb/image_rect_color" to="camera/rgb/image_rect_color"/>
|
||||||
|
<remap from="depth_registered/image_raw" to="camera/depth_registered/image_raw"/>
|
||||||
|
<remap from="depth_registered/camera_info" to="camera/depth_registered/camera_info"/>
|
||||||
|
</node>
|
||||||
|
|
||||||
|
<!-- Example of tf synchronisation with the objectsStamped message -->
|
||||||
|
<node name="tf_example" pkg="find_object_2d" type="tf_example" output="screen">
|
||||||
|
<param name="map_frame_id" value="/map" type="string"/>
|
||||||
|
<param name="object_prefix" value="object" type="str"/>
|
||||||
|
</node>
|
||||||
|
<!-- fake some tf frames for the example /map -> /odom -> /base_link -> /camera_link -->
|
||||||
|
<node pkg="tf" type="static_transform_publisher" name="base_to_camera_tf"
|
||||||
|
args="0.1 0.0 0.3 0.0 0.0 0.0 /base_link /camera_link 100" />
|
||||||
|
<node pkg="tf" type="static_transform_publisher" name="odom_to_base_tf"
|
||||||
|
args="1.0 0.0 0.1 1.5707 0.0 0.0 /odom /base_link 100" />
|
||||||
|
<node pkg="tf" type="static_transform_publisher" name="map_to_odom_tf"
|
||||||
|
args="0.0 0.5 0.0 0.7853 0.0 0.0 /map /odom 100" />
|
||||||
|
</launch>
|
||||||
5
msg/ObjectsStamped.msg
Normal file
5
msg/ObjectsStamped.msg
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# objects format:
|
||||||
|
# [ObjectId1, objectWidth, objectHeight, h11, h12, h13, h21, h22, h23, h31, h32, h33, ObjectId2...]
|
||||||
|
# where h## is a 3x3 homography matrix (h31 = dx and h32 = dy, see QTransform)
|
||||||
|
Header header
|
||||||
|
std_msgs/Float32MultiArray objects
|
||||||
@ -2,29 +2,36 @@
|
|||||||
|
|
||||||
### Qt Gui stuff ###
|
### Qt Gui stuff ###
|
||||||
SET(headers_ui
|
SET(headers_ui
|
||||||
../include/${PROJECT_PREFIX}/MainWindow.h
|
../include/${PROJECT_PREFIX}/MainWindow.h
|
||||||
../include/${PROJECT_PREFIX}/FindObject.h
|
../include/${PROJECT_PREFIX}/FindObject.h
|
||||||
../include/${PROJECT_PREFIX}/Camera.h
|
../include/${PROJECT_PREFIX}/Camera.h
|
||||||
../include/${PROJECT_PREFIX}/TcpServer.h
|
../include/${PROJECT_PREFIX}/TcpServer.h
|
||||||
../include/${PROJECT_PREFIX}/ObjWidget.h
|
../include/${PROJECT_PREFIX}/ObjWidget.h
|
||||||
./AddObjectDialog.h
|
./AddObjectDialog.h
|
||||||
./CameraTcpServer.h
|
./CameraTcpServer.h
|
||||||
./ParametersToolBox.h
|
./ParametersToolBox.h
|
||||||
./AboutDialog.h
|
./AboutDialog.h
|
||||||
./RectItem.h
|
./RectItem.h
|
||||||
./ImageDropWidget.h
|
./ImageDropWidget.h
|
||||||
./rtabmap/PdfPlot.h
|
./rtabmap/PdfPlot.h
|
||||||
./utilite/UPlot.h
|
./utilite/UPlot.h
|
||||||
)
|
)
|
||||||
|
IF(CATKIN_BUILD)
|
||||||
|
SET(headers_ui
|
||||||
|
${headers_ui}
|
||||||
|
./ros/CameraROS.h
|
||||||
|
./ros/FindObjectROS.h
|
||||||
|
)
|
||||||
|
ENDIF(CATKIN_BUILD)
|
||||||
|
|
||||||
SET(uis
|
SET(uis
|
||||||
./ui/mainWindow.ui
|
./ui/mainWindow.ui
|
||||||
./ui/addObjectDialog.ui
|
./ui/addObjectDialog.ui
|
||||||
./ui/aboutDialog.ui
|
./ui/aboutDialog.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(qrc
|
SET(qrc
|
||||||
./resources.qrc
|
./resources.qrc
|
||||||
)
|
)
|
||||||
|
|
||||||
# generate rules for building source files from the resources
|
# generate rules for building source files from the resources
|
||||||
@ -38,47 +45,68 @@ QT4_WRAP_CPP(moc_srcs ${headers_ui})
|
|||||||
### Qt Gui stuff end###
|
### Qt Gui stuff end###
|
||||||
|
|
||||||
SET(SRC_FILES
|
SET(SRC_FILES
|
||||||
./MainWindow.cpp
|
./MainWindow.cpp
|
||||||
./AddObjectDialog.cpp
|
./AddObjectDialog.cpp
|
||||||
./KeypointItem.cpp
|
./KeypointItem.cpp
|
||||||
./RectItem.cpp
|
./RectItem.cpp
|
||||||
./QtOpenCV.cpp
|
./QtOpenCV.cpp
|
||||||
./Camera.cpp
|
./Camera.cpp
|
||||||
./CameraTcpServer.cpp
|
./CameraTcpServer.cpp
|
||||||
./ParametersToolBox.cpp
|
./ParametersToolBox.cpp
|
||||||
./Settings.cpp
|
./Settings.cpp
|
||||||
./ObjWidget.cpp
|
./ObjWidget.cpp
|
||||||
./ImageDropWidget.cpp
|
./ImageDropWidget.cpp
|
||||||
./FindObject.cpp
|
./FindObject.cpp
|
||||||
./AboutDialog.cpp
|
./AboutDialog.cpp
|
||||||
./TcpServer.cpp
|
./TcpServer.cpp
|
||||||
./Vocabulary.cpp
|
./Vocabulary.cpp
|
||||||
./JsonWriter.cpp
|
./JsonWriter.cpp
|
||||||
./utilite/ULogger.cpp
|
./utilite/ULogger.cpp
|
||||||
./utilite/UPlot.cpp
|
./utilite/UPlot.cpp
|
||||||
./utilite/UDirectory.cpp
|
./utilite/UDirectory.cpp
|
||||||
./utilite/UFile.cpp
|
./utilite/UFile.cpp
|
||||||
./utilite/UConversion.cpp
|
./utilite/UConversion.cpp
|
||||||
./rtabmap/PdfPlot.cpp
|
./rtabmap/PdfPlot.cpp
|
||||||
./json/jsoncpp.cpp
|
./json/jsoncpp.cpp
|
||||||
${moc_srcs}
|
${moc_srcs}
|
||||||
${moc_uis}
|
${moc_uis}
|
||||||
${srcs_qrc}
|
${srcs_qrc}
|
||||||
)
|
)
|
||||||
|
IF(CATKIN_BUILD)
|
||||||
|
SET(SRC_FILES
|
||||||
|
${SRC_FILES}
|
||||||
|
./ros/CameraROS.cpp
|
||||||
|
./ros/FindObjectROS.cpp
|
||||||
|
)
|
||||||
|
ENDIF(CATKIN_BUILD)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SET(INCLUDE_DIRS
|
SET(INCLUDE_DIRS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../include
|
${CMAKE_CURRENT_SOURCE_DIR}/../include
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
${OpenCV_INCLUDE_DIRS}
|
${OpenCV_INCLUDE_DIRS}
|
||||||
${CMAKE_CURRENT_BINARY_DIR} # for qt ui generated in binary dir
|
${CMAKE_CURRENT_BINARY_DIR} # for qt ui generated in binary dir
|
||||||
)
|
)
|
||||||
|
IF(CATKIN_BUILD)
|
||||||
|
SET(INCLUDE_DIRS
|
||||||
|
${INCLUDE_DIRS}
|
||||||
|
${catkin_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
ENDIF(CATKIN_BUILD)
|
||||||
|
|
||||||
INCLUDE(${QT_USE_FILE})
|
INCLUDE(${QT_USE_FILE})
|
||||||
|
|
||||||
SET(LIBRARIES
|
SET(LIBRARIES
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
${OpenCV_LIBS}
|
${OpenCV_LIBS}
|
||||||
)
|
)
|
||||||
|
IF(CATKIN_BUILD)
|
||||||
|
SET(LIBRARIES
|
||||||
|
${LIBRARIES}
|
||||||
|
${catkin_LIBRARIES}
|
||||||
|
)
|
||||||
|
ENDIF(CATKIN_BUILD)
|
||||||
|
|
||||||
#include files
|
#include files
|
||||||
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
|
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
|
||||||
@ -87,10 +115,27 @@ INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
|
|||||||
ADD_LIBRARY(find_object ${SRC_FILES})
|
ADD_LIBRARY(find_object ${SRC_FILES})
|
||||||
# Linking with Qt libraries
|
# Linking with Qt libraries
|
||||||
TARGET_LINK_LIBRARIES(find_object ${LIBRARIES})
|
TARGET_LINK_LIBRARIES(find_object ${LIBRARIES})
|
||||||
|
IF(CATKIN_BUILD)
|
||||||
|
set_target_properties(find_object PROPERTIES OUTPUT_NAME find_object_2d)
|
||||||
|
ENDIF(CATKIN_BUILD)
|
||||||
|
|
||||||
INSTALL(TARGETS find_object
|
IF(NOT CATKIN_BUILD)
|
||||||
RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT runtime
|
INSTALL(TARGETS find_object
|
||||||
LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT devel
|
RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT runtime
|
||||||
ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" COMPONENT devel)
|
LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT devel
|
||||||
|
ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" COMPONENT devel)
|
||||||
|
|
||||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../include/ DESTINATION "${INSTALL_INCLUDE_DIR}" COMPONENT devel FILES_MATCHING PATTERN "*.h" PATTERN ".svn" EXCLUDE)
|
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../include/ DESTINATION "${INSTALL_INCLUDE_DIR}" COMPONENT devel FILES_MATCHING PATTERN "*.h" PATTERN ".svn" EXCLUDE)
|
||||||
|
ELSE()
|
||||||
|
add_executable(find_object_2d ros/find_object_2d_node.cpp)
|
||||||
|
target_link_libraries(find_object_2d find_object ${LIBRARIES})
|
||||||
|
add_dependencies(find_object_2d find_object_2d_generate_messages_cpp)
|
||||||
|
|
||||||
|
add_executable(print_objects_detected ros/print_objects_detected_node.cpp)
|
||||||
|
target_link_libraries(print_objects_detected ${LIBRARIES})
|
||||||
|
add_dependencies(print_objects_detected find_object_2d_generate_messages_cpp)
|
||||||
|
|
||||||
|
add_executable(tf_example ros/tf_example_node.cpp)
|
||||||
|
target_link_libraries(tf_example ${LIBRARIES})
|
||||||
|
add_dependencies(tf_example find_object_2d_generate_messages_cpp)
|
||||||
|
ENDIF()
|
||||||
|
|||||||
168
src/ros/CameraROS.cpp
Normal file
168
src/ros/CameraROS.cpp
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Universite de Sherbrooke nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CameraROS.h"
|
||||||
|
#include "find_object/Settings.h"
|
||||||
|
|
||||||
|
#include <opencv2/imgproc/imgproc.hpp>
|
||||||
|
#include <sensor_msgs/image_encodings.h>
|
||||||
|
|
||||||
|
using namespace find_object;
|
||||||
|
|
||||||
|
CameraROS::CameraROS(bool subscribeDepth, QObject * parent) :
|
||||||
|
Camera(parent),
|
||||||
|
subscribeDepth_(subscribeDepth)
|
||||||
|
{
|
||||||
|
ros::NodeHandle nh; // public
|
||||||
|
ros::NodeHandle pnh("~"); // private
|
||||||
|
|
||||||
|
qRegisterMetaType<ros::Time>("ros::Time");
|
||||||
|
qRegisterMetaType<cv::Mat>("cv::Mat");
|
||||||
|
|
||||||
|
if(!subscribeDepth_)
|
||||||
|
{
|
||||||
|
image_transport::ImageTransport it(nh);
|
||||||
|
imageSub_ = it.subscribe(nh.resolveName("image"), 1, &CameraROS::imgReceivedCallback, this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int queueSize = 10;
|
||||||
|
pnh.param("queue_size", queueSize, queueSize);
|
||||||
|
ROS_INFO("find_object_ros: queue_size = %d", queueSize);
|
||||||
|
|
||||||
|
ros::NodeHandle rgb_nh(nh, "rgb");
|
||||||
|
ros::NodeHandle rgb_pnh(pnh, "rgb");
|
||||||
|
ros::NodeHandle depth_nh(nh, "depth_registered");
|
||||||
|
ros::NodeHandle depth_pnh(pnh, "depth_registered");
|
||||||
|
image_transport::ImageTransport rgb_it(rgb_nh);
|
||||||
|
image_transport::ImageTransport depth_it(depth_nh);
|
||||||
|
image_transport::TransportHints hintsRgb("raw", ros::TransportHints(), rgb_pnh);
|
||||||
|
image_transport::TransportHints hintsDepth("raw", ros::TransportHints(), depth_pnh);
|
||||||
|
|
||||||
|
rgbSub_.subscribe(rgb_it, rgb_nh.resolveName("image_rect_color"), 1, hintsRgb);
|
||||||
|
depthSub_.subscribe(depth_it, depth_nh.resolveName("image_raw"), 1, hintsDepth);
|
||||||
|
cameraInfoSub_.subscribe(depth_nh, "camera_info", 1);
|
||||||
|
sync_ = new message_filters::Synchronizer<MySyncPolicy>(MySyncPolicy(queueSize), rgbSub_, depthSub_, cameraInfoSub_);
|
||||||
|
sync_->registerCallback(boost::bind(&CameraROS::imgDepthReceivedCallback, this, _1, _2, _3));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList CameraROS::subscribedTopics() const
|
||||||
|
{
|
||||||
|
QStringList topics;
|
||||||
|
if(subscribeDepth_)
|
||||||
|
{
|
||||||
|
topics.append(rgbSub_.getTopic().c_str());
|
||||||
|
topics.append(depthSub_.getTopic().c_str());
|
||||||
|
topics.append(cameraInfoSub_.getTopic().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
topics.append(imageSub_.getTopic().c_str());
|
||||||
|
}
|
||||||
|
return topics;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CameraROS::start()
|
||||||
|
{
|
||||||
|
this->startTimer();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraROS::stop()
|
||||||
|
{
|
||||||
|
this->stopTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraROS::takeImage()
|
||||||
|
{
|
||||||
|
ros::spinOnce();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraROS::imgReceivedCallback(const sensor_msgs::ImageConstPtr & msg)
|
||||||
|
{
|
||||||
|
if(msg->data.size())
|
||||||
|
{
|
||||||
|
cv_bridge::CvImageConstPtr ptr = cv_bridge::toCvShare(msg);
|
||||||
|
if(msg->encoding.compare(sensor_msgs::image_encodings::BGR8) == 0)
|
||||||
|
{
|
||||||
|
cv::Mat cpy = ptr->image.clone();
|
||||||
|
Q_EMIT rosDataReceived(msg->header.frame_id, msg->header.stamp, cv::Mat(), 0.0f);
|
||||||
|
Q_EMIT imageReceived(cpy);
|
||||||
|
}
|
||||||
|
else if(msg->encoding.compare(sensor_msgs::image_encodings::RGB8) == 0)
|
||||||
|
{
|
||||||
|
cv::Mat bgr;
|
||||||
|
cv::cvtColor(ptr->image, bgr, cv::COLOR_RGB2BGR);
|
||||||
|
Q_EMIT rosDataReceived(msg->header.frame_id, msg->header.stamp, cv::Mat(), 0.0f);
|
||||||
|
Q_EMIT imageReceived(bgr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ROS_ERROR("find_object_ros: Encoding \"%s\" detected. Supported image encodings are bgr8 and rgb8...", msg->encoding.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraROS::imgDepthReceivedCallback(
|
||||||
|
const sensor_msgs::ImageConstPtr& rgbMsg,
|
||||||
|
const sensor_msgs::ImageConstPtr& depthMsg,
|
||||||
|
const sensor_msgs::CameraInfoConstPtr& cameraInfoMsg)
|
||||||
|
{
|
||||||
|
if(!(rgbMsg->encoding.compare(sensor_msgs::image_encodings::MONO8) ==0 ||
|
||||||
|
rgbMsg->encoding.compare(sensor_msgs::image_encodings::BGR8) == 0 ||
|
||||||
|
rgbMsg->encoding.compare(sensor_msgs::image_encodings::RGB8) == 0) &&
|
||||||
|
(depthMsg->encoding.compare(sensor_msgs::image_encodings::TYPE_16UC1)!=0 ||
|
||||||
|
depthMsg->encoding.compare(sensor_msgs::image_encodings::TYPE_32FC1)!=0))
|
||||||
|
{
|
||||||
|
ROS_ERROR("find_object_ros: Input type must be rgb=mono8,rgb8,bgr8 and depth=32FC1,16UC1");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rgbMsg->data.size())
|
||||||
|
{
|
||||||
|
cv_bridge::CvImageConstPtr ptr = cv_bridge::toCvShare(rgbMsg);
|
||||||
|
cv_bridge::CvImageConstPtr ptrDepth = cv_bridge::toCvShare(depthMsg);
|
||||||
|
float depthConstant = 1.0f/cameraInfoMsg->K[4];
|
||||||
|
if(rgbMsg->encoding.compare(sensor_msgs::image_encodings::BGR8) == 0)
|
||||||
|
{
|
||||||
|
cv::Mat cpy = ptr->image.clone();
|
||||||
|
Q_EMIT rosDataReceived(rgbMsg->header.frame_id, rgbMsg->header.stamp, ptrDepth->image, depthConstant);
|
||||||
|
Q_EMIT imageReceived(cpy);
|
||||||
|
}
|
||||||
|
else if(rgbMsg->encoding.compare(sensor_msgs::image_encodings::RGB8) == 0)
|
||||||
|
{
|
||||||
|
cv::Mat bgr;
|
||||||
|
cv::cvtColor(ptr->image, bgr, cv::COLOR_RGB2BGR);
|
||||||
|
Q_EMIT rosDataReceived(rgbMsg->header.frame_id, rgbMsg->header.stamp, ptrDepth->image, depthConstant);
|
||||||
|
Q_EMIT imageReceived(bgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
90
src/ros/CameraROS.h
Normal file
90
src/ros/CameraROS.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Universite de Sherbrooke nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CAMERAROS_H_
|
||||||
|
#define CAMERAROS_H_
|
||||||
|
|
||||||
|
#include <ros/ros.h>
|
||||||
|
#include <ros/spinner.h>
|
||||||
|
#include <cv_bridge/cv_bridge.h>
|
||||||
|
|
||||||
|
#include <message_filters/subscriber.h>
|
||||||
|
#include <message_filters/synchronizer.h>
|
||||||
|
#include <message_filters/sync_policies/approximate_time.h>
|
||||||
|
|
||||||
|
#include <image_transport/image_transport.h>
|
||||||
|
#include <image_transport/subscriber_filter.h>
|
||||||
|
|
||||||
|
#include <sensor_msgs/CameraInfo.h>
|
||||||
|
#include <sensor_msgs/Image.h>
|
||||||
|
|
||||||
|
#include "find_object/Camera.h"
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
|
||||||
|
class CameraROS : public find_object::Camera {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CameraROS(bool subscribeDepth, QObject * parent = 0);
|
||||||
|
virtual ~CameraROS() {}
|
||||||
|
|
||||||
|
virtual bool start();
|
||||||
|
virtual void stop();
|
||||||
|
|
||||||
|
QStringList subscribedTopics() const;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void rosDataReceived(const std::string & frameId,
|
||||||
|
const ros::Time & stamp,
|
||||||
|
const cv::Mat & depth,
|
||||||
|
float depthConstant);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
virtual void takeImage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void imgReceivedCallback(const sensor_msgs::ImageConstPtr & msg);
|
||||||
|
void imgDepthReceivedCallback(
|
||||||
|
const sensor_msgs::ImageConstPtr& rgbMsg,
|
||||||
|
const sensor_msgs::ImageConstPtr& depthMsg,
|
||||||
|
const sensor_msgs::CameraInfoConstPtr& cameraInfoMsg);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool subscribeDepth_;
|
||||||
|
image_transport::Subscriber imageSub_;
|
||||||
|
|
||||||
|
image_transport::SubscriberFilter rgbSub_;
|
||||||
|
image_transport::SubscriberFilter depthSub_;
|
||||||
|
message_filters::Subscriber<sensor_msgs::CameraInfo> cameraInfoSub_;
|
||||||
|
|
||||||
|
typedef message_filters::sync_policies::ApproximateTime<
|
||||||
|
sensor_msgs::Image,
|
||||||
|
sensor_msgs::Image,
|
||||||
|
sensor_msgs::CameraInfo> MySyncPolicy;
|
||||||
|
message_filters::Synchronizer<MySyncPolicy> * sync_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CAMERAROS_H_ */
|
||||||
239
src/ros/FindObjectROS.cpp
Normal file
239
src/ros/FindObjectROS.cpp
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Universite de Sherbrooke nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FindObjectROS.h"
|
||||||
|
|
||||||
|
#include <std_msgs/Float32MultiArray.h>
|
||||||
|
#include "find_object_2d/ObjectsStamped.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
using namespace find_object;
|
||||||
|
|
||||||
|
FindObjectROS::FindObjectROS(const std::string & objFramePrefix, QObject * parent) :
|
||||||
|
FindObject(parent),
|
||||||
|
objFramePrefix_("object")
|
||||||
|
{
|
||||||
|
ros::NodeHandle pnh("~"); // public
|
||||||
|
pnh.param("object_prefix", objFramePrefix_, objFramePrefix_);
|
||||||
|
|
||||||
|
ros::NodeHandle nh; // public
|
||||||
|
|
||||||
|
pub_ = nh.advertise<std_msgs::Float32MultiArray>("objects", 1);
|
||||||
|
pubStamped_ = nh.advertise<find_object_2d::ObjectsStamped>("objectsStamped", 1);
|
||||||
|
|
||||||
|
this->connect(this, SIGNAL(objectsFound(find_object::DetectionInfo)), this, SLOT(publish(find_object::DetectionInfo)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindObjectROS::publish(const find_object::DetectionInfo & info)
|
||||||
|
{
|
||||||
|
// send tf before the message
|
||||||
|
if(info.objDetected_.size() && !depth_.empty() && depthConstant_ != 0.0f)
|
||||||
|
{
|
||||||
|
std::vector<tf::StampedTransform> transforms;
|
||||||
|
QMultiMap<int, QSize>::const_iterator iterSizes=info.objDetectedSizes_.constBegin();
|
||||||
|
for(QMultiMap<int, QTransform>::const_iterator iter=info.objDetected_.constBegin();
|
||||||
|
iter!=info.objDetected_.constEnd();
|
||||||
|
++iter, ++iterSizes)
|
||||||
|
{
|
||||||
|
// get data
|
||||||
|
int id = iter.key();
|
||||||
|
float objectWidth = iterSizes->width();
|
||||||
|
float objectHeight = iterSizes->height();
|
||||||
|
|
||||||
|
// Find center of the object
|
||||||
|
QPointF center = iter->map(QPointF(objectWidth/2, objectHeight/2));
|
||||||
|
QPointF xAxis = iter->map(QPointF(3*objectWidth/4, objectHeight/2));
|
||||||
|
QPointF yAxis = iter->map(QPointF(objectWidth/2, 3*objectHeight/4));
|
||||||
|
|
||||||
|
cv::Vec3f center3D = this->getDepth(depth_,
|
||||||
|
center.x()+0.5f, center.y()+0.5f,
|
||||||
|
float(depth_.cols/2)-0.5f, float(depth_.rows/2)-0.5f,
|
||||||
|
1.0f/depthConstant_, 1.0f/depthConstant_);
|
||||||
|
|
||||||
|
cv::Vec3f axisEndX = this->getDepth(depth_,
|
||||||
|
xAxis.x()+0.5f, xAxis.y()+0.5f,
|
||||||
|
float(depth_.cols/2)-0.5f, float(depth_.rows/2)-0.5f,
|
||||||
|
1.0f/depthConstant_, 1.0f/depthConstant_);
|
||||||
|
|
||||||
|
cv::Vec3f axisEndY = this->getDepth(depth_,
|
||||||
|
yAxis.x()+0.5f, yAxis.y()+0.5f,
|
||||||
|
float(depth_.cols/2)-0.5f, float(depth_.rows/2)-0.5f,
|
||||||
|
1.0f/depthConstant_, 1.0f/depthConstant_);
|
||||||
|
|
||||||
|
if(std::isfinite(center3D.val[0]) && std::isfinite(center3D.val[1]) && std::isfinite(center3D.val[2]) &&
|
||||||
|
std::isfinite(axisEndX.val[0]) && std::isfinite(axisEndX.val[1]) && std::isfinite(axisEndX.val[2]) &&
|
||||||
|
std::isfinite(axisEndY.val[0]) && std::isfinite(axisEndY.val[1]) && std::isfinite(axisEndY.val[2]))
|
||||||
|
{
|
||||||
|
tf::StampedTransform transform;
|
||||||
|
transform.setIdentity();
|
||||||
|
transform.child_frame_id_ = QString("%1_%2").arg(objFramePrefix_.c_str()).arg(id).toStdString();
|
||||||
|
transform.frame_id_ = frameId_;
|
||||||
|
transform.stamp_ = stamp_;
|
||||||
|
transform.setOrigin(tf::Vector3(center3D.val[0], center3D.val[1], center3D.val[2]));
|
||||||
|
|
||||||
|
//set rotation (y inverted)
|
||||||
|
tf::Vector3 xAxis(axisEndX.val[0] - center3D.val[0], axisEndX.val[1] - center3D.val[1], axisEndX.val[2] - center3D.val[2]);
|
||||||
|
xAxis.normalize();
|
||||||
|
tf::Vector3 yAxis(axisEndY.val[0] - center3D.val[0], axisEndY.val[1] - center3D.val[1], axisEndY.val[2] - center3D.val[2]);
|
||||||
|
yAxis.normalize();
|
||||||
|
tf::Vector3 zAxis = xAxis*yAxis;
|
||||||
|
tf::Matrix3x3 rotationMatrix(
|
||||||
|
xAxis.x(), yAxis.x() ,zAxis.x(),
|
||||||
|
xAxis.y(), yAxis.y(), zAxis.y(),
|
||||||
|
xAxis.z(), yAxis.z(), zAxis.z());
|
||||||
|
tf::Quaternion q;
|
||||||
|
rotationMatrix.getRotation(q);
|
||||||
|
// set x axis going front of the object, with z up and z left
|
||||||
|
q *= tf::createQuaternionFromRPY(CV_PI/2.0, CV_PI/2.0, 0);
|
||||||
|
transform.setRotation(q.normalized());
|
||||||
|
|
||||||
|
transforms.push_back(transform);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ROS_WARN("Object %d detected, center 2D at (%f,%f), but invalid depth, cannot set frame \"%s\"! "
|
||||||
|
"(maybe object is too near of the camera or bad depth image)\n",
|
||||||
|
id,
|
||||||
|
center.x(), center.y(),
|
||||||
|
QString("%1_%2").arg(objFramePrefix_.c_str()).arg(id).toStdString().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(transforms.size())
|
||||||
|
{
|
||||||
|
tfBroadcaster_.sendTransform(transforms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pub_.getNumSubscribers() || pubStamped_.getNumSubscribers())
|
||||||
|
{
|
||||||
|
std_msgs::Float32MultiArray msg;
|
||||||
|
find_object_2d::ObjectsStamped msgStamped;
|
||||||
|
msg.data = std::vector<float>(info.objDetected_.size()*12);
|
||||||
|
msgStamped.objects.data = std::vector<float>(info.objDetected_.size()*12);
|
||||||
|
int i=0;
|
||||||
|
QMultiMap<int, QSize>::const_iterator iterSizes=info.objDetectedSizes_.constBegin();
|
||||||
|
for(QMultiMap<int, QTransform>::const_iterator iter=info.objDetected_.constBegin();
|
||||||
|
iter!=info.objDetected_.constEnd();
|
||||||
|
++iter, ++iterSizes)
|
||||||
|
{
|
||||||
|
msg.data[i] = msgStamped.objects.data[i] = iter.key(); ++i;
|
||||||
|
msg.data[i] = msgStamped.objects.data[i] = iterSizes->width(); ++i;
|
||||||
|
msg.data[i] = msgStamped.objects.data[i] = iterSizes->height(); ++i;
|
||||||
|
msg.data[i] = msgStamped.objects.data[i] = iter->m11(); ++i;
|
||||||
|
msg.data[i] = msgStamped.objects.data[i] = iter->m12(); ++i;
|
||||||
|
msg.data[i] = msgStamped.objects.data[i] = iter->m13(); ++i;
|
||||||
|
msg.data[i] = msgStamped.objects.data[i] = iter->m21(); ++i;
|
||||||
|
msg.data[i] = msgStamped.objects.data[i] = iter->m22(); ++i;
|
||||||
|
msg.data[i] = msgStamped.objects.data[i] = iter->m23(); ++i;
|
||||||
|
msg.data[i] = msgStamped.objects.data[i] = iter->m31(); ++i;// dx
|
||||||
|
msg.data[i] = msgStamped.objects.data[i] = iter->m32(); ++i;// dy
|
||||||
|
msg.data[i] = msgStamped.objects.data[i] = iter->m33(); ++i;
|
||||||
|
}
|
||||||
|
if(pub_.getNumSubscribers())
|
||||||
|
{
|
||||||
|
pub_.publish(msg);
|
||||||
|
}
|
||||||
|
if(pubStamped_.getNumSubscribers())
|
||||||
|
{
|
||||||
|
// use same header as the input image (for synchronization and frame reference)
|
||||||
|
msgStamped.header.frame_id = frameId_;
|
||||||
|
msgStamped.header.stamp = stamp_;
|
||||||
|
pubStamped_.publish(msgStamped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindObjectROS::setDepthData(const std::string & frameId,
|
||||||
|
const ros::Time & stamp,
|
||||||
|
const cv::Mat & depth,
|
||||||
|
float depthConstant)
|
||||||
|
{
|
||||||
|
frameId_ = frameId;
|
||||||
|
stamp_ = stamp;
|
||||||
|
depth_ = depth;
|
||||||
|
depthConstant_ = depthConstant;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Vec3f FindObjectROS::getDepth(const cv::Mat & depthImage,
|
||||||
|
int x, int y,
|
||||||
|
float cx, float cy,
|
||||||
|
float fx, float fy)
|
||||||
|
{
|
||||||
|
if(!(x >=0 && x<depthImage.cols && y >=0 && y<depthImage.rows))
|
||||||
|
{
|
||||||
|
ROS_ERROR("Point must be inside the image (x=%d, y=%d), image size=(%d,%d)",
|
||||||
|
x, y,
|
||||||
|
depthImage.cols, depthImage.rows);
|
||||||
|
return cv::Vec3f(
|
||||||
|
std::numeric_limits<float>::quiet_NaN (),
|
||||||
|
std::numeric_limits<float>::quiet_NaN (),
|
||||||
|
std::numeric_limits<float>::quiet_NaN ());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cv::Vec3f pt;
|
||||||
|
|
||||||
|
// Use correct principal point from calibration
|
||||||
|
float center_x = cx; //cameraInfo.K.at(2)
|
||||||
|
float center_y = cy; //cameraInfo.K.at(5)
|
||||||
|
|
||||||
|
bool isInMM = depthImage.type() == CV_16UC1; // is in mm?
|
||||||
|
|
||||||
|
// Combine unit conversion (if necessary) with scaling by focal length for computing (X,Y)
|
||||||
|
float unit_scaling = isInMM?0.001f:1.0f;
|
||||||
|
float constant_x = unit_scaling / fx; //cameraInfo.K.at(0)
|
||||||
|
float constant_y = unit_scaling / fy; //cameraInfo.K.at(4)
|
||||||
|
float bad_point = std::numeric_limits<float>::quiet_NaN ();
|
||||||
|
|
||||||
|
float depth;
|
||||||
|
bool isValid;
|
||||||
|
if(isInMM)
|
||||||
|
{
|
||||||
|
depth = (float)depthImage.at<uint16_t>(y,x);
|
||||||
|
isValid = depth != 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
depth = depthImage.at<float>(y,x);
|
||||||
|
isValid = std::isfinite(depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for invalid measurements
|
||||||
|
if (!isValid)
|
||||||
|
{
|
||||||
|
pt.val[0] = pt.val[1] = pt.val[2] = bad_point;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fill in XYZ
|
||||||
|
pt.val[0] = (float(x) - center_x) * depth * constant_x;
|
||||||
|
pt.val[1] = (float(y) - center_y) * depth * constant_y;
|
||||||
|
pt.val[2] = depth*unit_scaling;
|
||||||
|
}
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
79
src/ros/FindObjectROS.h
Normal file
79
src/ros/FindObjectROS.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Universite de Sherbrooke nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FINDOBJECTROS_H_
|
||||||
|
#define FINDOBJECTROS_H_
|
||||||
|
|
||||||
|
#include <ros/ros.h>
|
||||||
|
#include <cv_bridge/cv_bridge.h>
|
||||||
|
#include <tf/transform_broadcaster.h>
|
||||||
|
#include "find_object/FindObject.h"
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QMultiMap>
|
||||||
|
#include <QtCore/QPair>
|
||||||
|
#include <QtCore/QRect>
|
||||||
|
#include <QtGui/QTransform>
|
||||||
|
|
||||||
|
class FindObjectROS : public find_object::FindObject
|
||||||
|
{
|
||||||
|
Q_OBJECT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FindObjectROS(const std::string & objPrefix, QObject * parent = 0);
|
||||||
|
virtual ~FindObjectROS() {}
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void publish(const find_object::DetectionInfo & info);
|
||||||
|
|
||||||
|
void setDepthData(const std::string & frameId,
|
||||||
|
const ros::Time & stamp,
|
||||||
|
const cv::Mat & depth,
|
||||||
|
float depthConstant);
|
||||||
|
|
||||||
|
private:
|
||||||
|
cv::Vec3f getDepth(const cv::Mat & depthImage,
|
||||||
|
int x, int y,
|
||||||
|
float cx, float cy,
|
||||||
|
float fx, float fy);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
ros::Publisher pub_;
|
||||||
|
ros::Publisher pubStamped_;
|
||||||
|
|
||||||
|
std::string frameId_;
|
||||||
|
ros::Time stamp_;
|
||||||
|
cv::Mat depth_;
|
||||||
|
float depthConstant_;
|
||||||
|
|
||||||
|
std::string objFramePrefix_;
|
||||||
|
tf::TransformBroadcaster tfBroadcaster_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FINDOBJECTROS_H_ */
|
||||||
201
src/ros/find_object_2d_node.cpp
Normal file
201
src/ros/find_object_2d_node.cpp
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Universite de Sherbrooke nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CameraROS.h"
|
||||||
|
#include "FindObjectROS.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDir>
|
||||||
|
#include "find_object/MainWindow.h"
|
||||||
|
#include "ParametersToolBox.h"
|
||||||
|
#include "find_object/Settings.h"
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
using namespace find_object;
|
||||||
|
|
||||||
|
bool gui;
|
||||||
|
std::string settingsPath;
|
||||||
|
|
||||||
|
void my_handler_gui(int s){
|
||||||
|
QApplication::closeAllWindows();
|
||||||
|
QApplication::quit();
|
||||||
|
}
|
||||||
|
void my_handler(int s){
|
||||||
|
QCoreApplication::quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupQuitSignal(bool gui)
|
||||||
|
{
|
||||||
|
// Catch ctrl-c to close the gui
|
||||||
|
struct sigaction sigIntHandler;
|
||||||
|
if(gui)
|
||||||
|
{
|
||||||
|
sigIntHandler.sa_handler = my_handler_gui;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sigIntHandler.sa_handler = my_handler;
|
||||||
|
}
|
||||||
|
sigemptyset(&sigIntHandler.sa_mask);
|
||||||
|
sigIntHandler.sa_flags = 0;
|
||||||
|
sigaction(SIGINT, &sigIntHandler, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
ros::init(argc, argv, "find_object_2d");
|
||||||
|
|
||||||
|
gui = true;
|
||||||
|
std::string objectsPath;
|
||||||
|
std::string sessionPath;
|
||||||
|
settingsPath = QDir::homePath().append("/.ros/find_object_2d.ini").toStdString();
|
||||||
|
bool subscribeDepth = false;
|
||||||
|
std::string objFramePrefix = "object";
|
||||||
|
|
||||||
|
ros::NodeHandle nh("~");
|
||||||
|
|
||||||
|
nh.param("gui", gui, gui);
|
||||||
|
nh.param("objects_path", objectsPath, objectsPath);
|
||||||
|
nh.param("session_path", sessionPath, sessionPath);
|
||||||
|
nh.param("settings_path", settingsPath, settingsPath);
|
||||||
|
nh.param("subscribe_depth", subscribeDepth, subscribeDepth);
|
||||||
|
nh.param("obj_frame_prefix", objFramePrefix, objFramePrefix);
|
||||||
|
|
||||||
|
ROS_INFO("gui=%d", (int)gui);
|
||||||
|
ROS_INFO("objects_path=%s", objectsPath.c_str());
|
||||||
|
ROS_INFO("session_path=%s", sessionPath.c_str());
|
||||||
|
ROS_INFO("settings_path=%s", settingsPath.c_str());
|
||||||
|
ROS_INFO("subscribe_depth = %s", subscribeDepth?"true":"false");
|
||||||
|
ROS_INFO("obj_frame_prefix = %s", objFramePrefix.c_str());
|
||||||
|
|
||||||
|
if(settingsPath.empty())
|
||||||
|
{
|
||||||
|
settingsPath = QDir::homePath().append("/.ros/find_object_2d.ini").toStdString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!sessionPath.empty())
|
||||||
|
{
|
||||||
|
ROS_WARN("\"settings_path\" parameter is ignored when \"session_path\" is set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString path = settingsPath.c_str();
|
||||||
|
if(path.contains('~'))
|
||||||
|
{
|
||||||
|
path.replace('~', QDir::homePath());
|
||||||
|
settingsPath = path.toStdString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load settings, should be loaded before creating other objects
|
||||||
|
Settings::init(settingsPath.c_str());
|
||||||
|
|
||||||
|
FindObjectROS * findObjectROS = new FindObjectROS(objFramePrefix);
|
||||||
|
if(!sessionPath.empty())
|
||||||
|
{
|
||||||
|
if(!objectsPath.empty())
|
||||||
|
{
|
||||||
|
ROS_WARN("\"objects_path\" parameter is ignored when \"session_path\" is set.");
|
||||||
|
}
|
||||||
|
if(!findObjectROS->loadSession(sessionPath.c_str()))
|
||||||
|
{
|
||||||
|
ROS_ERROR("Failed to load session \"%s\"", sessionPath.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(!objectsPath.empty())
|
||||||
|
{
|
||||||
|
QString path = objectsPath.c_str();
|
||||||
|
if(path.contains('~'))
|
||||||
|
{
|
||||||
|
path.replace('~', QDir::homePath());
|
||||||
|
}
|
||||||
|
if(!findObjectROS->loadObjects(path))
|
||||||
|
{
|
||||||
|
ROS_ERROR("No objects loaded from path \"%s\"", path.toStdString().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraROS * camera = new CameraROS(subscribeDepth);
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
camera,
|
||||||
|
SIGNAL(rosDataReceived(const std::string &, const ros::Time &, const cv::Mat &, float)),
|
||||||
|
findObjectROS,
|
||||||
|
SLOT(setDepthData(const std::string &, const ros::Time &, const cv::Mat &, float)));
|
||||||
|
|
||||||
|
// Catch ctrl-c to close the gui
|
||||||
|
setupQuitSignal(gui);
|
||||||
|
|
||||||
|
if(gui)
|
||||||
|
{
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
MainWindow mainWindow(findObjectROS, camera); // take ownership
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
&mainWindow,
|
||||||
|
SIGNAL(objectsFound(const find_object::DetectionInfo &)),
|
||||||
|
findObjectROS,
|
||||||
|
SLOT(publish(const find_object::DetectionInfo &)));
|
||||||
|
|
||||||
|
QStringList topics = camera->subscribedTopics();
|
||||||
|
if(topics.size() == 1)
|
||||||
|
{
|
||||||
|
mainWindow.setSourceImageText(mainWindow.tr(
|
||||||
|
"<qt>Find-Object subscribed to <b>%1</b> topic.<br/>"
|
||||||
|
"You can remap the topic when starting the node: <br/>\"rosrun find_object_2d find_object_2d image:=your/image/topic\".<br/>"
|
||||||
|
"</qt>").arg(topics.first()));
|
||||||
|
}
|
||||||
|
else if(topics.size() == 3)
|
||||||
|
{
|
||||||
|
mainWindow.setSourceImageText(mainWindow.tr(
|
||||||
|
"<qt>Find-Object subscribed to : <br/> <b>%1</b> <br/> <b>%2</b> <br/> <b>%3</b><br/>"
|
||||||
|
"</qt>").arg(topics.at(0)).arg(topics.at(1)).arg(topics.at(2)));
|
||||||
|
}
|
||||||
|
mainWindow.show();
|
||||||
|
app.connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) );
|
||||||
|
|
||||||
|
// loop
|
||||||
|
mainWindow.startProcessing();
|
||||||
|
app.exec();
|
||||||
|
Settings::saveSettings();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
|
// connect stuff:
|
||||||
|
QObject::connect(camera, SIGNAL(imageReceived(const cv::Mat &)), findObjectROS, SLOT(detect(const cv::Mat &)));
|
||||||
|
|
||||||
|
//loop
|
||||||
|
camera->start();
|
||||||
|
app.exec();
|
||||||
|
|
||||||
|
delete camera;
|
||||||
|
delete findObjectROS;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
115
src/ros/print_objects_detected_node.cpp
Normal file
115
src/ros/print_objects_detected_node.cpp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Universite de Sherbrooke nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ros/ros.h>
|
||||||
|
#include <std_msgs/Float32MultiArray.h>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <QTransform>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IMPORTANT :
|
||||||
|
* Parameter General/MirrorView must be false
|
||||||
|
* Parameter Homography/homographyComputed must be true
|
||||||
|
*/
|
||||||
|
void objectsDetectedCallback(const std_msgs::Float32MultiArray & msg)
|
||||||
|
{
|
||||||
|
printf("---\n");
|
||||||
|
if(msg.data.size())
|
||||||
|
{
|
||||||
|
for(unsigned int i=0; i<msg.data.size(); i+=12)
|
||||||
|
{
|
||||||
|
// get data
|
||||||
|
int id = (int)msg.data[i];
|
||||||
|
float objectWidth = msg.data[i+1];
|
||||||
|
float objectHeight = msg.data[i+2];
|
||||||
|
|
||||||
|
// Find corners Qt
|
||||||
|
QTransform qtHomography(msg.data[i+3], msg.data[i+4], msg.data[i+5],
|
||||||
|
msg.data[i+6], msg.data[i+7], msg.data[i+8],
|
||||||
|
msg.data[i+9], msg.data[i+10], msg.data[i+11]);
|
||||||
|
|
||||||
|
QPointF qtTopLeft = qtHomography.map(QPointF(0,0));
|
||||||
|
QPointF qtTopRight = qtHomography.map(QPointF(objectWidth,0));
|
||||||
|
QPointF qtBottomLeft = qtHomography.map(QPointF(0,objectHeight));
|
||||||
|
QPointF qtBottomRight = qtHomography.map(QPointF(objectWidth,objectHeight));
|
||||||
|
|
||||||
|
printf("Object %d detected, Qt corners at (%f,%f) (%f,%f) (%f,%f) (%f,%f)\n",
|
||||||
|
id,
|
||||||
|
qtTopLeft.x(), qtTopLeft.y(),
|
||||||
|
qtTopRight.x(), qtTopRight.y(),
|
||||||
|
qtBottomLeft.x(), qtBottomLeft.y(),
|
||||||
|
qtBottomRight.x(), qtBottomRight.y());
|
||||||
|
|
||||||
|
// Example with OpenCV
|
||||||
|
if(0)
|
||||||
|
{
|
||||||
|
// Find corners OpenCV
|
||||||
|
cv::Mat cvHomography(3, 3, CV_32F);
|
||||||
|
cvHomography.at<float>(0,0) = msg.data[i+3];
|
||||||
|
cvHomography.at<float>(1,0) = msg.data[i+4];
|
||||||
|
cvHomography.at<float>(2,0) = msg.data[i+5];
|
||||||
|
cvHomography.at<float>(0,1) = msg.data[i+6];
|
||||||
|
cvHomography.at<float>(1,1) = msg.data[i+7];
|
||||||
|
cvHomography.at<float>(2,1) = msg.data[i+8];
|
||||||
|
cvHomography.at<float>(0,2) = msg.data[i+9];
|
||||||
|
cvHomography.at<float>(1,2) = msg.data[i+10];
|
||||||
|
cvHomography.at<float>(2,2) = msg.data[i+11];
|
||||||
|
std::vector<cv::Point2f> inPts, outPts;
|
||||||
|
inPts.push_back(cv::Point2f(0,0));
|
||||||
|
inPts.push_back(cv::Point2f(objectWidth,0));
|
||||||
|
inPts.push_back(cv::Point2f(0,objectHeight));
|
||||||
|
inPts.push_back(cv::Point2f(objectWidth,objectHeight));
|
||||||
|
cv::perspectiveTransform(inPts, outPts, cvHomography);
|
||||||
|
|
||||||
|
printf("Object %d detected, CV corners at (%f,%f) (%f,%f) (%f,%f) (%f,%f)\n",
|
||||||
|
id,
|
||||||
|
outPts.at(0).x, outPts.at(0).y,
|
||||||
|
outPts.at(1).x, outPts.at(1).y,
|
||||||
|
outPts.at(2).x, outPts.at(2).y,
|
||||||
|
outPts.at(3).x, outPts.at(3).y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("No objects detected.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
ros::init(argc, argv, "objects_detected");
|
||||||
|
|
||||||
|
ros::NodeHandle nh;
|
||||||
|
ros::Subscriber subs;
|
||||||
|
subs = nh.subscribe("objects", 1, objectsDetectedCallback);
|
||||||
|
|
||||||
|
ros::spin();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
101
src/ros/tf_example_node.cpp
Normal file
101
src/ros/tf_example_node.cpp
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Universite de Sherbrooke nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ros/ros.h>
|
||||||
|
#include <tf/transform_listener.h>
|
||||||
|
#include <find_object_2d/ObjectsStamped.h>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
|
||||||
|
class TfExample
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TfExample() :
|
||||||
|
mapFrameId_("/map"),
|
||||||
|
objFramePrefix_("object")
|
||||||
|
{
|
||||||
|
ros::NodeHandle pnh("~");
|
||||||
|
pnh.param("map_frame_id", mapFrameId_, mapFrameId_);
|
||||||
|
pnh.param("object_prefix", objFramePrefix_, objFramePrefix_);
|
||||||
|
|
||||||
|
ros::NodeHandle nh;
|
||||||
|
subs_ = nh.subscribe("objectsStamped", 1, &TfExample::objectsDetectedCallback, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here I synchronize with the ObjectsStamped topic to
|
||||||
|
// know when the TF is ready and for which objects
|
||||||
|
void objectsDetectedCallback(const find_object_2d::ObjectsStampedConstPtr & msg)
|
||||||
|
{
|
||||||
|
if(msg->objects.data.size())
|
||||||
|
{
|
||||||
|
for(unsigned int i=0; i<msg->objects.data.size(); i+=12)
|
||||||
|
{
|
||||||
|
// get data
|
||||||
|
int id = (int)msg->objects.data[i];
|
||||||
|
std::string objectFrameId = QString("%1_%2").arg(objFramePrefix_.c_str()).arg(id).toStdString(); // "object_1", "object_2"
|
||||||
|
|
||||||
|
tf::StampedTransform pose;
|
||||||
|
tf::StampedTransform poseCam;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get transformation from "object_#" frame to target frame "map"
|
||||||
|
// The timestamp matches the one sent over TF
|
||||||
|
tfListener_.lookupTransform(mapFrameId_, objectFrameId, msg->header.stamp, pose);
|
||||||
|
tfListener_.lookupTransform(msg->header.frame_id, objectFrameId, msg->header.stamp, poseCam);
|
||||||
|
}
|
||||||
|
catch(tf::TransformException & ex)
|
||||||
|
{
|
||||||
|
ROS_WARN("%s",ex.what());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here "pose" is the position of the object "id" in "/map" frame.
|
||||||
|
ROS_INFO("Object_%d [x,y,z] [x,y,z,w] in \"%s\" frame: [%f,%f,%f] [%f,%f,%f,%f]",
|
||||||
|
id, mapFrameId_.c_str(),
|
||||||
|
pose.getOrigin().x(), pose.getOrigin().y(), pose.getOrigin().z(),
|
||||||
|
pose.getRotation().x(), pose.getRotation().y(), pose.getRotation().z(), pose.getRotation().w());
|
||||||
|
ROS_INFO("Object_%d [x,y,z] [x,y,z,w] in \"%s\" frame: [%f,%f,%f] [%f,%f,%f,%f]",
|
||||||
|
id, msg->header.frame_id.c_str(),
|
||||||
|
poseCam.getOrigin().x(), poseCam.getOrigin().y(), poseCam.getOrigin().z(),
|
||||||
|
poseCam.getRotation().x(), poseCam.getRotation().y(), poseCam.getRotation().z(), poseCam.getRotation().w());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string mapFrameId_;
|
||||||
|
std::string objFramePrefix_;
|
||||||
|
ros::Subscriber subs_;
|
||||||
|
tf::TransformListener tfListener_;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
ros::init(argc, argv, "tf_example_node");
|
||||||
|
|
||||||
|
TfExample sync;
|
||||||
|
ros::spin();
|
||||||
|
}
|
||||||
@ -2,4 +2,6 @@ ADD_SUBDIRECTORY( tcpClient )
|
|||||||
ADD_SUBDIRECTORY( tcpImagesServer )
|
ADD_SUBDIRECTORY( tcpImagesServer )
|
||||||
ADD_SUBDIRECTORY( tcpRequest )
|
ADD_SUBDIRECTORY( tcpRequest )
|
||||||
ADD_SUBDIRECTORY( tcpService )
|
ADD_SUBDIRECTORY( tcpService )
|
||||||
|
IF(NONFREE)
|
||||||
ADD_SUBDIRECTORY( similarity )
|
ADD_SUBDIRECTORY( similarity )
|
||||||
|
ENDIF(NONFREE)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user