diff --git a/CMakeLists.txt b/CMakeLists.txt index f38836b..7e572e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,58 +1,82 @@ # swatbotics/apriltags-cpp/CMakeLists.txt -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 3.5.1) project(APRILTAGS) +set(CMAKE_CXX_STANDARD 11) # for std::chrono set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) -set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) + +if(WIN32) + set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/build) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${LIBRARY_OUTPUT_PATH}) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${LIBRARY_OUTPUT_PATH}) +else() + set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) +endif() if(APPLE) - include_directories(/opt/local/include) # MacPorts - link_directories(/opt/local/lib) - find_library(OPENGL_LIBRARY OpenGL) + include_directories(/opt/local/include) # MacPorts + link_directories(/opt/local/lib) + find_library(OPENGL_LIBRARY OpenGL) else() - find_library(OPENGL_LIBRARY GL) - find_library(GLU_LIBRARY GLU) - set(OPENGL_LIBRARY ${OPENGL_LIBRARY} ${GLU_LIBRARY}) + find_library(OPENGL_LIBRARY GL) + find_library(GLU_LIBRARY GLU) + set(OPENGL_LIBRARY ${OPENGL_LIBRARY} ${GLU_LIBRARY}) endif() find_library(GLUT_LIBRARY glut) include(FindPkgConfig) -pkg_search_module(OPENCV REQUIRED opencv>=2.3 opencv-2.3.1) -include_directories(${OPENCV_INCLUDE_DIRS}) - -pkg_check_modules(CAIRO cairo) - -if (${CAIRO_FOUND}) -add_definitions(-DMZ_HAVE_CAIRO) -endif () +if(UNIX) + pkg_search_module(OPENCV REQUIRED opencv>=3.4) + include_directories(${OPENCV_INCLUDE_DIRS}) + + pkg_check_modules(CAIRO cairo) + if(${CAIRO_FOUND}) + add_definitions(-DMZ_HAVE_CAIRO) + endif() +else() + find_package(OpenCV REQUIRED) + if(${OpenCV_FOUND}) + if( ${OpenCV_VERSION}} VERSION_GREATER "3.4") + include_directories(${OpenCV_INCLUDE_DIRS}) + else() + message(FATAL_ERROR "OpenCV found but version too old. current version: " ${OpenCV_FIND_VERSION} ". required: 3.4 or newer.") + endif() + else() + message(FATAL_ERROR "OpenCV not found!") + endif() +endif() find_package( CGAL QUIET COMPONENTS ) -if (CGAL_FOUND) - include( ${CGAL_USE_FILE} ) - add_definitions(-DHAVE_CGAL) - find_package( Boost REQUIRED ) +if (${CGAL_FOUND}) + include( ${CGAL_USE_FILE} ) + add_definitions(-DHAVE_CGAL) + find_package( Boost REQUIRED ) + + if(MSVC) + add_definitions("/EHsc") # To work with boost header only + # otherwise may give linking error + endif(MSVC) else() - message("CGAL not found, can not use new quad detector") + message("CGAL not found, can not use new quad detector") endif() -set(CMAKE_C_FLAGS "-Wall -g") -set(CMAKE_CXX_FLAGS "-Wall -g") - -if (APPLE OR UNIX) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare -frounding-math") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsign-compare -frounding-math") -endif() +if(UNIX) + set(CMAKE_C_FLAGS "-Wall -g") + set(CMAKE_CXX_FLAGS "-Wall -g") -set(CMAKE_C_FLAGS_DEBUG "-O") -set(CMAKE_CXX_FLAGS_DEBUG "-O") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare -frounding-math") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsign-compare -frounding-math") + + set(CMAKE_C_FLAGS_DEBUG "-O") + set(CMAKE_CXX_FLAGS_DEBUG "-O") -set(CMAKE_C_FLAGS_RELEASE "-O2") -set(CMAKE_CXX_FLAGS_RELEASE "-O2") + set(CMAKE_C_FLAGS_RELEASE "-O2") + set(CMAKE_CXX_FLAGS_RELEASE "-O2") +endif() add_subdirectory(src) - diff --git a/images/Tags36h11.pdf b/images/Tags36h11.pdf new file mode 100644 index 0000000..8fe7cfe Binary files /dev/null and b/images/Tags36h11.pdf differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 81e506e..f81578b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,29 +11,35 @@ add_library(apriltags UnionFindSimple.cpp ) -set(AT_LIBS apriltags ${OPENCV_LDFLAGS}) - -target_link_libraries(apriltags ${AT_LIBS}) - -add_executable(camtest camtest.cpp) -target_link_libraries(camtest ${AT_LIBS}) +target_link_libraries(apriltags ${OPENCV_LDFLAGS}) -add_executable(tagtest tagtest.cpp) -target_link_libraries(tagtest ${AT_LIBS}) +set_target_properties(apriltags PROPERTIES PREFIX "lib") +set_target_properties(apriltags PROPERTIES DEBUG_POSTFIX "d") -add_executable(quadtest quadtest.cpp) -target_link_libraries(quadtest ${AT_LIBS}) +if(WIN32) + target_compile_options(apriltags PRIVATE "$<$:-O>") + target_compile_options(apriltags PRIVATE "$<$:-O2>") +endif() -if (GLUT_LIBRARY) +set(AT_LIBS apriltags ${OPENCV_LDFLAGS}) - add_executable(gltest gltest.cpp) - target_link_libraries(gltest ${GLUT_LIBRARY} ${OPENGL_LIBRARY} ${AT_LIBS}) +if(NOT WIN32) + add_executable(camtest camtest.cpp) + target_link_libraries(camtest ${AT_LIBS}) -endif() + add_executable(tagtest tagtest.cpp) + target_link_libraries(tagtest ${AT_LIBS}) -if (CAIRO_FOUND) + add_executable(quadtest quadtest.cpp) + target_link_libraries(quadtest ${AT_LIBS}) - add_executable(maketags maketags.cpp) - target_link_libraries(maketags ${CAIRO_LIBRARIES} ${AT_LIBS} ${CAIRO_LIBS}) + if(GLUT_LIBRARY) + add_executable(gltest gltest.cpp) + target_link_libraries(gltest ${GLUT_LIBRARY} ${OPENGL_LIBRARY} ${AT_LIBS}) + endif() -endif() + if(CAIRO_FOUND) + add_executable(maketags maketags.cpp) + target_link_libraries(maketags ${CAIRO_LIBRARIES} ${AT_LIBS} ${CAIRO_LIBS}) + endif() +endif() \ No newline at end of file diff --git a/src/MathUtil.cpp b/src/MathUtil.cpp index 0659615..1899653 100644 --- a/src/MathUtil.cpp +++ b/src/MathUtil.cpp @@ -8,10 +8,11 @@ #include "MathUtil.h" #include +#include const at::real MathUtil::epsilon = AT_EPSILON; -const at::real MathUtil::twopi_inv = 0.5/M_PI; -const at::real MathUtil::twopi = 2.0*M_PI; +const at::real MathUtil::twopi_inv = 0.5/CV_PI; +const at::real MathUtil::twopi = 2.0*CV_PI; at::real MathUtil::fabs(at::real f) { return std::fabs(f); @@ -160,12 +161,12 @@ at::real MathUtil::atan2(at::real y, at::real x) { if (x>=0) { return atn; } - return M_PI+atn; + return CV_PI +atn; } if (x>=0) { return atn; } - return -at::real(M_PI)+atn; + return -at::real(CV_PI)+atn; } @@ -178,9 +179,9 @@ at::real MathUtil::atan(at::real x) { return atan_mag1(x); } if (x < 0) { - return -M_PI/2-atan_mag1(1/x); + return -CV_PI/2-atan_mag1(1/x); } else { - return M_PI/2-atan_mag1(1/x); + return CV_PI/2-atan_mag1(1/x); } } diff --git a/src/Profiler.h b/src/Profiler.h index daeb98a..ee6ccc2 100644 --- a/src/Profiler.h +++ b/src/Profiler.h @@ -10,7 +10,7 @@ #define _PROFILER_H_ #include -#include +#include // Lightweight classes/structs used for profiling AprilTags. @@ -56,10 +56,17 @@ struct TimingInfo { typedef std::map TimingLookup; ////////////////////////////////////////////////////////////////////// -// Class for profiling. You may need to replace getTimeAsDouble on -// platforms where gettimeofday is not available. +// Class for profiling + + class Profiler { + typedef std::chrono::high_resolution_clock Time; + typedef std::chrono::microseconds Ms; + +private: + std::chrono::time_point init; + public: TimingLookup timers; @@ -69,14 +76,16 @@ class Profiler { Profiler(): num_iterations(0), num_detections(0) {} - static double getTimeAsDouble() { - struct timeval tp; - gettimeofday(&tp, 0); - return double(tp.tv_sec) + double(tp.tv_usec) * 1e-6; + + double getTimeAsDouble() { + auto now = std::chrono::time_point_cast(Time::now()); + return (now - init).count(); } void start(int step, int substep, const char* desc) { + init = std::chrono::time_point_cast(Time::now()); + std::pair info = timers.insert(std::make_pair(AlgorithmStep(step, substep), TimingInfo())); @@ -84,7 +93,6 @@ class Profiler { i->second.start = getTimeAsDouble(); i->second.desc = desc; - } void end(int step, int substep) { diff --git a/src/TagDetector.cpp b/src/TagDetector.cpp index 4e1f4bc..13124ff 100644 --- a/src/TagDetector.cpp +++ b/src/TagDetector.cpp @@ -19,8 +19,9 @@ #include "DebugImage.h" #include +#include #include - +#include #ifdef HAVE_CGAL #include #include @@ -44,7 +45,7 @@ static const at::real kDefaultSigma = 0; static const at::real kDefaultSegSigma = 0.8; static const bool kDefaultSegDecimate = false; static const at::real kDefaultMinMag = 0.004; -static const at::real kDefaultMaxEdgeCost = 30*M_PI/180; +static const at::real kDefaultMaxEdgeCost = 30*CV_PI/180; static const at::real kDefaultThetaThresh = 100; static const at::real kDefaultMagThresh = 1200; static const at::real kDefaultMinimumLineLength = 4; @@ -65,7 +66,7 @@ void TagDetector::reportTimers() { std::cout << "report averaged over " << prof.num_iterations << " frames with " << prof.num_detections << " detections (" << (double(prof.num_detections)/prof.num_iterations) << " per frame)\n\n"; for (TimingLookup::const_iterator i=prof.timers.begin(); i!=prof.timers.end(); ++i) { - int usec = 1e6 * i->second.run / prof.num_iterations; + int usec = i->second.run / prof.num_iterations; std::cout << std::setw(12) << usec << " usec"; if (i->first.step) { std::cout << " "; } if (i->first.substep) { std::cout << " "; } @@ -247,7 +248,7 @@ TagDetector::TagDetector(const TagFamily& f, at::real TagDetector::arctan2(at::real y, at::real x) { - at::real coeff_1 = at::real(M_PI/4); + at::real coeff_1 = at::real(CV_PI/4); at::real coeff_2 = 3*coeff_1; at::real abs_y = fabs(y)+MathUtil::epsilon; // kludge to prevent 0/0 condition @@ -1091,9 +1092,9 @@ void TagDetector::getQuads_AT(const Images& images, at::real tminab = std::min(tmina, tminb + bshift); at::real tmaxab = std::max(tmaxa, tmaxb + bshift); - if (tmaxab - tminab > 2*M_PI) { + if (tmaxab - tminab > 2*CV_PI) { // corner case that's probably not useful to handle correctly. oh well. - tmaxab = tminab + 2*M_PI; + tmaxab = tminab + 2*CV_PI; } at::real mmaxab = std::max(mmax[ida], mmax[idb]); @@ -1244,7 +1245,7 @@ void TagDetector::getQuads_AT(const Images& images, } if (flip > noflip) { - seg->theta += M_PI; + seg->theta += CV_PI; } at::real dot = dx*cos(seg->theta) + dy*sin(seg->theta); @@ -2006,8 +2007,8 @@ bool TagDetector::decodeQuad(const Images& images, d.hxy = quad.opticalCenter; if (true) { - at::real c = cos(d.rotation*M_PI/2.0); - at::real s = sin(d.rotation*M_PI/2.0); + at::real c = cos(d.rotation*CV_PI/2.0); + at::real s = sin(d.rotation*CV_PI/2.0); at::real R[9] = { c, -s, 0, s, c, 0,