| This is a combination of the following upstream commits to support opencv3, in order: |
| |
| a53bcebbfc4e6c42ee73adddc41f8c2f8f8f39c8 apply patch #94414 to support OpenCV3 |
| b95b5ae012fecdd0a85b094728d00a69bc4b4a7c bump version about OpenCV3 support |
| d61c07bf6213774fa06380c466e7dc5438c03745 add rules if not right OpenCV version is found |
| bd69e872ea43447a11282988b1f20bdf4d4f50a7 polish |
| dc62c0e0ea55d189d918501cce4d92f4198a1a0c use same OpenCV logic than digiKam and kipi-plugins |
| |
| --- a/CMakeLists.txt 2015-03-21 14:57:53.000000000 +0100 |
| +++ b/CMakeLists.txt 2015-10-16 21:47:13.382898572 +0200 |
| @@ -9,6 +9,8 @@ |
| message(STATUS "----------------------------------------------------------------------------------") |
| message(STATUS "Starting CMake configuration for: libkface") |
| |
| +option(ENABLE_OPENCV3 "Build libkface with OpenCV3 instead OpenCV2 (default=OFF)" OFF) |
| + |
| find_package(Qt4 4.6.0 REQUIRED) |
| find_package(KDE4 REQUIRED) |
| |
| @@ -29,7 +31,26 @@ |
| set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) |
| |
| include(MacroOpenCV) |
| -DETECT_OPENCV(2.4.9 core highgui objdetect contrib legacy imgproc) |
| + |
| +if(ENABLE_OPENCV3) |
| + |
| + DETECT_OPENCV(3.0.0 core face highgui objdetect imgproc) |
| + |
| + if(${OpenCV_FOUND} AND ${OpenCV_VERSION} VERSION_LESS 3.0.0) |
| + message(STATUS "ENABLE_OPENCV3 option is enabled and OpenCV < 3.0.0 have been found. Disabled ENABLE_OPENCV3") |
| + set(OpenCV_FOUND FALSE) |
| + endif() |
| + |
| +else() |
| + |
| + DETECT_OPENCV(2.4.9 core highgui objdetect contrib legacy imgproc) |
| + |
| + if(${OpenCV_FOUND} AND ${OpenCV_VERSION} VERSION_GREATER 2.4.99) |
| + message(STATUS "ENABLE_OPENCV3 option is disabled and OpenCV >= 3.0.0 have been found. Enabled ENABLE_OPENCV3") |
| + set(OpenCV_FOUND FALSE) |
| + endif() |
| + |
| +endif() |
| |
| include_directories(${OpenCV_INCLUDE_DIRS}) |
| |
| @@ -48,11 +69,12 @@ |
| # 3.3.0 => 2.0.0 (Added a "simple" training method using image data directly for a single image) |
| # 3.4.0 => 2.0.0 (Added a "simple" training method using image data directly for an image list) |
| # 3.5.0 => 3.0.0 (Added d private internal container to reduce binary uncompatibility with Identity class) |
| + # 3.5.1 => 3.0.0 (Added OpenCV3 support) |
| |
| # Library API version |
| set(KFACE_LIB_MAJOR_VERSION "3") |
| set(KFACE_LIB_MINOR_VERSION "5") |
| - set(KFACE_LIB_PATCH_VERSION "0") |
| + set(KFACE_LIB_PATCH_VERSION "1") |
| |
| # Suffix to add at end of version string. Usual values are: |
| # "-git" : alpha code unstable from git. Do not use in production |
| --- a/README 2015-03-21 14:57:53.000000000 +0100 |
| +++ b/README 2015-10-16 21:47:13.376898647 +0200 |
| @@ -21,6 +21,11 @@ |
| libkde >= 4.4.x http://www.kde.org |
| libopencv >= 2.4.9 http://opencv.willowgarage.com/wiki (with opencv 'haarcascades' data files) |
| |
| +CMake compilation options to custom libkface: |
| + |
| +Use CMake "-DENABLE_OPENCV3=on" flag to compile libkface source code using OpenCV3 instead OpenCV2 (disabled by default). |
| + OpenCV3 support needs extra contrib modules package, especially 'face' and 'legacy' components. |
| + |
| -- INSTALL ------------------------------------------------------------ |
| |
| In order to compile, especially when QT3/Qt4 are installed at the same time, |
| --- a/libkface/CMakeLists.txt 2015-03-21 14:57:53.000000000 +0100 |
| +++ b/libkface/CMakeLists.txt 2015-10-16 21:47:13.376898647 +0200 |
| @@ -1,5 +1,5 @@ |
| # |
| -# Copyright (c) 2010-2014, Gilles Caulier, <caulier dot gilles at gmail dot com> |
| +# Copyright (c) 2010-2015, Gilles Caulier, <caulier dot gilles at gmail dot com> |
| # |
| # Redistribution and use is allowed according to the terms of the BSD license. |
| # For details see the accompanying COPYING-CMAKE-SCRIPTS file. |
| --- a/libkface/detection/opencvfacedetector.cpp 2015-03-21 14:57:53.000000000 +0100 |
| +++ b/libkface/detection/opencvfacedetector.cpp 2015-10-16 21:47:13.382898572 +0200 |
| @@ -18,7 +18,7 @@ |
| * <a href="alexjironkin at gmail dot com">alexjironkin at gmail dot com</a> |
| * @author Copyright (C) 2010 by Aditya Bhatt |
| * <a href="adityabhatt at gmail dot com">adityabhatt at gmail dot com</a> |
| - * @author Copyright (C) 2010-2014 by Gilles Caulier |
| + * @author Copyright (C) 2010-2015 by Gilles Caulier |
| * <a href="mailto:caulier dot gilles at gmail dot com">caulier dot gilles at gmail dot com</a> |
| * @author Copyright (C) 2010-2013 by Marcel Wiesweg |
| * <a href="mailto:marcel dot wiesweg at gmx dot de">marcel dot wiesweg at gmx dot de</a> |
| @@ -136,13 +136,14 @@ |
| |
| cv::Size getOriginalWindowSize() const |
| { |
| +#if OPENCV_VERSION <= OPENCV_MAKE_VERSION(2,4,99) |
| // This is a HACK which may break any time. Work around the fact that getOriginalWindowSize() |
| // always returns (0,0) and we need these values. |
| if (oldCascade) |
| { |
| return oldCascade->orig_window_size; |
| } |
| - |
| +#endif |
| return cv::Size(0, 0); |
| } |
| |
| --- a/libkface/libopencv.h.cmake.in 2015-03-21 14:57:53.000000000 +0100 |
| +++ b/libkface/libopencv.h.cmake.in 2015-10-16 21:47:13.382898572 +0200 |
| @@ -7,7 +7,7 @@ |
| * @date 2010-06-16 |
| * @brief Wrapper for OpenCV header files |
| * |
| - * @author Copyright (C) 2012-2014 by Gilles Caulier |
| + * @author Copyright (C) 2012-2015 by Gilles Caulier |
| * <a href="mailto:caulier dot gilles at gmail dot com">caulier dot gilles at gmail dot com</a> |
| * |
| * This program is free software; you can redistribute it |
| @@ -31,16 +31,16 @@ |
| |
| // Pragma directives to reduce warnings from OpenCV header files. |
| #if not defined(__APPLE__) && defined(__GNUC__) |
| -#pragma GCC diagnostic push |
| -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" |
| -#pragma GCC diagnostic ignored "-Woverloaded-virtual" |
| +# pragma GCC diagnostic push |
| +# pragma GCC diagnostic ignored "-Wnon-virtual-dtor" |
| +# pragma GCC diagnostic ignored "-Woverloaded-virtual" |
| #endif |
| |
| #if defined(__APPLE__) && defined(__clang__) |
| -#pragma clang diagnostic push |
| -#pragma clang diagnostic ignored "-Wnon-virtual-dtor" |
| -#pragma clang diagnostic ignored "-Woverloaded-virtual" |
| -#pragma clang diagnostic ignored "-Wcast-align" |
| +# pragma clang diagnostic push |
| +# pragma clang diagnostic ignored "-Wnon-virtual-dtor" |
| +# pragma clang diagnostic ignored "-Woverloaded-virtual" |
| +# pragma clang diagnostic ignored "-Wcast-align" |
| #endif |
| |
| // OpenCV includes |
| @@ -49,25 +49,32 @@ |
| |
| #define OPENCV_MAKE_VERSION(major,minor,patch) (((major) << 16) | ((minor) << 8) | (patch)) |
| #define OPENCV_VERSION OPENCV_MAKE_VERSION(CV_MAJOR_VERSION,CV_MINOR_VERSION,CV_SUBMINOR_VERSION) |
| -#define OPENCV_TEST_VERSION(major,minor,patch) ( OPENCV_VERSION >= OPENCV_MAKE_VERSION(major,minor,patch) ) |
| +#define OPENCV_TEST_VERSION(major,minor,patch) ( OPENCV_VERSION < OPENCV_MAKE_VERSION(major,minor,patch) ) |
| |
| -#include <opencv2/core/core.hpp> |
| -#include <opencv2/core/internal.hpp> |
| -#include <opencv2/contrib/contrib.hpp> |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| +# include <opencv2/core/core.hpp> |
| +# include <opencv2/core/internal.hpp> |
| +# include <opencv2/contrib/contrib.hpp> |
| +#else |
| +# include <opencv2/face.hpp> |
| +# include <opencv2/core.hpp> |
| +#endif |
| |
| // for old-style code |
| +#if OPENCV_VERSION <= OPENCV_MAKE_VERSION(2,4,99) |
| +# include <opencv2/legacy/compat.hpp> |
| +#endif |
| #include <opencv2/opencv.hpp> |
| -#include <opencv2/legacy/compat.hpp> |
| #include <opencv2/highgui/highgui_c.h> |
| #include <opencv/cvaux.h> |
| |
| // Restore warnings |
| #if not defined(__APPLE__) && defined(__GNUC__) |
| -#pragma GCC diagnostic pop |
| +# pragma GCC diagnostic pop |
| #endif |
| |
| #if defined(__APPLE__) && defined(__clang__) |
| -#pragma clang diagnostic pop |
| +# pragma clang diagnostic pop |
| #endif |
| |
| #endif // LIB_OPEN_CV_H |
| --- a/libkface/recognition-opencv-lbph/facerec_borrowed.h 2015-03-21 14:57:53.000000000 +0100 |
| +++ b/libkface/recognition-opencv-lbph/facerec_borrowed.h 2015-10-16 21:47:13.382898572 +0200 |
| @@ -45,7 +45,11 @@ |
| namespace KFaceIface |
| { |
| |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| class LBPHFaceRecognizer : public cv::FaceRecognizer |
| +#else |
| +class LBPHFaceRecognizer : public cv::face::FaceRecognizer |
| +#endif |
| { |
| public: |
| |
| @@ -99,8 +103,13 @@ |
| |
| ~LBPHFaceRecognizer() {} |
| |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| using cv::FaceRecognizer::save; |
| using cv::FaceRecognizer::load; |
| +#else |
| + using cv::face::FaceRecognizer::save; |
| + using cv::face::FaceRecognizer::load; |
| +#endif |
| |
| static cv::Ptr<LBPHFaceRecognizer> create(int radius=1, int neighbors=8, int grid_x=8, int grid_y=8, double threshold = DBL_MAX, PredictionStatistics statistics = NearestNeighbor); |
| |
| @@ -139,6 +148,8 @@ |
| /** |
| * Getter functions. |
| */ |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| + |
| int neighbors() const { return m_neighbors; } |
| int radius() const { return m_radius; } |
| int grid_x() const { return m_grid_x; } |
| @@ -147,6 +158,34 @@ |
| // NOTE: Implementation done through CV_INIT_ALGORITHM macro from OpenCV. |
| cv::AlgorithmInfo* info() const; |
| |
| +#else |
| + |
| + int getNeighbors() const { return m_neighbors; } |
| + void setNeighbors(int _neighbors) { m_neighbors = _neighbors; } |
| + |
| + int getRadius() const { return m_radius; } |
| + void setRadius(int radius) { m_radius = radius; } |
| + |
| + int getGrid_x() const { return m_grid_x; } |
| + void setGrid_x(int _grid_x) { m_grid_x = _grid_x; } |
| + |
| + int getGrid_y() const { return m_grid_y; } |
| + void setGrid_y(int _grid_y) { m_grid_y = _grid_y; } |
| + |
| + double getThreshold() const { return m_threshold; } |
| + void setThreshold(double _threshold) { m_threshold = _threshold; } |
| + |
| + void setHistograms(std::vector<cv::Mat> _histograms) { m_histograms = _histograms; } |
| + std::vector<cv::Mat> getHistograms() const { return m_histograms; } |
| + |
| + void setLabels(cv::Mat _labels) { m_labels = _labels; } |
| + cv::Mat getLabels() const { return m_labels; } |
| + |
| + void setStatistic(int _statistic) { m_statisticsMode = _statistic; } |
| + int getStatistic() const { return m_statisticsMode; } |
| + |
| +#endif |
| + |
| private: |
| |
| /** Computes a LBPH model with images in src and |
| --- a/libkface/recognition-opencv-lbph/lbphfacemodel.cpp 2015-03-21 14:57:53.000000000 +0100 |
| +++ b/libkface/recognition-opencv-lbph/lbphfacemodel.cpp 2015-10-16 21:47:13.383898559 +0200 |
| @@ -61,7 +61,11 @@ |
| : cv::Ptr<LBPHFaceRecognizer>(LBPHFaceRecognizer::create()), |
| databaseId(0) |
| { |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| ptr()->set("threshold", 100.0); |
| +#else |
| + ptr()->setThreshold(100.0); |
| +#endif |
| } |
| |
| LBPHFaceModel::~LBPHFaceModel() |
| @@ -80,9 +84,13 @@ |
| |
| const LBPHFaceRecognizer* LBPHFaceModel::ptr() const |
| { |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| const LBPHFaceRecognizer* const ptr = cv::Ptr<LBPHFaceRecognizer>::operator const KFaceIface::LBPHFaceRecognizer*(); |
| +#else |
| + const LBPHFaceRecognizer* const ptr = cv::Ptr<LBPHFaceRecognizer>::operator KFaceIface::LBPHFaceRecognizer*(); |
| +#endif |
| |
| - if (!ptr) |
| + if (!ptr) |
| kWarning() << "LBPHFaceRecognizer pointer is null"; |
| |
| return ptr; |
| @@ -90,47 +98,83 @@ |
| |
| int LBPHFaceModel::radius() const |
| { |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| return ptr()->get<int>("radius"); |
| +#else |
| + return ptr()->getRadius(); |
| +#endif |
| } |
| |
| void LBPHFaceModel::setRadius(int radius) |
| { |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| ptr()->set("radius", radius); |
| +#else |
| + ptr()->setRadius(radius); |
| +#endif |
| } |
| |
| int LBPHFaceModel::neighbors() const |
| { |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| return ptr()->get<int>("neighbors"); |
| +#else |
| + return ptr()->getNeighbors(); |
| +#endif |
| } |
| |
| void LBPHFaceModel::setNeighbors(int neighbors) |
| { |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| ptr()->set("neighbors", neighbors); |
| +#else |
| + ptr()->setNeighbors(neighbors); |
| +#endif |
| } |
| |
| int LBPHFaceModel::gridX() const |
| { |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| return ptr()->get<int>("grid_x"); |
| +#else |
| + return ptr()->getGrid_x(); |
| +#endif |
| } |
| |
| void LBPHFaceModel::setGridX(int grid_x) |
| { |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| ptr()->set("grid_x", grid_x); |
| +#else |
| + ptr()->setGrid_x(grid_x); |
| +#endif |
| } |
| |
| int LBPHFaceModel::gridY() const |
| { |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| return ptr()->get<int>("grid_y"); |
| +#else |
| + return ptr()->getGrid_y(); |
| +#endif |
| } |
| |
| void LBPHFaceModel::setGridY(int grid_y) |
| { |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| ptr()->set("grid_y", grid_y); |
| +#else |
| + ptr()->setGrid_y(grid_y); |
| +#endif |
| } |
| |
| OpenCVMatData LBPHFaceModel::histogramData(int index) const |
| { |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| return OpenCVMatData(ptr()->get<std::vector<cv::Mat> >("histograms").at(index)); |
| +#else |
| + return OpenCVMatData(ptr()->getHistograms().at(index)); |
| +#endif |
| } |
| |
| QList<LBPHistogramMetadata> LBPHFaceModel::histogramMetadata() const |
| @@ -168,12 +212,24 @@ |
| m_histogramMetadata << metadata; |
| } |
| |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| std::vector<cv::Mat> currentHistograms = ptr()->get<std::vector<cv::Mat> >("histograms"); |
| cv::Mat currentLabels = ptr()->get<cv::Mat>("labels"); |
| +#else |
| + std::vector<cv::Mat> currentHistograms = ptr()->getHistograms(); |
| + cv::Mat currentLabels = ptr()->getLabels(); |
| +#endif |
| + |
| currentHistograms.insert(currentHistograms.end(), newHistograms.begin(), newHistograms.end()); |
| currentLabels.push_back(newLabels); |
| + |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| ptr()->set("histograms", currentHistograms); |
| - ptr()->set("labels", currentLabels); |
| + ptr()->set("labels", currentLabels); |
| +#else |
| + ptr()->setHistograms(currentHistograms); |
| + ptr()->setLabels(currentLabels); |
| +#endif |
| |
| /* |
| //Most cumbersome and inefficient way through a file storage which we were forced to use if we used standard OpenCV |
| @@ -215,7 +271,11 @@ |
| |
| // Update local information |
| // We assume new labels are simply appended |
| +#if OPENCV_TEST_VERSION(3,0,0) |
| cv::Mat currentLabels = ptr()->get<cv::Mat>("labels"); |
| +#else |
| + cv::Mat currentLabels = ptr()->getLabels(); |
| +#endif |
| |
| for (int i = m_histogramMetadata.size() ; i < currentLabels.rows ; i++) |
| { |
| --- a/libkface/recognition-opencv-lbph/facerec_borrowed.cpp |
| +++ b/libkface/recognition-opencv-lbph/facerec_borrowed.cpp |
| @@ -531,15 +531,17 @@ |
| return ptr; |
| } |
| |
| -CV_INIT_ALGORITHM(LBPHFaceRecognizer, "FaceRecognizer.LBPH-KFaceIface", |
| - obj.info()->addParam(obj, "radius", obj.m_radius); |
| - obj.info()->addParam(obj, "neighbors", obj.m_neighbors); |
| - obj.info()->addParam(obj, "grid_x", obj.m_grid_x); |
| - obj.info()->addParam(obj, "grid_y", obj.m_grid_y); |
| - obj.info()->addParam(obj, "threshold", obj.m_threshold); |
| - obj.info()->addParam(obj, "histograms", obj.m_histograms); // modification: Make Read/Write |
| - obj.info()->addParam(obj, "labels", obj.m_labels); // modification: Make Read/Write |
| - obj.info()->addParam(obj, "statistic", obj.m_statisticsMode)); // modification: Add parameter |
| +#if OPENCV_VERSION <= OPENCV_MAKE_VERSION(2,4,11) |
| + CV_INIT_ALGORITHM(LBPHFaceRecognizer, "FaceRecognizer.LBPH-KFaceIface", |
| + obj.info()->addParam(obj, "radius", obj.m_radius); |
| + obj.info()->addParam(obj, "neighbors", obj.m_neighbors); |
| + obj.info()->addParam(obj, "grid_x", obj.m_grid_x); |
| + obj.info()->addParam(obj, "grid_y", obj.m_grid_y); |
| + obj.info()->addParam(obj, "threshold", obj.m_threshold); |
| + obj.info()->addParam(obj, "histograms", obj.m_histograms); // modification: Make Read/Write |
| + obj.info()->addParam(obj, "labels", obj.m_labels); // modification: Make Read/Write |
| + obj.info()->addParam(obj, "statistic", obj.m_statisticsMode)); // modification: Add parameter |
| +#endif |
| |
| } // namespace KFaceIface |
| |