From da6355fd3b5d1f03873dd13f60ff6d025c54b6dd Mon Sep 17 00:00:00 2001 From: sangho park Date: Mon, 5 Mar 2018 15:25:41 +0900 Subject: [PATCH 01/16] fix typo - defalut => default Change-Id: I5048d28765b0420ec8d60eddb6831a2cef2e832e Signed-off-by: sangho park --- include/mv_image.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/include/mv_image.h b/include/mv_image.h index c525b1c..7e7d22c 100644 --- a/include/mv_image.h +++ b/include/mv_image.h @@ -40,7 +40,7 @@ extern "C" { * be recognized scale factor attribute of the engine configuration. * @details The value of the factor will be used for resizing of * the images (objects) for recognition. Scale factor is the double value - * and the defalut is 1.2 + * and the default is 1.2 * * @since_tizen 3.0 * @see mv_engine_config_set_double_attribute() @@ -55,7 +55,7 @@ extern "C" { * @details The maximal number of keypoints can be selected on the image * object to calculate descriptors. This keypoints will be used * for image (object) recognition and has to be specified as integer number - * and the defalut is 1000 + * and the default is 1000 * @since_tizen 3.0 * @see mv_engine_config_set_int_attribute() * @see mv_engine_config_get_int_attribute() @@ -67,7 +67,7 @@ extern "C" { * factor attribute of the engine configuration. * @details The value of the factor will be used for resizing of * the scene including the images (objects) for recognition. - * Scale factor is the double value and the defalut is 1.2 + * Scale factor is the double value and the default is 1.2 * * @since_tizen 3.0 * @see mv_engine_config_set_double_attribute() @@ -82,7 +82,7 @@ extern "C" { * @details The maximal number of keypoints can be selected on the scene including * the images (objects) to calculate descriptors. * This keypoints will be used for image recognition and has to be specified - * as unsigned integer and the defalut is 5000 + * as unsigned integer and the default is 5000 * * @since_tizen 3.0 * @see mv_engine_config_set_double_attribute() @@ -96,7 +96,7 @@ extern "C" { * configuration. * @details The minimal number of keypoints should be matched between an image and a scene. * It will be taken into account for image objects recognition. - * Value is unsigned integer and the defalut is 30 + * Value is unsigned integer and the default is 30 * * @since_tizen 3.0 * @see mv_engine_config_set_int_attribute() @@ -113,7 +113,7 @@ extern "C" { * amount of matching keypoints required for image recognition. * Too low value will result in unsustainable behavior, but * effect of object overlapping will be reduced. Value can be from 0 to 1 - * and the defalut is 0.05 + * and the default is 0.05 * * @since_tizen 3.0 * @see mv_engine_config_set_double_attribute() @@ -126,7 +126,7 @@ extern "C" { * matching error for the image recognition attribute of the engine * configuration. * @details Allowable error of matches number. Value can be from 0 to 1 - * and the defalut is 0.1 + * and the default is 0.1 * * @since_tizen 3.0 * @see mv_engine_config_set_double_attribute() @@ -139,7 +139,7 @@ extern "C" { * recognition results in the tracking history attribute of the engine * configuration. * @details Number of previous recognition results, which will influence - * the stabilization. Value is unsigned integer and the defalut is 3 + * the stabilization. Value is unsigned integer and the default is 3 * * @since_tizen 3.0 * @see mv_engine_config_set_int_attribute() @@ -152,7 +152,7 @@ extern "C" { * offset attribute of the engine configuration. * @details Relative offset value, for which the object offset is * expected (relative to the object size in the current frame). - * Value is a double and the defalut is 0 + * Value is a double and the default is 0 * * @since_tizen 3.0 * @see mv_engine_config_set_double_attribute() @@ -192,7 +192,7 @@ extern "C" { * speed of the tracking stabilization attribute of the engine * configuration. * @details Start speed will be used for image stabilization. Value is a double - * and the defalut is 0.3 + * and the default is 0.3 * @since_tizen 3.0 * @see mv_engine_config_set_double_attribute() * @see mv_engine_config_get_double_attribute() @@ -205,7 +205,7 @@ extern "C" { * configuration. * @details Acceleration will be used for image stabilization (relative to * the distance from current location to stabilized location). - * Value is double from 0 to 1 and the defalut is 0.1 + * Value is double from 0 to 1 and the default is 0.1 * * @since_tizen 3.0 * @see mv_engine_config_set_double_attribute() -- 2.7.4 From b3714ca9dd6a475a268bf09288047e4d703b337d Mon Sep 17 00:00:00 2001 From: sangho park Date: Mon, 5 Mar 2018 15:28:49 +0900 Subject: [PATCH 02/16] fix typo - triger => trigger Change-Id: Ie4ce9bdb33049e0bbeb88a76dccb1beabf9f51de Signed-off-by: sangho park --- include/mv_surveillance.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mv_surveillance.h b/include/mv_surveillance.h index 5ca50d2..7c6cb76 100644 --- a/include/mv_surveillance.h +++ b/include/mv_surveillance.h @@ -901,7 +901,7 @@ int mv_surveillance_get_event_trigger_type( /** * @brief Sets ROI (Region Of Interest) to the event trigger. * @details When ROI is set for the event trigger, then event check for this - * @a triger will be performed only inside the polygonal region + * @a trigger will be performed only inside the polygonal region * determined by @a roi parameter. * If this method has been never called for the @a trigger, then event * will be checked for the whole input frame (event check is performed -- 2.7.4 From 0f4b9ea0e9b8fe24cc0c237ccca24dd85169fc69 Mon Sep 17 00:00:00 2001 From: sangho park Date: Mon, 19 Mar 2018 16:41:41 +0900 Subject: [PATCH 03/16] fix coverity CID-111024 Unchecked return value CID-110444 Resource leak CID-110342 Resource leak CID-108973 Resource leak CID-107052 Resource leak Change-Id: I4dc600bd5e48cefefd02e43599f869ce2162835f Signed-off-by: sangho park --- mv_face/face/src/mv_face_open.cpp | 4 +++- .../surveillance/src/EventTriggerPersonRecognition.cpp | 6 ++++++ packaging/capi-media-vision.spec | 2 +- test/testsuites/face/face_test_suite.c | 14 ++++++++++++++ test/testsuites/surveillance/surveillance_test_suite.c | 5 +++++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/mv_face/face/src/mv_face_open.cpp b/mv_face/face/src/mv_face_open.cpp index 337b8b8..6531363 100644 --- a/mv_face/face/src/mv_face_open.cpp +++ b/mv_face/face/src/mv_face_open.cpp @@ -40,7 +40,9 @@ static void extractRecognitionParams( mv_engine_config_h working_cfg = NULL; if (NULL == engine_cfg) { - mv_create_engine_config(&working_cfg); + if (MEDIA_VISION_ERROR_NONE == mv_create_engine_config(&working_cfg)) { + LOGI("mv_create_engine_config is called"); + } } else { working_cfg = engine_cfg; } diff --git a/mv_surveillance/surveillance/src/EventTriggerPersonRecognition.cpp b/mv_surveillance/surveillance/src/EventTriggerPersonRecognition.cpp index 5dd9d09..5fbf607 100644 --- a/mv_surveillance/surveillance/src/EventTriggerPersonRecognition.cpp +++ b/mv_surveillance/surveillance/src/EventTriggerPersonRecognition.cpp @@ -163,6 +163,12 @@ int EventTriggerPersonRecognition::parseEngineConfig(mv_engine_config_h engineCo modelPath = NULL; } + const int err = mv_face_recognition_model_destroy(recognitionModel); + if (MEDIA_VISION_ERROR_NONE != err) { + LOGE("Error while trying to delete face recognition model." + " Error code: %i.", err); + } + return error; } diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec index 49f5898..5d73ca5 100644 --- a/packaging/capi-media-vision.spec +++ b/packaging/capi-media-vision.spec @@ -1,6 +1,6 @@ Name: capi-media-vision Summary: Media Vision library for Tizen Native API -Version: 0.3.28 +Version: 0.3.29 Release: 1 Group: Multimedia/Framework License: Apache-2.0 and BSD-3-Clause diff --git a/test/testsuites/face/face_test_suite.c b/test/testsuites/face/face_test_suite.c index 7db9560..c170246 100644 --- a/test/testsuites/face/face_test_suite.c +++ b/test/testsuites/face/face_test_suite.c @@ -254,6 +254,13 @@ int perform_detect() free(out_file_name); + const int err2 = mv_destroy_source(source); + if (MEDIA_VISION_ERROR_NONE != err2) { + printf(TEXT_RED + "ERROR: Errors were occurred during destroying the source!!! code: %i" + TEXT_RESET "\n", err2); + } + return err; } @@ -1598,6 +1605,13 @@ void track_on_sample_cb( printf(TEXT_RED "ERROR: Errors were occurred during filling the source " "based on the video frame! Error code: %i\n" TEXT_RESET , err); + const int err2 = mv_destroy_source(source); + if (MEDIA_VISION_ERROR_NONE != err2) { + printf(TEXT_RED + "ERROR: Errors were occurred during destroying the source!!! code: %i" + TEXT_RESET "\n", err2); + } + return; } diff --git a/test/testsuites/surveillance/surveillance_test_suite.c b/test/testsuites/surveillance/surveillance_test_suite.c index b8cce60..82373e2 100644 --- a/test/testsuites/surveillance/surveillance_test_suite.c +++ b/test/testsuites/surveillance/surveillance_test_suite.c @@ -577,6 +577,11 @@ void push_source() if (MEDIA_VISION_ERROR_NONE != error) { PRINT_E("Errors were occurred during source loading, code %i", error); + int error2 = mv_destroy_source(source); + if (MEDIA_VISION_ERROR_NONE != error2) { + PRINT_E("Errors were occurred during source destroying, code %i", error2); + } + return; } -- 2.7.4 From d6ef47d6802abb3febb4d0e81197c39ea3444551 Mon Sep 17 00:00:00 2001 From: sangho park Date: Thu, 10 May 2018 11:18:59 +0900 Subject: [PATCH 04/16] fix coverity CID-110342 Resource leak Change-Id: If8c0ea85c19f4bc251e798e6fb11eedb417144b7 Signed-off-by: sangho park --- packaging/capi-media-vision.spec | 2 +- test/testsuites/surveillance/surveillance_test_suite.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec index 5d73ca5..a66512b 100644 --- a/packaging/capi-media-vision.spec +++ b/packaging/capi-media-vision.spec @@ -1,6 +1,6 @@ Name: capi-media-vision Summary: Media Vision library for Tizen Native API -Version: 0.3.29 +Version: 0.3.30 Release: 1 Group: Multimedia/Framework License: Apache-2.0 and BSD-3-Clause diff --git a/test/testsuites/surveillance/surveillance_test_suite.c b/test/testsuites/surveillance/surveillance_test_suite.c index 82373e2..5d80753 100644 --- a/test/testsuites/surveillance/surveillance_test_suite.c +++ b/test/testsuites/surveillance/surveillance_test_suite.c @@ -596,6 +596,10 @@ void push_source() error = mv_surveillance_push_source(source, video_stream_id); if (MEDIA_VISION_ERROR_NONE != error) { PRINT_E("Errors were occurred during source pushing, code %i", error); + int error2 = mv_destroy_source(source); + if (MEDIA_VISION_ERROR_NONE != error2) { + PRINT_E("Errors were occurred during source destroying, code %i", error2); + } return; } -- 2.7.4 From 308eab6b69a5c4394a7dda1a51c9621c185270d1 Mon Sep 17 00:00:00 2001 From: Tae-Young Chung Date: Thu, 8 Feb 2018 15:18:52 +0900 Subject: [PATCH 05/16] Migration to OpenCV 3.4.0 Change-Id: I38918bc7555837f234ce0f4c52da4cbd5f2e9232 Signed-off-by: Tae-Young Chung --- .../barcode_generator/src/BarcodeGenerator.cpp | 6 +- mv_face/face/CMakeLists.txt | 2 +- mv_face/face/include/FaceDetector.h | 2 +- mv_face/face/include/FaceExpressionRecognizer.h | 5 +- mv_face/face/include/FaceEyeCondition.h | 2 +- mv_face/face/include/FaceRecognitionModel.h | 10 +- .../include/{TrackerMedianFlow.h => FaceTracker.h} | 20 +- mv_face/face/include/FaceTrackingModel.h | 6 +- mv_face/face/include/FaceUtil.h | 2 +- mv_face/face/src/FaceExpressionRecognizer.cpp | 1 - mv_face/face/src/FaceRecognitionModel.cpp | 58 +- .../src/{TrackerMedianFlow.cpp => FaceTracker.cpp} | 58 +- mv_face/face/src/FaceTrackingModel.cpp | 16 +- mv_face/face/src/FaceUtil.cpp | 2 +- mv_image/image/CMakeLists.txt | 2 +- mv_image/image/include/Features/FeatureExtractor.h | 5 - .../include/Features/FeatureExtractorFactory.h | 2 +- mv_image/image/include/Features/FeatureMatcher.h | 2 - mv_image/image/include/Features/FeaturePack.h | 11 +- mv_image/image/include/ImageMathUtil.h | 2 +- .../image/include/Recognition/ImageRecognizer.h | 2 +- mv_image/image/include/Tracking/CascadeTracker.h | 2 +- mv_image/image/include/Tracking/ObjectTracker.h | 2 +- .../image/src/Features/BasicExtractorFactory.cpp | 36 +- mv_image/image/src/Features/FeatureExtractor.cpp | 3 +- mv_image/image/src/Features/FeatureMatcher.cpp | 2 +- mv_image/image/src/Features/FeaturePack.cpp | 2 +- .../image/src/Features/ORBExtractorFactory.cpp | 14 +- mv_image/image/src/Recognition/ImageObject.cpp | 3 +- mv_image/image/src/Tracking/AsyncTracker.cpp | 2 +- mv_image/image/src/Tracking/CascadeTracker.cpp | 12 +- .../src/Tracking/FeatureSubstitutionTracker.cpp | 4 +- mv_image/image/src/Tracking/ImageTrackingModel.cpp | 6 +- mv_image/image/src/Tracking/MFTracker.cpp | 7 +- mv_image/image/src/mv_image_open.cpp | 2 +- .../include/EventTriggerPersonAppearance.h | 6 +- mv_surveillance/surveillance/include/HoGDetector.h | 201 ---- mv_surveillance/surveillance/include/MFTracker.h | 2 +- .../surveillance/include/SurveillanceHelper.h | 2 +- mv_surveillance/surveillance/src/EventManager.cpp | 2 +- .../src/EventTriggerMovementDetection.cpp | 2 +- .../src/EventTriggerPersonAppearance.cpp | 3 +- mv_surveillance/surveillance/src/HoGDetector.cpp | 1006 -------------------- mv_surveillance/surveillance/src/MFTracker.cpp | 7 +- .../surveillance/src/SurveillanceHelper.cpp | 5 +- packaging/capi-media-vision.spec | 4 +- .../common/image_helper/src/ImageHelper.cpp | 6 +- .../common/image_helper/src/image_helper.cpp | 2 +- 48 files changed, 187 insertions(+), 1374 deletions(-) rename mv_face/face/include/{TrackerMedianFlow.h => FaceTracker.h} (90%) rename mv_face/face/src/{TrackerMedianFlow.cpp => FaceTracker.cpp} (89%) delete mode 100644 mv_surveillance/surveillance/include/HoGDetector.h delete mode 100644 mv_surveillance/surveillance/src/HoGDetector.cpp diff --git a/mv_barcode/barcode_generator/src/BarcodeGenerator.cpp b/mv_barcode/barcode_generator/src/BarcodeGenerator.cpp index d329946..1bfe327 100644 --- a/mv_barcode/barcode_generator/src/BarcodeGenerator.cpp +++ b/mv_barcode/barcode_generator/src/BarcodeGenerator.cpp @@ -20,9 +20,9 @@ #include -#include -#include -#include +#include +#include +#include #include #include diff --git a/mv_face/face/CMakeLists.txt b/mv_face/face/CMakeLists.txt index caff530..8aec2e3 100644 --- a/mv_face/face/CMakeLists.txt +++ b/mv_face/face/CMakeLists.txt @@ -17,7 +17,7 @@ include_directories("${PROJECT_SOURCE_DIR}/src") file(GLOB MV_FACE_INCLUDE_LIST "${PROJECT_SOURCE_DIR}/include/*.h") file(GLOB MV_FACE_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.cpp" "${PROJECT_SOURCE_DIR}/src/*.c") -find_package(OpenCV REQUIRED core objdetect contrib) +find_package(OpenCV REQUIRED core objdetect imgproc tracking face) if(NOT OpenCV_FOUND) message(SEND_ERROR "Failed to find OpenCV") return() diff --git a/mv_face/face/include/FaceDetector.h b/mv_face/face/include/FaceDetector.h index 48d1730..55c0132 100644 --- a/mv_face/face/include/FaceDetector.h +++ b/mv_face/face/include/FaceDetector.h @@ -17,7 +17,7 @@ #ifndef __MEDIA_VISION_FACE_DETECTOR_H__ #define __MEDIA_VISION_FACE_DETECTOR_H__ -#include +#include #include #include diff --git a/mv_face/face/include/FaceExpressionRecognizer.h b/mv_face/face/include/FaceExpressionRecognizer.h index b894833..496e407 100644 --- a/mv_face/face/include/FaceExpressionRecognizer.h +++ b/mv_face/face/include/FaceExpressionRecognizer.h @@ -20,12 +20,9 @@ #include "mv_common_c.h" #include "mv_face_open.h" +#include #include -namespace cv { - class Mat; -} - /** * @file FaceExpressionRecognizer.h * @brief This file contains the FaceExpressionRecognizer class which implements diff --git a/mv_face/face/include/FaceEyeCondition.h b/mv_face/face/include/FaceEyeCondition.h index 7c1ec36..cc7a9bc 100644 --- a/mv_face/face/include/FaceEyeCondition.h +++ b/mv_face/face/include/FaceEyeCondition.h @@ -20,7 +20,7 @@ #include #include -#include +#include /** * @file FaceEyeCondition.h diff --git a/mv_face/face/include/FaceRecognitionModel.h b/mv_face/face/include/FaceRecognitionModel.h index f89c846..8a8f3ae 100644 --- a/mv_face/face/include/FaceRecognitionModel.h +++ b/mv_face/face/include/FaceRecognitionModel.h @@ -19,11 +19,13 @@ #include "FaceUtil.h" -#include -#include +#include +#include +#include #include #include +#include /** * @file FaceRecognitionModel.h @@ -252,7 +254,7 @@ private: * Factory method for creating of the recognition algorithm based on input * configuration: */ - static cv::Ptr CreateRecognitionAlgorithm( + static cv::Ptr CreateRecognitionAlgorithm( const FaceRecognitionModelConfig& config = FaceRecognitionModelConfig()); @@ -268,7 +270,7 @@ private: FaceRecognitionModelConfig m_learnAlgorithmConfig; /**< Configuration of the learning method */ - cv::Ptr m_recognizer; /**< Recognizer associated with + cv::Ptr m_recognizer; /**< Recognizer associated with the current model */ std::set m_learnedLabels; /**< Vector of the labels had been learned diff --git a/mv_face/face/include/TrackerMedianFlow.h b/mv_face/face/include/FaceTracker.h similarity index 90% rename from mv_face/face/include/TrackerMedianFlow.h rename to mv_face/face/include/FaceTracker.h index e8bed92..5266fea 100644 --- a/mv_face/face/include/TrackerMedianFlow.h +++ b/mv_face/face/include/FaceTracker.h @@ -42,11 +42,12 @@ #ifndef __MEDIA_VISION_TRACKER_MEDIAN_FLOW_H__ #define __MEDIA_VISION_TRACKER_MEDIAN_FLOW_H__ -#include "opencv2/core/core.hpp" +#include +#include namespace cv { -class TrackerMedianFlowModel; +//class TrackerMedianFlowModel; /** @brief Median Flow tracker implementation. @@ -58,7 +59,7 @@ by authors to outperform MIL). During the implementation period the code at , the courtesy of the author Arthur Amarra, was used for the reference purpose. */ -class TrackerMedianFlow : public virtual Algorithm { +class FaceTracker : public TrackerMedianFlow { public: struct Params { /** @@ -80,12 +81,12 @@ public: flow search used for tracking */ }; - TrackerMedianFlow(Params paramsIn = Params()); + FaceTracker(Params paramsIn = Params()); - bool copyTo(TrackerMedianFlow& copy) const; + bool copyTo(FaceTracker& copy) const; - bool init(const Mat& image, const Rect_& boundingBox); - bool update(const Mat& image, Rect_& boundingBox); + bool initImpl(const Mat& image, const Rect2d& boundingBox); + bool updateImpl(const Mat& image, Rect2d& boundingBox); bool isInited() const; @@ -94,11 +95,12 @@ public: void read(FileStorage& fn); void write(FileStorage& fs) const; + void read( const FileNode& fn ); private: bool m_isInit; - bool medianFlowImpl(Mat oldImage, Mat newImage, Rect_& oldBox); + bool medianFlowImpl(Mat oldImage, Mat newImage, Rect2f& oldBox); Rect_ vote( const std::vector& oldPoints, @@ -132,7 +134,7 @@ private: Lucas–Kanade optical flow algorithm used during tracking */ - Rect_ m_boundingBox; /**< Tracking object bounding box */ + Rect2d m_boundingBox; /**< Tracking object bounding box */ float m_confidence; /**< Confidence that face was tracked correctly at the last tracking iteration */ diff --git a/mv_face/face/include/FaceTrackingModel.h b/mv_face/face/include/FaceTrackingModel.h index 8c73705..95f8d6e 100644 --- a/mv_face/face/include/FaceTrackingModel.h +++ b/mv_face/face/include/FaceTrackingModel.h @@ -17,7 +17,9 @@ #ifndef __MEDIA_VISION_FACE_TRACKING_MODEL_H__ #define __MEDIA_VISION_FACE_TRACKING_MODEL_H__ -#include "TrackerMedianFlow.h" +#include +#include "FaceTracker.h" + /** * @file FaceTrackingModel.h @@ -158,7 +160,7 @@ private: of the tracking model to perform track */ - cv::Ptr m_tracker; /**< Underlying OpenCV tracking + cv::Ptr m_tracker; /**< Underlying OpenCV tracking model */ }; diff --git a/mv_face/face/include/FaceUtil.h b/mv_face/face/include/FaceUtil.h index 65c5896..bd2cd63 100644 --- a/mv_face/face/include/FaceUtil.h +++ b/mv_face/face/include/FaceUtil.h @@ -17,7 +17,7 @@ #ifndef __MEDIA_VISION_FACE_UTIL_H__ #define __MEDIA_VISION_FACE_UTIL_H__ -#include +#include #include "mv_common_c.h" diff --git a/mv_face/face/src/FaceExpressionRecognizer.cpp b/mv_face/face/src/FaceExpressionRecognizer.cpp index a1f7b0b..54f5309 100644 --- a/mv_face/face/src/FaceExpressionRecognizer.cpp +++ b/mv_face/face/src/FaceExpressionRecognizer.cpp @@ -20,7 +20,6 @@ #include -#include namespace MediaVision { namespace Face { diff --git a/mv_face/face/src/FaceRecognitionModel.cpp b/mv_face/face/src/FaceRecognitionModel.cpp index e247f58..32a6d8c 100644 --- a/mv_face/face/src/FaceRecognitionModel.cpp +++ b/mv_face/face/src/FaceRecognitionModel.cpp @@ -56,17 +56,17 @@ bool isEmptyAlgorithmParam(const std::string& path) return false; } -int CopyOpenCVAlgorithmParameters(const cv::Ptr& srcAlg, - cv::Ptr& dstAlg) +int CopyOpenCVAlgorithmParameters(const cv::Ptr& srcAlg, + cv::Ptr& dstAlg) { char tempPath[1024] = ""; - snprintf(tempPath, 1024, "/tmp/alg_copy_%p_%p", srcAlg.obj, dstAlg.obj); + snprintf(tempPath, 1024, "/tmp/alg_copy_%p_%p", srcAlg.get(), dstAlg.get()); - srcAlg->save(tempPath); + srcAlg->write(tempPath); if (!isEmptyAlgorithmParam(tempPath)) - dstAlg->load(tempPath); + dstAlg->read(tempPath); if (0 != remove(tempPath)) LOGW("Error removing serialized FaceRecognizer in %s", tempPath); @@ -123,11 +123,11 @@ int CopyOpenCVAlgorithmParameters(const cv::Ptr& srcAlg, } void ParseOpenCVLabels( - const cv::Ptr& recognizer, + const cv::Ptr& recognizer, std::set& outLabels) { if (!recognizer.empty()) { - cv::Mat labels = recognizer->getMat("labels"); + cv::Mat labels = (dynamic_cast(recognizer.get()))->getLabels(); for (int i = 0; i < labels.rows; ++i) outLabels.insert(labels.at(i, 0)); @@ -174,7 +174,7 @@ bool FaceRecognitionModelConfig::operator!=( FaceRecognitionModel::FaceRecognitionModel() : m_canRecognize(false), - m_recognizer(NULL) + m_recognizer() // The default constructor creates a null Ptr { ; /* NULL */ } @@ -255,7 +255,7 @@ int FaceRecognitionModel::save(const std::string& fileName) } storage << "can_recognize" << m_canRecognize; - m_recognizer->save(storage); + m_recognizer->write(storage); storage.release(); } else { @@ -292,39 +292,39 @@ int FaceRecognitionModel::load(const std::string& fileName) storage["algorithm"] >> algName; storage["can_recognize"] >> canRecognize; - cv::Ptr tempRecognizer; + cv::Ptr tempRecognizer; FaceRecognitionModelConfig tempConfig; std::set tempLearnedLabels; if (algName == "Eigenfaces") { - tempRecognizer = cv::createEigenFaceRecognizer(); + tempRecognizer = cv::face::EigenFaceRecognizer::create(); storage["resizeW"] >> tempConfig.mImgWidth; storage["resizeH"] >> tempConfig.mImgHeight; - tempRecognizer->load(storage); + tempRecognizer->read(storage.root()); tempConfig.mModelType = MEDIA_VISION_FACE_MODEL_TYPE_EIGENFACES; tempConfig.mNumComponents = - tempRecognizer->getInt("ncomponents"); + (dynamic_cast(tempRecognizer.get()))->getNumComponents(); ParseOpenCVLabels(tempRecognizer, tempLearnedLabels); } else if (algName == "Fisherfaces") { - tempRecognizer = cv::createFisherFaceRecognizer(); + tempRecognizer = cv::face::FisherFaceRecognizer::create(); storage["resizeW"] >> tempConfig.mImgWidth; storage["resizeH"] >> tempConfig.mImgHeight; - tempRecognizer->load(storage); + tempRecognizer->read(storage.root()); tempConfig.mModelType = MEDIA_VISION_FACE_MODEL_TYPE_FISHERFACES; tempConfig.mNumComponents = - tempRecognizer->getInt("ncomponents"); + (dynamic_cast(tempRecognizer.get()))->getNumComponents(); ParseOpenCVLabels(tempRecognizer, tempLearnedLabels); } else if (algName == "LBPH") { - tempRecognizer = cv::createLBPHFaceRecognizer(); - tempRecognizer->load(storage); + tempRecognizer = cv::face::LBPHFaceRecognizer::create(); + tempRecognizer->read(storage.root()); tempConfig.mModelType = MEDIA_VISION_FACE_MODEL_TYPE_LBPH; - tempConfig.mGridX = tempRecognizer->getInt("grid_x"); - tempConfig.mGridY = tempRecognizer->getInt("grid_y"); - tempConfig.mNeighbors = tempRecognizer->getInt("neighbors"); - tempConfig.mRadius = tempRecognizer->getInt("radius"); + tempConfig.mGridX = (dynamic_cast(tempRecognizer.get()))->getGridX(); + tempConfig.mGridY = (dynamic_cast(tempRecognizer.get()))->getGridY(); + tempConfig.mNeighbors = (dynamic_cast(tempRecognizer.get()))->getNeighbors(); + tempConfig.mRadius = (dynamic_cast(tempRecognizer.get()))->getRadius(); ParseOpenCVLabels(tempRecognizer, tempLearnedLabels); } else { tempConfig = FaceRecognitionModelConfig(); @@ -336,7 +336,7 @@ int FaceRecognitionModel::load(const std::string& fileName) return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT; } - tempConfig.mThreshold = tempRecognizer->getDouble("threshold"); + tempConfig.mThreshold = tempRecognizer->getThreshold(); LOGD("Recognition model of [%s] type has been loaded from file", algName.c_str()); @@ -529,23 +529,23 @@ int FaceRecognitionModel::recognize(const cv::Mat& image, FaceRecognitionResults return MEDIA_VISION_ERROR_NONE; } -cv::Ptr FaceRecognitionModel::CreateRecognitionAlgorithm( +cv::Ptr FaceRecognitionModel::CreateRecognitionAlgorithm( const FaceRecognitionModelConfig& config) { - cv::Ptr tempRecognizer; + cv::Ptr tempRecognizer; switch (config.mModelType) { case MEDIA_VISION_FACE_MODEL_TYPE_EIGENFACES: - tempRecognizer = cv::createEigenFaceRecognizer( + tempRecognizer = cv::face::EigenFaceRecognizer::create( config.mNumComponents, config.mThreshold); break; case MEDIA_VISION_FACE_MODEL_TYPE_FISHERFACES: - tempRecognizer = cv::createFisherFaceRecognizer( + tempRecognizer = cv::face::FisherFaceRecognizer::create( config.mNumComponents, config.mThreshold); break; case MEDIA_VISION_FACE_MODEL_TYPE_LBPH: - tempRecognizer = cv::createLBPHFaceRecognizer( + tempRecognizer = cv::face::LBPHFaceRecognizer::create( config.mRadius, config.mNeighbors, config.mGridX, @@ -553,7 +553,7 @@ cv::Ptr FaceRecognitionModel::CreateRecognitionAlgorithm( config.mThreshold); break; default: - return NULL; + LOGE("Unknown FaceRecognition model"); } return tempRecognizer; diff --git a/mv_face/face/src/TrackerMedianFlow.cpp b/mv_face/face/src/FaceTracker.cpp similarity index 89% rename from mv_face/face/src/TrackerMedianFlow.cpp rename to mv_face/face/src/FaceTracker.cpp index 759b606..f5427ce 100644 --- a/mv_face/face/src/TrackerMedianFlow.cpp +++ b/mv_face/face/src/FaceTracker.cpp @@ -39,10 +39,10 @@ // //M*/ -#include "TrackerMedianFlow.h" +#include "FaceTracker.h" #include "opencv2/video/tracking.hpp" -#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/imgproc.hpp" #include #include @@ -52,14 +52,14 @@ namespace { } /* anonymous namespace */ namespace cv { -TrackerMedianFlow::Params::Params() +FaceTracker::Params::Params() { mPointsInGrid = 10; mWindowSize = Size(3, 3); mPyrMaxLevel = 5; } -void TrackerMedianFlow::Params::read(const cv::FileNode& fn) +void FaceTracker::Params::read(const cv::FileNode& fn) { mPointsInGrid = fn["pointsInGrid"]; int winSizeHeight = fn["windowSizeHeight"]; @@ -68,7 +68,7 @@ void TrackerMedianFlow::Params::read(const cv::FileNode& fn) mPyrMaxLevel = fn["pyrMaxLevel"]; } -void TrackerMedianFlow::Params::write(cv::FileStorage& fs) const +void FaceTracker::Params::write(cv::FileStorage& fs) const { fs << "pointsInGrid" << mPointsInGrid; fs << "windowSizeHeight" << mWindowSize.height; @@ -76,7 +76,7 @@ void TrackerMedianFlow::Params::write(cv::FileStorage& fs) const fs << "pyrMaxLevel" << mPyrMaxLevel; } -TrackerMedianFlow::TrackerMedianFlow(Params paramsIn) : +FaceTracker::FaceTracker(Params paramsIn) : m_termcrit(TermCriteria::COUNT | TermCriteria::EPS, 20, 0.3), m_confidence(0.0) { @@ -84,7 +84,7 @@ TrackerMedianFlow::TrackerMedianFlow(Params paramsIn) : m_isInit = false; } -bool TrackerMedianFlow::copyTo(TrackerMedianFlow& copy) const +bool FaceTracker::copyTo(FaceTracker& copy) const { copy.m_isInit = m_isInit; copy.m_params = m_params; @@ -95,7 +95,7 @@ bool TrackerMedianFlow::copyTo(TrackerMedianFlow& copy) const return true; } -bool TrackerMedianFlow::init(const Mat& image, const Rect_& boundingBox) +bool FaceTracker::initImpl(const Mat& image, const Rect2d& boundingBox) { if (image.empty()) return false; @@ -109,7 +109,7 @@ bool TrackerMedianFlow::init(const Mat& image, const Rect_& boundingBox) return m_isInit; } -bool TrackerMedianFlow::update(const Mat& image, Rect_& boundingBox) +bool FaceTracker::updateImpl(const Mat& image, Rect2d& boundingBox) { if (!m_isInit || image.empty()) return false; @@ -119,8 +119,8 @@ bool TrackerMedianFlow::update(const Mat& image, Rect_& boundingBox) * frame and bounding box. Then, track as usually: */ if (m_image.rows != image.rows || m_image.cols != image.cols) { - const float xFactor = (float) image.cols / m_image.cols; - const float yFactor = (float) image.rows / m_image.rows; + const double xFactor = (double) image.cols / m_image.cols; + const double yFactor = (double) image.rows / m_image.rows; resize(m_image, m_image, Size(), xFactor, yFactor); @@ -132,33 +132,33 @@ bool TrackerMedianFlow::update(const Mat& image, Rect_& boundingBox) Mat oldImage = m_image; - Rect_ oldBox = m_boundingBox; + Rect2f oldBox = (Rect2f)m_boundingBox; if(!medianFlowImpl(oldImage, image, oldBox)) return false; - boundingBox = oldBox; + boundingBox = (Rect2d)oldBox; image.copyTo(m_image); m_boundingBox = boundingBox; return true; } -bool TrackerMedianFlow::isInited() const +bool FaceTracker::isInited() const { return m_isInit; } -float TrackerMedianFlow::getLastConfidence() const +float FaceTracker::getLastConfidence() const { return m_confidence; } -Rect_ TrackerMedianFlow::getLastBoundingBox() const +Rect_ FaceTracker::getLastBoundingBox() const { return m_boundingBox; } -bool TrackerMedianFlow::medianFlowImpl( - Mat oldGrayImage, Mat newGrayImage, Rect_& oldBox) +bool FaceTracker::medianFlowImpl( + Mat oldGrayImage, Mat newGrayImage, Rect2f& oldBox) { std::vector pointsToTrackOld, pointsToTrackNew; @@ -241,7 +241,7 @@ bool TrackerMedianFlow::medianFlowImpl( return true; } -Rect_ TrackerMedianFlow::vote( +Rect_ FaceTracker::vote( const std::vector& oldPoints, const std::vector& newPoints, const Rect_& oldRect, @@ -305,7 +305,7 @@ Rect_ TrackerMedianFlow::vote( } template -T TrackerMedianFlow::getMedian(std::vector& values, int size) +T FaceTracker::getMedian(std::vector& values, int size) { if (size == -1) size = (int)values.size(); @@ -319,14 +319,14 @@ T TrackerMedianFlow::getMedian(std::vector& values, int size) } } -float TrackerMedianFlow::l2distance(Point2f p1, Point2f p2) +float FaceTracker::l2distance(Point2f p1, Point2f p2) { float dx = p1.x - p2.x; float dy = p1.y - p2.y; return sqrt(dx * dx + dy * dy); } -void TrackerMedianFlow::check_FB( +void FaceTracker::check_FB( std::vector newPyramid, const std::vector& oldPoints, const std::vector& newPoints, @@ -358,7 +358,7 @@ void TrackerMedianFlow::check_FB( status[idx] = (FBerror[idx] < FBerrorMedian); } -void TrackerMedianFlow::check_NCC( +void FaceTracker::check_NCC( const Mat& oldImage, const Mat& newImage, const std::vector& oldPoints, @@ -391,9 +391,14 @@ void TrackerMedianFlow::check_NCC( status[idx] = status[idx] && (NCC[idx] > median); } -void TrackerMedianFlow::read(cv::FileStorage& fs) +void FaceTracker::read(const cv::FileNode& fn) { - m_params.read(fs.root()); + m_params.read(fn); +} + +void FaceTracker::read(cv::FileStorage& fs) +{ + read(fs.root()); float bbX = 0.f; float bbY = 0.f; float bbW = 0.f; @@ -406,7 +411,8 @@ void TrackerMedianFlow::read(cv::FileStorage& fs) fs["lastImage"] >> m_image; } -void TrackerMedianFlow::write(cv::FileStorage& fs) const + +void FaceTracker::write(cv::FileStorage& fs) const { m_params.write(fs); fs << "lastLocationX" << m_boundingBox.x; diff --git a/mv_face/face/src/FaceTrackingModel.cpp b/mv_face/face/src/FaceTrackingModel.cpp index 98df8a4..46faa0b 100644 --- a/mv_face/face/src/FaceTrackingModel.cpp +++ b/mv_face/face/src/FaceTrackingModel.cpp @@ -32,26 +32,26 @@ FaceTrackingResults::FaceTrackingResults() : FaceTrackingModel::FaceTrackingModel() : m_canTrack(false), - m_tracker(new cv::TrackerMedianFlow()) + m_tracker(new cv::FaceTracker()) { ; /* NULL */ } FaceTrackingModel::FaceTrackingModel(const FaceTrackingModel& origin) : m_canTrack(origin.m_canTrack), - m_tracker(new cv::TrackerMedianFlow()) + m_tracker(new cv::FaceTracker()) { if (!origin.m_tracker.empty()) - origin.m_tracker->copyTo(*(m_tracker.obj)); + origin.m_tracker->copyTo(*(m_tracker.get())); } FaceTrackingModel& FaceTrackingModel::operator=(const FaceTrackingModel& copy) { if (this != ©) { m_canTrack = copy.m_canTrack; - m_tracker = cv::Ptr(new cv::TrackerMedianFlow()); + m_tracker = cv::Ptr(new cv::FaceTracker()); if (!copy.m_tracker.empty()) - copy.m_tracker->copyTo(*(m_tracker.obj)); + copy.m_tracker->copyTo(*(m_tracker.get())); } return *this; @@ -162,7 +162,7 @@ int FaceTrackingModel::prepare( return MEDIA_VISION_ERROR_INVALID_OPERATION; } - if (!m_tracker->init(image, boundingBox)) { + if (!m_tracker->initImpl(image, boundingBox)) { LOGE("Failed to prepare tracking model."); return MEDIA_VISION_ERROR_INVALID_OPERATION; } @@ -174,8 +174,10 @@ int FaceTrackingModel::prepare( int FaceTrackingModel::track(const cv::Mat& image, FaceTrackingResults& results) { if (!m_tracker.empty() && m_canTrack) { - results.mIsTracked = m_tracker->update(image, results.mFaceLocation); + cv::Rect2d faceLocation = (cv::Rect2d)results.mFaceLocation; + results.mIsTracked = m_tracker->updateImpl(image, faceLocation); results.mConfidence = m_tracker->getLastConfidence(); + results.mFaceLocation = (cv::Rect2f)faceLocation; } else { LOGE("Attempt to track face with not prepared model"); return MEDIA_VISION_ERROR_INVALID_OPERATION; diff --git a/mv_face/face/src/FaceUtil.cpp b/mv_face/face/src/FaceUtil.cpp index 954f82b..c2e5ec0 100644 --- a/mv_face/face/src/FaceUtil.cpp +++ b/mv_face/face/src/FaceUtil.cpp @@ -18,7 +18,7 @@ #include "mv_private.h" -#include +#include namespace MediaVision { namespace Face { diff --git a/mv_image/image/CMakeLists.txt b/mv_image/image/CMakeLists.txt index 801c418..acdb240 100644 --- a/mv_image/image/CMakeLists.txt +++ b/mv_image/image/CMakeLists.txt @@ -17,7 +17,7 @@ include_directories("${PROJECT_SOURCE_DIR}/src") file(GLOB_RECURSE MV_IMAGE_INC_LIST "${PROJECT_SOURCE_DIR}/include/*.h") file(GLOB_RECURSE MV_IMAGE_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.cpp" "${PROJECT_SOURCE_DIR}/src/*.c") -find_package(OpenCV REQUIRED core imgproc objdetect features2d contrib) +find_package(OpenCV REQUIRED core imgproc objdetect tracking features2d xfeatures2d) if(NOT OpenCV_FOUND) message(SEND_ERROR "Failed to find OpenCV") return() diff --git a/mv_image/image/include/Features/FeatureExtractor.h b/mv_image/image/include/Features/FeatureExtractor.h index 4a34fae..f2f6e5e 100644 --- a/mv_image/image/include/Features/FeatureExtractor.h +++ b/mv_image/image/include/Features/FeatureExtractor.h @@ -21,11 +21,6 @@ #include "Features/FeaturePack.h" -namespace cv { -class FeatureDetector; -class DescriptorExtractor; -} - namespace MediaVision { namespace Image { /** diff --git a/mv_image/image/include/Features/FeatureExtractorFactory.h b/mv_image/image/include/Features/FeatureExtractorFactory.h index 837725a..1477292 100644 --- a/mv_image/image/include/Features/FeatureExtractorFactory.h +++ b/mv_image/image/include/Features/FeatureExtractorFactory.h @@ -19,7 +19,7 @@ #include "Features/FeatureExtractor.h" -#include +#include namespace MediaVision { namespace Image { diff --git a/mv_image/image/include/Features/FeatureMatcher.h b/mv_image/image/include/Features/FeatureMatcher.h index 37f4508..971e7f9 100644 --- a/mv_image/image/include/Features/FeatureMatcher.h +++ b/mv_image/image/include/Features/FeatureMatcher.h @@ -19,8 +19,6 @@ #include "Features/FeaturePack.h" -#include - namespace MediaVision { namespace Image { diff --git a/mv_image/image/include/Features/FeaturePack.h b/mv_image/image/include/Features/FeaturePack.h index c492bf3..422de0b 100644 --- a/mv_image/image/include/Features/FeaturePack.h +++ b/mv_image/image/include/Features/FeaturePack.h @@ -17,14 +17,15 @@ #ifndef __MEDIA_VISION_FEATUREPACK_H__ #define __MEDIA_VISION_FEATUREPACK_H__ +#include "mv_private.h" #include "ImageConfig.h" #include -#include - -namespace cv { -class KeyPoint; -} +#include +#include +#include +#include +#include namespace MediaVision { namespace Image { diff --git a/mv_image/image/include/ImageMathUtil.h b/mv_image/image/include/ImageMathUtil.h index f8a8ce1..bd49674 100644 --- a/mv_image/image/include/ImageMathUtil.h +++ b/mv_image/image/include/ImageMathUtil.h @@ -17,7 +17,7 @@ #ifndef __MEDIA_VISION_IMAGEMATHUTIL_H__ #define __MEDIA_VISION_IMAGEMATHUTIL_H__ -#include +#include /** * @file ImageMathUtil.h diff --git a/mv_image/image/include/Recognition/ImageRecognizer.h b/mv_image/image/include/Recognition/ImageRecognizer.h index 2a92550..5ac2f2e 100644 --- a/mv_image/image/include/Recognition/ImageRecognizer.h +++ b/mv_image/image/include/Recognition/ImageRecognizer.h @@ -22,7 +22,7 @@ #include "Recognition/ImageObject.h" -#include +#include /** * @file ImageRecognizer.h diff --git a/mv_image/image/include/Tracking/CascadeTracker.h b/mv_image/image/include/Tracking/CascadeTracker.h index e28e294..09a9d08 100644 --- a/mv_image/image/include/Tracking/CascadeTracker.h +++ b/mv_image/image/include/Tracking/CascadeTracker.h @@ -19,7 +19,7 @@ #include "Tracking/ObjectTracker.h" -#include +#include #include diff --git a/mv_image/image/include/Tracking/ObjectTracker.h b/mv_image/image/include/Tracking/ObjectTracker.h index ffc02c1..0fe88b4 100644 --- a/mv_image/image/include/Tracking/ObjectTracker.h +++ b/mv_image/image/include/Tracking/ObjectTracker.h @@ -17,7 +17,7 @@ #ifndef __MEDIA_VISION_OBJECTTRACKER_H__ #define __MEDIA_VISION_OBJECTTRACKER_H__ -#include +#include namespace MediaVision { namespace Image { diff --git a/mv_image/image/src/Features/BasicExtractorFactory.cpp b/mv_image/image/src/Features/BasicExtractorFactory.cpp index 9c2d6e6..0982be1 100644 --- a/mv_image/image/src/Features/BasicExtractorFactory.cpp +++ b/mv_image/image/src/Features/BasicExtractorFactory.cpp @@ -16,7 +16,7 @@ #include "Features/BasicExtractorFactory.h" -#include +#include namespace MediaVision { namespace Image { @@ -32,17 +32,35 @@ BasicExtractorFactory::BasicExtractorFactory( cv::Ptr BasicExtractorFactory::buildFeatureExtractor() { cv::Ptr featureExtractor(new (std::nothrow)FeatureExtractor()); - if (featureExtractor == NULL) - return NULL; - cv::Ptr detector = - cv::FeatureDetector::create(KeypointNames[__kpType]); + if (featureExtractor != NULL) { + cv::Ptr detector; + switch (__kpType) { + case KT_ORB: + detector = cv::ORB::create(); + break; + case KT_GFTT: + detector = cv::GFTTDetector::create(); + break; + default: + LOGE("Unknown feature detector", __FUNCTION__); + } - cv::Ptr extractor = - cv::DescriptorExtractor::create(DescriptorNames[__descType]); + cv::Ptr extractor; + switch (__descType) { + case DT_ORB: + extractor = cv::ORB::create(); + break; + case DT_BRIEF: + extractor = cv::xfeatures2d::BriefDescriptorExtractor::create(); + break; + default: + LOGE("Unkown feature extractor", __FUNCTION__); + } - featureExtractor->setFeatureDetector(detector, __kpType); - featureExtractor->setDescriptorExtractor(extractor, __descType); + featureExtractor->setFeatureDetector(detector, __kpType); + featureExtractor->setDescriptorExtractor(extractor, __descType); + } return featureExtractor; } diff --git a/mv_image/image/src/Features/FeatureExtractor.cpp b/mv_image/image/src/Features/FeatureExtractor.cpp index 15c36be..5b04f00 100644 --- a/mv_image/image/src/Features/FeatureExtractor.cpp +++ b/mv_image/image/src/Features/FeatureExtractor.cpp @@ -18,7 +18,8 @@ #include "ImageMathUtil.h" -#include +#include + namespace MediaVision { namespace Image { diff --git a/mv_image/image/src/Features/FeatureMatcher.cpp b/mv_image/image/src/Features/FeatureMatcher.cpp index 891e85f..f7c887c 100644 --- a/mv_image/image/src/Features/FeatureMatcher.cpp +++ b/mv_image/image/src/Features/FeatureMatcher.cpp @@ -18,7 +18,7 @@ #include "ImageMathUtil.h" -#include +#include namespace MediaVision { namespace Image { diff --git a/mv_image/image/src/Features/FeaturePack.cpp b/mv_image/image/src/Features/FeaturePack.cpp index 57338ff..d2ce616 100644 --- a/mv_image/image/src/Features/FeaturePack.cpp +++ b/mv_image/image/src/Features/FeaturePack.cpp @@ -16,7 +16,7 @@ #include "Features/FeaturePack.h" -#include +#include namespace MediaVision { namespace Image { diff --git a/mv_image/image/src/Features/ORBExtractorFactory.cpp b/mv_image/image/src/Features/ORBExtractorFactory.cpp index cc482ce..1dcded8 100644 --- a/mv_image/image/src/Features/ORBExtractorFactory.cpp +++ b/mv_image/image/src/Features/ORBExtractorFactory.cpp @@ -18,7 +18,7 @@ #include "ImageMathUtil.h" -#include +#include namespace MediaVision { namespace Image { @@ -33,17 +33,9 @@ ORBExtractorFactory::ORBExtractorFactory( cv::Ptr ORBExtractorFactory::buildFeatureExtractor() { cv::Ptr featureExtractor(new (std::nothrow)FeatureExtractor()); - if (featureExtractor == NULL) - return NULL; - cv::Ptr detector( - new (std::nothrow)cv::ORB( - __maximumFeaturesNumber, - __scaleFactor)); - if (detector == NULL) - return NULL; - - cv::Ptr extractor = detector; + cv::Ptr detector = cv::ORB::create(__maximumFeaturesNumber, __scaleFactor); + cv::Ptr extractor = detector; featureExtractor->setFeatureDetector(detector, KT_ORB); featureExtractor->setDescriptorExtractor(extractor, DT_ORB); diff --git a/mv_image/image/src/Recognition/ImageObject.cpp b/mv_image/image/src/Recognition/ImageObject.cpp index 057038e..60d30b2 100644 --- a/mv_image/image/src/Recognition/ImageObject.cpp +++ b/mv_image/image/src/Recognition/ImageObject.cpp @@ -26,10 +26,11 @@ #include "mv_common.h" #include -#include +#include #include #include +#include namespace MediaVision { namespace Image { diff --git a/mv_image/image/src/Tracking/AsyncTracker.cpp b/mv_image/image/src/Tracking/AsyncTracker.cpp index ea24f8a..8916784 100644 --- a/mv_image/image/src/Tracking/AsyncTracker.cpp +++ b/mv_image/image/src/Tracking/AsyncTracker.cpp @@ -22,7 +22,7 @@ namespace MediaVision { namespace Image { AsyncTracker::AsyncTracker(const AsyncTracker& copy) : - __baseTracker(copy.__baseTracker.obj->clone()), + __baseTracker(copy.__baseTracker.get()->clone()), __result(copy.__result), __isRun(false), __isUpdated(copy.__isUpdated), diff --git a/mv_image/image/src/Tracking/CascadeTracker.cpp b/mv_image/image/src/Tracking/CascadeTracker.cpp index 7110939..a60bbb2 100644 --- a/mv_image/image/src/Tracking/CascadeTracker.cpp +++ b/mv_image/image/src/Tracking/CascadeTracker.cpp @@ -49,7 +49,7 @@ bool CascadeTracker::track(const cv::Mat& frame, std::vector& result) std::set::iterator it = __trackers.begin(); for (; it != __trackers.end(); ++it) - if (!it->mTracker.obj->track(frame, it->mResult)) + if (!it->mTracker.get()->track(frame, it->mResult)) it->mResult.clear(); return mergeResults(result); @@ -60,7 +60,7 @@ void CascadeTracker::reinforcement(const std::vector& location) std::set::iterator it = __trackers.begin(); for (; it != __trackers.end(); ++it) - it->mTracker.obj->reinforcement(location); + it->mTracker.get()->reinforcement(location); } cv::Ptr CascadeTracker::clone() const @@ -76,7 +76,7 @@ CascadeTracker& CascadeTracker::operator=(const CascadeTracker& copy) std::set::iterator it = copy.__trackers.begin(); for (; it != copy.__trackers.end(); ++it) { - TrackerInfo temp(it->mTracker.obj->clone(), it->mPriority); + TrackerInfo temp(it->mTracker.get()->clone(), it->mPriority); temp.mResult = it->mResult; __trackers.insert(temp); @@ -121,7 +121,7 @@ void CascadeTracker::internalReinforcement() bool isUpdated = true; /* TODO: Redesign without dynamic_cast */ - AsyncTracker *asyncView = dynamic_cast(it1->mTracker.obj); + AsyncTracker *asyncView = dynamic_cast(it1->mTracker.get()); if (NULL != asyncView) isUpdated = asyncView->isUpdated(it1->mResult); @@ -135,7 +135,7 @@ void CascadeTracker::internalReinforcement() if (getQuadrangleArea(checkedArea.data()) < __minimumArea) { it1->mResult = std::vector(0); - it1->mTracker.obj->reinforcement(it1->mResult); + it1->mTracker.get()->reinforcement(it1->mResult); } float priority = it1->mPriority; @@ -143,7 +143,7 @@ void CascadeTracker::internalReinforcement() for (; it2 != __trackers.end(); ++it2) if (it1 != it2 && priority > it2->mPriority) - it2->mTracker.obj->reinforcement(it1->mResult); + it2->mTracker.get()->reinforcement(it1->mResult); } } } diff --git a/mv_image/image/src/Tracking/FeatureSubstitutionTracker.cpp b/mv_image/image/src/Tracking/FeatureSubstitutionTracker.cpp index 43805a8..b6e10fc 100644 --- a/mv_image/image/src/Tracking/FeatureSubstitutionTracker.cpp +++ b/mv_image/image/src/Tracking/FeatureSubstitutionTracker.cpp @@ -78,11 +78,11 @@ bool FeatureSubstitutionTracker::track( sceneImageObject->fill(frame, __featureExtractingParams, computeExpectedArea()); - ImageRecognizer recognizer(*sceneImageObject.obj); + ImageRecognizer recognizer(*sceneImageObject.get()); const bool isTracked = recognizer.recognize( - *__target.obj, + *(__target.get()), __recogParams, contour, __objectScalingFactor); diff --git a/mv_image/image/src/Tracking/ImageTrackingModel.cpp b/mv_image/image/src/Tracking/ImageTrackingModel.cpp index 3d78550..e0337ad 100644 --- a/mv_image/image/src/Tracking/ImageTrackingModel.cpp +++ b/mv_image/image/src/Tracking/ImageTrackingModel.cpp @@ -28,6 +28,7 @@ #include #include #include +#include namespace MediaVision { namespace Image { @@ -44,12 +45,13 @@ ImageTrackingModel::ImageTrackingModel() : ImageTrackingModel::ImageTrackingModel(const ImageTrackingModel& copy) : __target(copy.__target), - __tracker(copy.__tracker.empty()? NULL: copy.__tracker->clone()), __stabilizator(copy.__stabilizator), __location(copy.__location), __stabilizationParams(copy.__stabilizationParams) { - ; /* NULL */ + if (!copy.__tracker.empty()) + __tracker = copy.__tracker->clone(); + /* NULL */ } void ImageTrackingModel::setTarget(const ImageObject& target) diff --git a/mv_image/image/src/Tracking/MFTracker.cpp b/mv_image/image/src/Tracking/MFTracker.cpp index fd99019..72695b2 100644 --- a/mv_image/image/src/Tracking/MFTracker.cpp +++ b/mv_image/image/src/Tracking/MFTracker.cpp @@ -16,7 +16,8 @@ #include "Tracking/MFTracker.h" -#include +#include "opencv2/video/tracking.hpp" +#include "opencv2/imgproc.hpp" namespace MediaVision { namespace Image { @@ -205,13 +206,13 @@ bool MFTracker::medianFlowImpl( std::vector errors(numberOfPointsToTrackOld); std::vector tempPyramid; - cv::buildOpticalFlowPyramid( + buildOpticalFlowPyramid( newImage_gray, tempPyramid, __params.mWindowSize, __params.mPyrMaxLevel); - cv::calcOpticalFlowPyrLK(__pyramid, + calcOpticalFlowPyrLK(__pyramid, tempPyramid, pointsToTrackOld, pointsToTrackNew, diff --git a/mv_image/image/src/mv_image_open.cpp b/mv_image/image/src/mv_image_open.cpp index 38df14f..04d4a9a 100644 --- a/mv_image/image/src/mv_image_open.cpp +++ b/mv_image/image/src/mv_image_open.cpp @@ -26,7 +26,7 @@ #include "Recognition/ImageRecognizer.h" #include "Tracking/ImageTrackingModel.h" -#include +#include namespace { diff --git a/mv_surveillance/surveillance/include/EventTriggerPersonAppearance.h b/mv_surveillance/surveillance/include/EventTriggerPersonAppearance.h index a4ce5a0..4355107 100644 --- a/mv_surveillance/surveillance/include/EventTriggerPersonAppearance.h +++ b/mv_surveillance/surveillance/include/EventTriggerPersonAppearance.h @@ -27,9 +27,9 @@ #include "EventResult.h" #include "EventDefs.h" -#include "HoGDetector.h" -#include +#include +#include #include @@ -187,7 +187,7 @@ private: CVRectangles __disappearedRects; - modifiedcv::HOGDescriptor __hogClassifier; /**< Classifier to be used for full body + cv::HOGDescriptor __hogClassifier; /**< Classifier to be used for full body person detection */ MVRectangles __detectedLocations; diff --git a/mv_surveillance/surveillance/include/HoGDetector.h b/mv_surveillance/surveillance/include/HoGDetector.h deleted file mode 100644 index b4fd68f..0000000 --- a/mv_surveillance/surveillance/include/HoGDetector.h +++ /dev/null @@ -1,201 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2009, Willow Garage Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's 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. -// -// * The name of the copyright holders may not 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 Intel Corporation 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. -// -//M*/ - -#ifndef __MEDIA_VISION_HOGDETECTOR_H__ -#define __MEDIA_VISION_HOGDETECTOR_H__ - -/** - * @file HOGDetector.h - * @brief This file contains structure of HOG detector. - */ - -#include "opencv2/core/core.hpp" -#include "opencv2/objdetect/objdetect.hpp" - -#include - -namespace modifiedcv { - -using namespace cv; - -struct HOGDescriptor { - enum { L2Hys = 0 }; - enum { DEFAULT_NLEVELS = 64 }; - - /* default constructor */ - HOGDescriptor() : - winSize(64, 128), - blockSize(16, 16), - blockStride(8, 8), - cellSize(8, 8), - nbins(9), - derivAperture(1), - winSigma(-1), - histogramNormType(HOGDescriptor::L2Hys), - L2HysThreshold(0.2), - gammaCorrection(true), - nlevels(HOGDescriptor::DEFAULT_NLEVELS) - {} - - /* constructor */ - HOGDescriptor( - Size _winSize, - Size _blockSize, - Size _blockStride, - Size _cellSize, - int _nbins, - int _derivAperture = 1, - double _winSigma = -1., - int _histogramNormType = L2Hys, - double _L2HysThreshold = 0.2, - bool _gammaCorrection = false, - int _nlevels = DEFAULT_NLEVELS) : - winSize(_winSize), - blockSize(_blockSize), - blockStride(_blockStride), - cellSize(_cellSize), - nbins(_nbins), - derivAperture(_derivAperture), - winSigma(_winSigma), - histogramNormType(_histogramNormType), - L2HysThreshold(_L2HysThreshold), - gammaCorrection(_gammaCorrection), - nlevels(_nlevels) - {} - - /* default destructor */ - virtual ~HOGDescriptor() {} - - size_t getDescriptorSize() const; - - bool checkDetectorSize() const; - - double getWinSigma() const; - - virtual void setSVMDetector(InputArray _svmdetector); - - virtual void compute( - const Mat& img, - CV_OUT vector& descriptors, - Size winStride = Size(), - Size padding = Size(), - const vector& locations = vector()) const; - - /* with found weights output */ - virtual void detect( - const Mat& img, - CV_OUT vector& foundLocations, - CV_OUT vector& weights, - double hitThreshold = 0., - Size winStride = Size(), - Size padding = Size(), - const vector& searchLocations = vector()) const; - - /* without found weights output */ - virtual void detect( - const Mat& img, - CV_OUT vector& foundLocations, - double hitThreshold = 0., - Size winStride = Size(), - Size padding = Size(), - const vector& searchLocations = vector()) const; - - /* with result weights output */ - virtual void detectMultiScale( - const Mat& img, - CV_OUT vector& foundLocations, - CV_OUT vector& foundWeights, - double hitThreshold = 0, - Size winStride = Size(), - Size padding = Size(), - double scale = 1.05, - double finalThreshold = 2.0, - bool useMeanshiftGrouping = false) const; - - /* without found weights output */ - virtual void detectMultiScale( - const Mat& img, - CV_OUT vector& foundLocations, - double hitThreshold = 0., - Size winStride = Size(), - Size padding = Size(), - double scale = 1.05, - double finalThreshold = 2.0, - bool useMeanshiftGrouping = false) const; - - virtual void computeGradient( - const Mat& img, - CV_OUT Mat& grad, - CV_OUT Mat& angleOfs, - Size paddingTL = Size(), - Size paddingBR = Size()) const; - - static vector getDefaultPeopleDetector(); - - static vector getDaimlerPeopleDetector(); - - /* read/parse Dalal's alt model file */ - void readALTModel(std::string modelfile); - - void groupRectangles( - vector& rectList, - vector& weights, - int groupThreshold, - double eps) const; - - Size winSize; - Size blockSize; - Size blockStride; - Size cellSize; - int nbins; - int derivAperture; - double winSigma; - int histogramNormType; - double L2HysThreshold; - bool gammaCorrection; - vector svmDetector; - int nlevels; -}; - -} /* modifiedcv */ - -#endif /* __MEDIA_VISION_HOGDETECTOR_H__ */ diff --git a/mv_surveillance/surveillance/include/MFTracker.h b/mv_surveillance/surveillance/include/MFTracker.h index 947f6d4..4a58714 100644 --- a/mv_surveillance/surveillance/include/MFTracker.h +++ b/mv_surveillance/surveillance/include/MFTracker.h @@ -17,7 +17,7 @@ #ifndef __MEDIA_VISION_MFTRACKER_H__ #define __MEDIA_VISION_MFTRACKER_H__ -#include +#include namespace mediavision { namespace surveillance { diff --git a/mv_surveillance/surveillance/include/SurveillanceHelper.h b/mv_surveillance/surveillance/include/SurveillanceHelper.h index 1ad303a..9e0de18 100644 --- a/mv_surveillance/surveillance/include/SurveillanceHelper.h +++ b/mv_surveillance/surveillance/include/SurveillanceHelper.h @@ -24,7 +24,7 @@ #include -#include +#include namespace mediavision { namespace surveillance { diff --git a/mv_surveillance/surveillance/src/EventManager.cpp b/mv_surveillance/surveillance/src/EventManager.cpp index 77787f3..7dc2c09 100644 --- a/mv_surveillance/surveillance/src/EventManager.cpp +++ b/mv_surveillance/surveillance/src/EventManager.cpp @@ -22,7 +22,7 @@ #include "EventTriggerPersonRecognition.h" #include "EventTriggerMovementDetection.h" -#include +#include "mv_private.h" namespace mediavision { namespace surveillance { diff --git a/mv_surveillance/surveillance/src/EventTriggerMovementDetection.cpp b/mv_surveillance/surveillance/src/EventTriggerMovementDetection.cpp index af37537..6385f3a 100644 --- a/mv_surveillance/surveillance/src/EventTriggerMovementDetection.cpp +++ b/mv_surveillance/surveillance/src/EventTriggerMovementDetection.cpp @@ -22,7 +22,7 @@ #include -#include "opencv2/highgui/highgui.hpp" +#include "opencv2/highgui.hpp" namespace mediavision { namespace surveillance { diff --git a/mv_surveillance/surveillance/src/EventTriggerPersonAppearance.cpp b/mv_surveillance/surveillance/src/EventTriggerPersonAppearance.cpp index 59bc61a..f09f39d 100644 --- a/mv_surveillance/surveillance/src/EventTriggerPersonAppearance.cpp +++ b/mv_surveillance/surveillance/src/EventTriggerPersonAppearance.cpp @@ -21,8 +21,7 @@ #include "SurveillanceHelper.h" #include "EventTriggerMovementDetection.h" -#include "opencv2/opencv.hpp" -#include "opencv2/highgui/highgui.hpp" +#include "opencv2/highgui.hpp" #include diff --git a/mv_surveillance/surveillance/src/HoGDetector.cpp b/mv_surveillance/surveillance/src/HoGDetector.cpp deleted file mode 100644 index 4d1ea0c..0000000 --- a/mv_surveillance/surveillance/src/HoGDetector.cpp +++ /dev/null @@ -1,1006 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2009, Willow Garage Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's 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. -// -// * The name of the copyright holders may not 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 Intel Corporation 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. -// -//M*/ -#include -#include "HoGDetector.h" -#include "opencv2/imgproc/imgproc.hpp" -#include - -#ifdef ENABLE_NEON -#include -#endif - -#ifdef ENABLE_OMP -#include -#define NCORES 4 -static int coreids[NCORES] = {1, 2, 3, 4}; -#endif - -/****************************************************************************************\ - The code below is implementation of HOG (Histogram-of-Oriented Gradients) - descriptor and object detection, introduced by Navneet Dalal and Bill Triggs. - - The computed feature vectors are compatible with the - INRIA Object Detection and Localization Toolkit - (http://pascal.inrialpes.fr/soft/olt/) -\****************************************************************************************/ - -namespace modifiedcv { - -class ParallelLoopBodyWrapper { -public: - ParallelLoopBodyWrapper(const cv::ParallelLoopBody& _body, const cv::Range& _r) { - body = &_body; - wholeRange = _r; - nstripes = cvRound(wholeRange.end - wholeRange.start); - } - void operator()(const cv::Range& sr) const { - cv::Range r; - r.start = (int)(wholeRange.start + - ((uint64)sr.start*(wholeRange.end - wholeRange.start) + nstripes/2)/nstripes); - r.end = sr.end >= nstripes ? wholeRange.end : (int)(wholeRange.start + - ((uint64)sr.end*(wholeRange.end - wholeRange.start) + nstripes/2)/nstripes); - (*body)(r); - } - cv::Range stripeRange() const { - return cv::Range(0, nstripes); - } - -protected: - const cv::ParallelLoopBody* body; - cv::Range wholeRange; - int nstripes; -}; - -void parallel_for_(const cv::Range& range, const cv::ParallelLoopBody& body) -{ -#if defined ENABLE_OMP - ParallelLoopBodyWrapper pbody(body, range); - cv::Range stripeRange = pbody.stripeRange(); - int i = 0; - #pragma omp parallel for private(i) num_threads(NCORES) - for (i = stripeRange.start; i < stripeRange.end; ++i) { - cpu_set_t mask; - CPU_ZERO(&mask); - CPU_SET(coreids[i % 4], &mask); - - if (sched_setaffinity (0, sizeof(mask), &mask) == -1) { - printf("Could not set CPU Affinity, continuing..."); - } - - pbody(Range(i, i + 1)); - } -#else - cv::parallel_for_(range, body); -#endif -} - -size_t HOGDescriptor::getDescriptorSize() const -{ - return (size_t)nbins* - (blockSize.width/cellSize.width)* - (blockSize.height/cellSize.height)* - ((winSize.width - blockSize.width)/blockStride.width + 1)* - ((winSize.height - blockSize.height)/blockStride.height + 1); -} - -double HOGDescriptor::getWinSigma() const -{ - return winSigma >= 0 ? winSigma : (blockSize.width + blockSize.height)/8.; -} - -bool HOGDescriptor::checkDetectorSize() const -{ - size_t detectorSize = svmDetector.size(), descriptorSize = getDescriptorSize(); - return detectorSize == 0 || - detectorSize == descriptorSize || - detectorSize == descriptorSize + 1; -} - -void HOGDescriptor::setSVMDetector(InputArray _svmDetector) -{ - _svmDetector.getMat().convertTo(svmDetector, CV_32F); - CV_Assert(checkDetectorSize()); -} - -void HOGDescriptor::computeGradient(const Mat& img, Mat& grad, Mat& qangle, - Size paddingTL, Size paddingBR) const -{ - CV_Assert(img.type() == CV_8U); - - Size gradsize(img.cols + paddingTL.width + paddingBR.width, - img.rows + paddingTL.height + paddingBR.height); - grad.create(gradsize, CV_32FC2); /* */ - qangle.create(gradsize, CV_8UC2); /* [0..nbins-1] - quantized gradient orientation */ - Size wholeSize; - Point roiofs; - img.locateROI(wholeSize, roiofs); - - int i, x, y; - /* int cn = img.channels(); */ - - Mat_ _lut(1, 256); - const float* lut = &_lut(0, 0); - - if ( gammaCorrection ) - for ( i = 0; i < 256; i++ ) - _lut(0, i) = std::sqrt((float)i); - else - for ( i = 0; i < 256; i++ ) - _lut(0, i) = (float)i; - - AutoBuffer mapbuf(gradsize.width + gradsize.height + 4); - int* xmap = (int*)mapbuf + 1; - int* ymap = xmap + gradsize.width + 2; - - const int borderType = (int)cv::BORDER_REFLECT_101; - - for ( x = -1; x < gradsize.width + 1; x++ ) - xmap[x] = cv::borderInterpolate(x - paddingTL.width + roiofs.x, - wholeSize.width, borderType) - roiofs.x; - for ( y = -1; y < gradsize.height + 1; y++ ) - ymap[y] = cv::borderInterpolate(y - paddingTL.height + roiofs.y, - wholeSize.height, borderType) - roiofs.y; - - /* x- & y- derivatives for the whole row */ - int width = gradsize.width; - AutoBuffer _dbuf(width*4); - float* dbuf = _dbuf; - Mat Dx(1, width, CV_32F, dbuf); - Mat Dy(1, width, CV_32F, dbuf + width); - Mat Mag(1, width, CV_32F, dbuf + width*2); - Mat Angle(1, width, CV_32F, dbuf + width*3); - - int _nbins = nbins; - float angleScale = (float)(_nbins/CV_PI); - - for ( y = 0; y < gradsize.height; y++ ) { - const uchar* imgPtr = img.data + img.step*ymap[y]; - const uchar* prevPtr = img.data + img.step*ymap[y-1]; - const uchar* nextPtr = img.data + img.step*ymap[y+1]; - float* gradPtr = (float*)grad.ptr(y); - uchar* qanglePtr = (uchar*)qangle.ptr(y); - - for (x = 0; x < width; x++) { - int x1 = xmap[x]; - dbuf[x] = (float)(lut[imgPtr[xmap[x+1]]] - lut[imgPtr[xmap[x-1]]]); - dbuf[width + x] = (float)(lut[nextPtr[x1]] - lut[prevPtr[x1]]); - } - - cartToPolar(Dx, Dy, Mag, Angle, false); - - for (x = 0; x < width; x++) { - float mag = dbuf[x+width*2], angle = dbuf[x+width*3]*angleScale - 0.5f; - int hidx = cvFloor(angle); - angle -= hidx; - gradPtr[x*2] = mag*(1.f - angle); - gradPtr[x*2+1] = mag*angle; - - if ( hidx < 0 ) - hidx += _nbins; - else if ( hidx >= _nbins ) - hidx -= _nbins; - assert((unsigned)hidx < (unsigned)_nbins); - - qanglePtr[x*2] = (uchar)hidx; - hidx++; - hidx &= hidx < _nbins ? -1 : 0; - qanglePtr[x*2+1] = (uchar)hidx; - } - } -} - - -struct HOGCache { - struct BlockData { - BlockData() : histOfs(0), imgOffset() {} - int histOfs; - Point imgOffset; - }; - - struct PixData { - size_t gradOfs, qangleOfs; - int histOfs[4]; - float histWeights[4]; - float gradWeight; - }; - - HOGCache(); - HOGCache(const HOGDescriptor* descriptor, - const Mat& img, Size paddingTL, Size paddingBR, - bool useCache, Size cacheStride); - virtual ~HOGCache() {}; - virtual void init(const HOGDescriptor* descriptor, - const Mat& img, Size paddingTL, Size paddingBR, - bool useCache, Size cacheStride); - - Size windowsInImage(Size imageSize, Size winStride) const; - Rect getWindow(Size imageSize, Size winStride, int idx) const; - - const float* getBlock(Point pt, float* buf); - virtual void normalizeBlockHistogram(float* histogram) const; - - vector pixData; - vector blockData; - - bool useCache; - vector ymaxCached; - Size winSize, cacheStride; - Size nblocks, ncells; - int blockHistogramSize; - int count1, count2, count4; - Point imgoffset; - Mat_ blockCache; - Mat_ blockCacheFlags; - - Mat grad, qangle; - const HOGDescriptor* descriptor; -}; - - -HOGCache::HOGCache() -{ - useCache = false; - blockHistogramSize = count1 = count2 = count4 = 0; - descriptor = 0; -} - -HOGCache::HOGCache(const HOGDescriptor* _descriptor, - const Mat& _img, Size _paddingTL, Size _paddingBR, - bool _useCache, Size _cacheStride) -{ - init(_descriptor, _img, _paddingTL, _paddingBR, _useCache, _cacheStride); -} - -void HOGCache::init(const HOGDescriptor* _descriptor, - const Mat& _img, Size _paddingTL, Size _paddingBR, - bool _useCache, Size _cacheStride) -{ - descriptor = _descriptor; - cacheStride = _cacheStride; - useCache = _useCache; - - descriptor->computeGradient(_img, grad, qangle, _paddingTL, _paddingBR); - imgoffset = _paddingTL; - - winSize = descriptor->winSize; - Size blockSize = descriptor->blockSize; - Size blockStride = descriptor->blockStride; - Size cellSize = descriptor->cellSize; - int i, j, nbins = descriptor->nbins; - int rawBlockSize = blockSize.width*blockSize.height; - - nblocks = Size((winSize.width - blockSize.width)/blockStride.width + 1, - (winSize.height - blockSize.height)/blockStride.height + 1); - ncells = Size(blockSize.width/cellSize.width, blockSize.height/cellSize.height); - blockHistogramSize = ncells.width*ncells.height*nbins; - - if ( useCache ) { - Size cacheSize((grad.cols - blockSize.width)/cacheStride.width+1, - (winSize.height/cacheStride.height)+1); - blockCache.create(cacheSize.height, cacheSize.width*blockHistogramSize); - blockCacheFlags.create(cacheSize); - size_t cacheRows = blockCache.rows; - ymaxCached.resize(cacheRows); - for (size_t ii = 0; ii < cacheRows; ii++ ) - ymaxCached[ii] = -1; - } - - Mat_ weights(blockSize); - float sigma = (float)descriptor->getWinSigma(); - float scale = 1.f/(sigma*sigma*2); - - float blockHalfHeight = blockSize.height*0.5f; - float blockHalfWidth = blockSize.width*0.5f; - for (i = 0; i < blockSize.height; i++) - for (j = 0; j < blockSize.width; j++) { - float di = i - blockHalfHeight; - float dj = j - blockHalfWidth; - weights(i, j) = std::exp(-(di*di + dj*dj)*scale); - } - - blockData.resize(nblocks.width*nblocks.height); - pixData.resize(rawBlockSize*3); - - /* - * Initialize 2 lookup tables, pixData & blockData. - * Here is why: - * - * The detection algorithm runs in 4 nested loops (at each pyramid layer): - * loop over the windows within the input image - * loop over the blocks within each window - * loop over the cells within each block - * loop over the pixels in each cell - * - * As each of the loops runs over a 2-dimensional array, - * we could get 8(!) nested loops in total, which is very-very slow. - * - * To speed the things up, we do the following: - * 1. loop over windows is unrolled in the HOGDescriptor::{compute|detect} methods; - * inside we compute the current search window using getWindow() method. - * Yes, it involves some overhead (function call + couple of divisions), - * but it's tiny in fact. - * 2. loop over the blocks is also unrolled. Inside we use pre-computed blockData[j] - * to set up gradient and histogram pointers. - * 3. loops over cells and pixels in each cell are merged - * (since there is no overlap between cells, each pixel in the block is processed once) - * and also unrolled. Inside we use PixData[k] to access the gradient values and - * update the histogram - */ - - count1 = count2 = count4 = 0; - for ( j = 0; j < blockSize.width; j++ ) - for ( i = 0; i < blockSize.height; i++ ) { - PixData* data = 0; - float cellX = (j+0.5f)/cellSize.width - 0.5f; - float cellY = (i+0.5f)/cellSize.height - 0.5f; - int icellX0 = cvFloor(cellX); - int icellY0 = cvFloor(cellY); - int icellX1 = icellX0 + 1, icellY1 = icellY0 + 1; - cellX -= icellX0; - cellY -= icellY0; - - if ( (unsigned)icellX0 < (unsigned)ncells.width && - (unsigned)icellX1 < (unsigned)ncells.width ) { - if ( (unsigned)icellY0 < (unsigned)ncells.height && - (unsigned)icellY1 < (unsigned)ncells.height ) { - data = &pixData[rawBlockSize*2 + (count4++)]; - data->histOfs[0] = (icellX0*ncells.height + icellY0)*nbins; - data->histWeights[0] = (1.f - cellX)*(1.f - cellY); - data->histOfs[1] = (icellX1*ncells.height + icellY0)*nbins; - data->histWeights[1] = cellX*(1.f - cellY); - data->histOfs[2] = (icellX0*ncells.height + icellY1)*nbins; - data->histWeights[2] = (1.f - cellX)*cellY; - data->histOfs[3] = (icellX1*ncells.height + icellY1)*nbins; - data->histWeights[3] = cellX*cellY; - } else { - data = &pixData[rawBlockSize + (count2++)]; - if ( (unsigned)icellY0 < (unsigned)ncells.height ) { - icellY1 = icellY0; - cellY = 1.f - cellY; - } - data->histOfs[0] = (icellX0*ncells.height + icellY1)*nbins; - data->histWeights[0] = (1.f - cellX)*cellY; - data->histOfs[1] = (icellX1*ncells.height + icellY1)*nbins; - data->histWeights[1] = cellX*cellY; - data->histOfs[2] = data->histOfs[3] = 0; - data->histWeights[2] = data->histWeights[3] = 0; - } - } else { - if ( (unsigned)icellX0 < (unsigned)ncells.width ) { - icellX1 = icellX0; - cellX = 1.f - cellX; - } - - if ( (unsigned)icellY0 < (unsigned)ncells.height && - (unsigned)icellY1 < (unsigned)ncells.height ) { - data = &pixData[rawBlockSize + (count2++)]; - data->histOfs[0] = (icellX1*ncells.height + icellY0)*nbins; - data->histWeights[0] = cellX*(1.f - cellY); - data->histOfs[1] = (icellX1*ncells.height + icellY1)*nbins; - data->histWeights[1] = cellX*cellY; - data->histOfs[2] = data->histOfs[3] = 0; - data->histWeights[2] = data->histWeights[3] = 0; - } else { - data = &pixData[count1++]; - if ( (unsigned)icellY0 < (unsigned)ncells.height ) { - icellY1 = icellY0; - cellY = 1.f - cellY; - } - data->histOfs[0] = (icellX1*ncells.height + icellY1)*nbins; - data->histWeights[0] = cellX*cellY; - data->histOfs[1] = data->histOfs[2] = data->histOfs[3] = 0; - data->histWeights[1] = data->histWeights[2] = data->histWeights[3] = 0; - } - } - data->gradOfs = (grad.cols*i + j)*2; - data->qangleOfs = (qangle.cols*i + j)*2; - data->gradWeight = weights(i, j); - } - - assert(count1 + count2 + count4 == rawBlockSize); - /* defragment pixData */ - for ( j = 0; j < count2; j++ ) - pixData[j + count1] = pixData[j + rawBlockSize]; - for ( j = 0; j < count4; j++ ) - pixData[j + count1 + count2] = pixData[j + rawBlockSize*2]; - count2 += count1; - count4 += count2; - - /* initialize blockData */ - for ( j = 0; j < nblocks.width; j++ ) - for ( i = 0; i < nblocks.height; i++ ) { - BlockData& data = blockData[j*nblocks.height + i]; - data.histOfs = (j*nblocks.height + i)*blockHistogramSize; - data.imgOffset = Point(j*blockStride.width, i*blockStride.height); - } -} - - -const float* HOGCache::getBlock(Point pt, float* buf) -{ - float* blockHist = buf; - assert(descriptor != 0); - - Size blockSize = descriptor->blockSize; - pt += imgoffset; - - CV_Assert( (unsigned)pt.x <= (unsigned)(grad.cols - blockSize.width) && - (unsigned)pt.y <= (unsigned)(grad.rows - blockSize.height) ); - - if ( useCache ) { - CV_Assert(pt.x % cacheStride.width == 0 && - pt.y % cacheStride.height == 0); - Point cacheIdx(pt.x/cacheStride.width, - (pt.y/cacheStride.height) % blockCache.rows); - if ( pt.y != ymaxCached[cacheIdx.y] ) { - Mat_ cacheRow = blockCacheFlags.row(cacheIdx.y); - cacheRow = (uchar)0; - ymaxCached[cacheIdx.y] = pt.y; - } - - blockHist = &blockCache[cacheIdx.y][cacheIdx.x*blockHistogramSize]; - uchar& computedFlag = blockCacheFlags(cacheIdx.y, cacheIdx.x); - if ( computedFlag != 0 ) - return blockHist; - computedFlag = (uchar)1; /* set it at once, before actual computing */ - } - - int k, C1 = count1, C2 = count2, C4 = count4; - const float* gradPtr = (const float*)(grad.data + grad.step*pt.y) + pt.x*2; - const uchar* qanglePtr = qangle.data + qangle.step*pt.y + pt.x*2; - - CV_Assert(blockHist != 0); - for ( k = 0; k < blockHistogramSize; k++ ) - blockHist[k] = 0.f; - - const PixData* _pixData = &pixData[0]; - - for ( k = 0; k < C1; k++ ) { - const PixData& pk = _pixData[k]; - const float* a = gradPtr + pk.gradOfs; - float w = pk.gradWeight*pk.histWeights[0]; - const uchar* h = qanglePtr + pk.qangleOfs; - int h0 = h[0], h1 = h[1]; - float* hist = blockHist + pk.histOfs[0]; - float t0 = hist[h0] + a[0]*w; - float t1 = hist[h1] + a[1]*w; - hist[h0] = t0; - hist[h1] = t1; - } - - for ( ; k < C2; k++ ) { - const PixData& pk = _pixData[k]; - const float* a = gradPtr + pk.gradOfs; - float w, t0, t1, a0 = a[0], a1 = a[1]; - const uchar* h = qanglePtr + pk.qangleOfs; - int h0 = h[0], h1 = h[1]; - - float* hist = blockHist + pk.histOfs[0]; - w = pk.gradWeight*pk.histWeights[0]; - t0 = hist[h0] + a0*w; - t1 = hist[h1] + a1*w; - hist[h0] = t0; - hist[h1] = t1; - - hist = blockHist + pk.histOfs[1]; - w = pk.gradWeight*pk.histWeights[1]; - t0 = hist[h0] + a0*w; - t1 = hist[h1] + a1*w; - hist[h0] = t0; - hist[h1] = t1; - } - - for ( ; k < C4; k++ ) { - const PixData& pk = _pixData[k]; - const float* a = gradPtr + pk.gradOfs; - float w, t0, t1, a0 = a[0], a1 = a[1]; - const uchar* h = qanglePtr + pk.qangleOfs; - int h0 = h[0], h1 = h[1]; - - float* hist = blockHist + pk.histOfs[0]; - w = pk.gradWeight*pk.histWeights[0]; - t0 = hist[h0] + a0*w; - t1 = hist[h1] + a1*w; - hist[h0] = t0; - hist[h1] = t1; - - hist = blockHist + pk.histOfs[1]; - w = pk.gradWeight*pk.histWeights[1]; - t0 = hist[h0] + a0*w; - t1 = hist[h1] + a1*w; - hist[h0] = t0; - hist[h1] = t1; - - hist = blockHist + pk.histOfs[2]; - w = pk.gradWeight*pk.histWeights[2]; - t0 = hist[h0] + a0*w; - t1 = hist[h1] + a1*w; - hist[h0] = t0; - hist[h1] = t1; - - hist = blockHist + pk.histOfs[3]; - w = pk.gradWeight*pk.histWeights[3]; - t0 = hist[h0] + a0*w; - t1 = hist[h1] + a1*w; - hist[h0] = t0; - hist[h1] = t1; - } - - normalizeBlockHistogram(blockHist); - - return blockHist; -} - -void HOGCache::normalizeBlockHistogram(float* _hist) const -{ -#ifdef ENABLE_NEON - /* NEON vector for loading the histogram to the memory */ - float32x4_t hist_v; - /* Initialize the accumulator for summation storing */ - float32x4_t acc = vdupq_n_f32(0.f); -#endif - - /* Histogram pointer in the memory */ - float *hist_ptr = &_hist[0]; - /* Variable to store values of summations */ - float sum = 0.f; - size_t sz = blockHistogramSize; - -#ifdef ENABLE_NEON - for (; sz != 0u; sz -= 4u) { - hist_v = vld1q_f32(hist_ptr); - acc = vmlaq_f32(acc, hist_v, hist_v); - hist_ptr += 4; - } - - sum += vgetq_lane_f32(acc, 0) + vgetq_lane_f32(acc, 1) + - vgetq_lane_f32(acc, 2) + vgetq_lane_f32(acc, 3); - - /* Reset accumulator */ - acc = vdupq_n_f32(0.f); - - sz = blockHistogramSize; - hist_ptr = &_hist[0]; -#else - for (size_t i = 0; i < sz; ++i) - sum += hist_ptr[i] * hist_ptr[i]; -#endif - - float scale = 1.f / (std::sqrt(sum) + sz * 0.1f); - sum = 0.f; - -#ifdef ENABLE_NEON - float32x4_t thres_v = vdupq_n_f32((float)descriptor->L2HysThreshold); - - for (; sz != 0; sz -= 4) { - /* Find minimal value among threshold and histogram value, accumulate - * this value squared */ - hist_v = vminq_f32(vmulq_n_f32(vld1q_f32(hist_ptr), scale), thres_v); - acc = vmlaq_f32(acc, hist_v, hist_v); - /* Update histograms in memory according with found min values */ - vst1q_f32(hist_ptr, hist_v); - hist_ptr += 4; - } - - sum += vgetq_lane_f32(acc, 0) + vgetq_lane_f32(acc, 1) + - vgetq_lane_f32(acc, 2) + vgetq_lane_f32(acc, 3); - -#else - float thresh = (float)descriptor->L2HysThreshold; - for (size_t i = 0; i < sz; ++i) { - hist_ptr[i] = std::min(hist_ptr[i] * scale, thresh); - sum += hist_ptr[i] * hist_ptr[i]; - } -#endif - - scale = 1.f / (std::sqrt(sum) + 1e-3f); - -#ifdef ENABLE_NEON - sz = blockHistogramSize; - hist_ptr = &_hist[0]; - - /* Scale histogram (normalize): */ - for (; sz != 0; sz -= 4) { - vst1q_f32(hist_ptr, vmulq_n_f32(vld1q_f32(hist_ptr), scale)); - hist_ptr += 4; - } -#else - for (size_t i = 0; i < sz; i++ ) - hist_ptr[i] *= scale; -#endif -} - - -Size HOGCache::windowsInImage(Size imageSize, Size winStride) const -{ - return Size((imageSize.width - winSize.width)/winStride.width + 1, - (imageSize.height - winSize.height)/winStride.height + 1); -} - -Rect HOGCache::getWindow(Size imageSize, Size winStride, int idx) const -{ - int nwindowsX = (imageSize.width - winSize.width)/winStride.width + 1; - int y = idx / nwindowsX; - int x = idx - nwindowsX*y; - return Rect( x*winStride.width, y*winStride.height, winSize.width, winSize.height ); -} - - -void HOGDescriptor::compute(const Mat& img, vector& descriptors, - Size winStride, Size padding, - const vector& locations) const -{ - if ( winStride == Size() ) - winStride = cellSize; - Size cacheStride(gcd(winStride.width, blockStride.width), - gcd(winStride.height, blockStride.height)); - size_t nwindows = locations.size(); - padding.width = (int)alignSize(std::max(padding.width, 0), cacheStride.width); - padding.height = (int)alignSize(std::max(padding.height, 0), cacheStride.height); - Size paddedImgSize(img.cols + padding.width*2, img.rows + padding.height*2); - - HOGCache cache(this, img, padding, padding, nwindows == 0, cacheStride); - - if ( !nwindows ) - nwindows = cache.windowsInImage(paddedImgSize, winStride).area(); - - const HOGCache::BlockData* blockData = &cache.blockData[0]; - - int nblocks = cache.nblocks.area(); - int blockHistogramSize = cache.blockHistogramSize; - size_t dsize = getDescriptorSize(); - descriptors.resize(dsize*nwindows); - - for ( size_t i = 0; i < nwindows; i++ ) { - float* descriptor = &descriptors[i*dsize]; - - Point pt0; - if ( !locations.empty() ) { - pt0 = locations[i]; - if ( pt0.x < -padding.width || pt0.x > img.cols + padding.width - winSize.width || - pt0.y < -padding.height || pt0.y > img.rows + padding.height - winSize.height ) - continue; - } else { - pt0 = cache.getWindow(paddedImgSize, winStride, (int)i).tl() - Point(padding); - CV_Assert(pt0.x % cacheStride.width == 0 && pt0.y % cacheStride.height == 0); - } - - for ( int j = 0; j < nblocks; j++ ) { - const HOGCache::BlockData& bj = blockData[j]; - Point pt = pt0 + bj.imgOffset; - - float* dst = descriptor + bj.histOfs; - const float* src = cache.getBlock(pt, dst); - if ( src != dst ) - for ( int k = 0; k < blockHistogramSize; k++ ) - dst[k] = src[k]; - } - } -} - - -void HOGDescriptor::detect(const Mat& img, - vector& hits, vector& weights, double hitThreshold, - Size winStride, Size padding, const vector& locations) const -{ - hits.clear(); - if ( svmDetector.empty() ) - return; - - if ( winStride == Size() ) - winStride = cellSize; - Size cacheStride(gcd(winStride.width, blockStride.width), - gcd(winStride.height, blockStride.height)); - size_t nwindows = locations.size(); - padding.width = (int)alignSize(std::max(padding.width, 0), cacheStride.width); - padding.height = (int)alignSize(std::max(padding.height, 0), cacheStride.height); - Size paddedImgSize(img.cols + padding.width*2, img.rows + padding.height*2); - - HOGCache cache(this, img, padding, padding, nwindows == 0, cacheStride); - - if ( !nwindows ) - nwindows = cache.windowsInImage(paddedImgSize, winStride).area(); - - const HOGCache::BlockData* blockData = &cache.blockData[0]; - - int nblocks = cache.nblocks.area(); - int blockHistogramSize = cache.blockHistogramSize; - size_t dsize = getDescriptorSize(); - - double rho = svmDetector.size() > dsize ? svmDetector[dsize] : 0; - vector blockHist(blockHistogramSize); - - for ( size_t i = 0; i < nwindows; i++ ) { - Point pt0; - if ( !locations.empty() ) { - pt0 = locations[i]; - if ( pt0.x < -padding.width || pt0.x > img.cols + padding.width - winSize.width || - pt0.y < -padding.height || pt0.y > img.rows + padding.height - winSize.height ) - continue; - } else { - pt0 = cache.getWindow(paddedImgSize, winStride, (int)i).tl() - Point(padding); - CV_Assert(pt0.x % cacheStride.width == 0 && pt0.y % cacheStride.height == 0); - } - double s = rho; - const float* svmVec = &svmDetector[0]; - int j, k; - - for ( j = 0; j < nblocks; j++, svmVec += blockHistogramSize ) { - const HOGCache::BlockData& bj = blockData[j]; - Point pt = pt0 + bj.imgOffset; - - const float* vec = cache.getBlock(pt, &blockHist[0]); -#ifdef ENABLE_NEON - float32x4_t vec_v; /* NEON feature vector */ - float32x4_t svm_v; /* NEON SVM feature weights */ - float32x4_t acc = vdupq_n_f32(0.f); /* NEON partial sum */ - for ( k = 0; k <= blockHistogramSize - 4; k += 4 ) { - vec_v = vld1q_f32(vec + k); - svm_v = vld1q_f32(svmVec + k); - acc = vmlaq_f32(acc, vec_v, svm_v); - } - - s += vgetq_lane_f32(acc, 0) + vgetq_lane_f32(acc, 1) + - vgetq_lane_f32(acc, 2) + vgetq_lane_f32(acc, 3); - -#else - for ( k = 0; k <= blockHistogramSize - 4; k += 4 ) - s += vec[k]*svmVec[k] + vec[k+1]*svmVec[k+1] + - vec[k+2]*svmVec[k+2] + vec[k+3]*svmVec[k+3]; -#endif - for ( ; k < blockHistogramSize; k++ ) - s += vec[k]*svmVec[k]; - } - - if ( s >= hitThreshold ) { - hits.push_back(pt0); - weights.push_back(s); - } - } -} - -void HOGDescriptor::detect(const Mat& img, vector& hits, double hitThreshold, - Size winStride, Size padding, const vector& locations) const -{ - vector weightsV; - detect(img, hits, weightsV, hitThreshold, winStride, padding, locations); -} - -class HOGInvoker : public ParallelLoopBody { - public: - HOGInvoker(const HOGDescriptor* _hog, const Mat& _img, - double _hitThreshold, Size _winStride, Size _padding, - const double* _levelScale, std::vector * _vec, Mutex* _mtx, - std::vector* _weights = 0, std::vector* _scales = 0) { - hog = _hog; - img = _img; - hitThreshold = _hitThreshold; - winStride = _winStride; - padding = _padding; - levelScale = _levelScale; - vec = _vec; - weights = _weights; - scales = _scales; - mtx = _mtx; - } - - void operator()(const Range& range) const { - int i, i1 = range.start, i2 = range.end; - double minScale = i1 > 0 ? levelScale[i1] : i2 > 1 ? levelScale[i1+1] : std::max(img.cols, img.rows); - Size maxSz(cvCeil(img.cols/minScale), cvCeil(img.rows/minScale)); - Mat smallerImgBuf(maxSz, img.type()); - vector locations; - vector hitsWeights; - - Size wholeSize; - Point offset; - img.locateROI(wholeSize, offset); - - for ( i = i1; i < i2; i++ ) { - double scale = levelScale[i]; - Size sz(cvRound(img.cols/scale), cvRound(img.rows/scale)); - Mat smallerImg(sz, img.type(), smallerImgBuf.data); - if (sz == img.size()) - smallerImg = Mat(sz, img.type(), img.data, img.step); - else - resize(img, smallerImg, sz); - hog->detect(smallerImg, locations, hitsWeights, hitThreshold, winStride, padding); - - Size scaledWinSize = Size(cvRound(hog->winSize.width*scale), cvRound(hog->winSize.height*scale)); - - mtx->lock(); - for ( size_t j = 0; j < locations.size(); j++ ) { - vec->push_back(Rect(cvRound(locations[j].x*scale), - cvRound(locations[j].y*scale), - scaledWinSize.width, scaledWinSize.height)); - if (scales) { - scales->push_back(scale); - } - } - mtx->unlock(); - - if (weights && (!hitsWeights.empty())) { - mtx->lock(); - for (size_t j = 0; j < locations.size(); j++) { - weights->push_back(hitsWeights[j]); - } - mtx->unlock(); - } - } - } - - const HOGDescriptor* hog; - Mat img; - double hitThreshold; - Size winStride; - Size padding; - const double* levelScale; - std::vector* vec; - std::vector* weights; - std::vector* scales; - Mutex* mtx; -}; - - -void HOGDescriptor::detectMultiScale( - const Mat& img, vector& foundLocations, vector& foundWeights, - double hitThreshold, Size winStride, Size padding, - double scale0, double finalThreshold, bool useMeanshiftGrouping) const -{ - double scale = 1.; - int levels = 0; - - vector levelScale; - for ( levels = 0; levels < nlevels; levels++ ) { - levelScale.push_back(scale); - if ( cvRound(img.cols/scale) < winSize.width || - cvRound(img.rows/scale) < winSize.height || - scale0 <= 1 ) - break; - scale *= scale0; - } - levels = std::max(levels, 1); - levelScale.resize(levels); - - std::vector allCandidates; - std::vector tempScales; - std::vector tempWeights; - std::vector foundScales; - Mutex mtx; - - modifiedcv::parallel_for_(Range(0, (int)levelScale.size()), - HOGInvoker(this, img, hitThreshold, winStride, padding, &levelScale[0], &allCandidates, &mtx, &tempWeights, &tempScales)); - - std::copy(tempScales.begin(), tempScales.end(), back_inserter(foundScales)); - foundLocations.clear(); - std::copy(allCandidates.begin(), allCandidates.end(), back_inserter(foundLocations)); - foundWeights.clear(); - std::copy(tempWeights.begin(), tempWeights.end(), back_inserter(foundWeights)); - - if ( useMeanshiftGrouping ) { - groupRectangles_meanshift(foundLocations, foundWeights, foundScales, finalThreshold, winSize); - } else { - groupRectangles(foundLocations, foundWeights, (int)finalThreshold, 0.2); - } -} - -void HOGDescriptor::detectMultiScale(const Mat& img, vector& foundLocations, - double hitThreshold, Size winStride, Size padding, - double scale0, double finalThreshold, bool useMeanshiftGrouping) const -{ - vector foundWeights; - detectMultiScale(img, foundLocations, foundWeights, hitThreshold, winStride, - padding, scale0, finalThreshold, useMeanshiftGrouping); -} - -void HOGDescriptor::groupRectangles(vector& rectList, vector& weights, int groupThreshold, double eps) const -{ - if ( groupThreshold <= 0 || rectList.empty() ) { - return; - } - - CV_Assert(rectList.size() == weights.size()); - - vector labels; - int nclasses = partition(rectList, labels, SimilarRects(eps)); - - vector > rrects(nclasses); - vector numInClass(nclasses, 0); - vector foundWeights(nclasses, DBL_MIN); - int i, j, nlabels = (int)labels.size(); - - for ( i = 0; i < nlabels; i++ ) { - int cls = labels[i]; - rrects[cls].x += rectList[i].x; - rrects[cls].y += rectList[i].y; - rrects[cls].width += rectList[i].width; - rrects[cls].height += rectList[i].height; - foundWeights[cls] = max(foundWeights[cls], weights[i]); - numInClass[cls]++; - } - - for ( i = 0; i < nclasses; i++ ) { - /* find the average of all ROI in the cluster */ - cv::Rect_ r = rrects[i]; - double s = 1.0/numInClass[i]; - rrects[i] = cv::Rect_(cv::saturate_cast(r.x*s), - cv::saturate_cast(r.y*s), - cv::saturate_cast(r.width*s), - cv::saturate_cast(r.height*s)); - } - - rectList.clear(); - weights.clear(); - - for ( i = 0; i < nclasses; i++ ) { - cv::Rect r1 = rrects[i]; - int n1 = numInClass[i]; - double w1 = foundWeights[i]; - if ( n1 <= groupThreshold ) - continue; - /* filter out small rectangles inside large rectangles */ - for ( j = 0; j < nclasses; j++ ) { - int n2 = numInClass[j]; - - if ( j == i || n2 <= groupThreshold ) - continue; - - cv::Rect r2 = rrects[j]; - - int dx = cv::saturate_cast(r2.width * eps); - int dy = cv::saturate_cast(r2.height * eps); - - if ( r1.x >= r2.x - dx && - r1.y >= r2.y - dy && - r1.x + r1.width <= r2.x + r2.width + dx && - r1.y + r1.height <= r2.y + r2.height + dy && - (n2 > std::max(3, n1) || n1 < 3) ) - break; - } - - if ( j == nclasses ) { - rectList.push_back(r1); - weights.push_back(w1); - } - } -} -} diff --git a/mv_surveillance/surveillance/src/MFTracker.cpp b/mv_surveillance/surveillance/src/MFTracker.cpp index b5e6da5..85b9803 100644 --- a/mv_surveillance/surveillance/src/MFTracker.cpp +++ b/mv_surveillance/surveillance/src/MFTracker.cpp @@ -16,7 +16,8 @@ #include "MFTracker.h" -#include +#include "opencv2/video/tracking.hpp" +#include "opencv2/imgproc.hpp" namespace mediavision { namespace surveillance { @@ -169,13 +170,13 @@ bool MFTracker::medianFlowImpl( std::vector errors(numberOfPointsToTrackOld); std::vector tempPyramid; - cv::buildOpticalFlowPyramid( + buildOpticalFlowPyramid( newImage_gray, tempPyramid, __params.mWindowSize, __params.mPyrMaxLevel); - cv::calcOpticalFlowPyrLK(__pyramid, + calcOpticalFlowPyrLK(__pyramid, tempPyramid, pointsToTrackOld, pointsToTrackNew, diff --git a/mv_surveillance/surveillance/src/SurveillanceHelper.cpp b/mv_surveillance/surveillance/src/SurveillanceHelper.cpp index bbd92e9..d2dddcc 100644 --- a/mv_surveillance/surveillance/src/SurveillanceHelper.cpp +++ b/mv_surveillance/surveillance/src/SurveillanceHelper.cpp @@ -16,9 +16,10 @@ #include "SurveillanceHelper.h" -#include +#include "mv_private.h" -#include "opencv2/highgui/highgui.hpp" +#include "opencv2/imgproc.hpp" +#include "opencv2/highgui.hpp" namespace mediavision { namespace surveillance { diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec index a66512b..56ee7bb 100644 --- a/packaging/capi-media-vision.spec +++ b/packaging/capi-media-vision.spec @@ -1,6 +1,6 @@ Name: capi-media-vision Summary: Media Vision library for Tizen Native API -Version: 0.3.30 +Version: 0.4.0 Release: 1 Group: Multimedia/Framework License: Apache-2.0 and BSD-3-Clause @@ -10,7 +10,7 @@ BuildRequires: pkgconfig(capi-media-tool) BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(capi-system-info) -BuildRequires: pkgconfig(opencv) +BuildRequires: pkgconfig(opencv) >= 3.4.0 BuildRequires: pkgconfig(zbar) BuildRequires: pkgconfig(glib-2.0) # Change to the pkgconfig(zint) after zint package refactor diff --git a/test/testsuites/common/image_helper/src/ImageHelper.cpp b/test/testsuites/common/image_helper/src/ImageHelper.cpp index b72c2e3..a02486c 100644 --- a/test/testsuites/common/image_helper/src/ImageHelper.cpp +++ b/test/testsuites/common/image_helper/src/ImageHelper.cpp @@ -23,9 +23,9 @@ #include -#include -#include -#include +#include +#include +#include /** * @file ImageHelper.cpp diff --git a/test/testsuites/common/image_helper/src/image_helper.cpp b/test/testsuites/common/image_helper/src/image_helper.cpp index 616e411..c4d9698 100644 --- a/test/testsuites/common/image_helper/src/image_helper.cpp +++ b/test/testsuites/common/image_helper/src/image_helper.cpp @@ -19,7 +19,7 @@ #include "mv_private.h" #include "ImageHelper.h" -#include +#include /** * @file image_helper.cpp -- 2.7.4 From 824fc757720f3bbc624195e105e3e24b562f9464 Mon Sep 17 00:00:00 2001 From: Tae-Young Chung Date: Thu, 15 Mar 2018 17:06:13 +0900 Subject: [PATCH 06/16] Fix ParseOpenCVLabels Since OpenCV 3.4.x, FaceRecognizer Class doesn't provide getLabels(). Instead, each algorithm provides getLabels(). OpenCV should be equal to or greater than 3.4.1 Change-Id: Iec123273bb347713fa648a505ec78922b2008b9c Signed-off-by: Tae-Young Chung --- mv_face/face/src/FaceRecognitionModel.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/mv_face/face/src/FaceRecognitionModel.cpp b/mv_face/face/src/FaceRecognitionModel.cpp index 32a6d8c..b9f4971 100644 --- a/mv_face/face/src/FaceRecognitionModel.cpp +++ b/mv_face/face/src/FaceRecognitionModel.cpp @@ -123,12 +123,10 @@ int CopyOpenCVAlgorithmParameters(const cv::Ptr& srcAl } void ParseOpenCVLabels( - const cv::Ptr& recognizer, + const cv::Mat labels, std::set& outLabels) { - if (!recognizer.empty()) { - cv::Mat labels = (dynamic_cast(recognizer.get()))->getLabels(); - + if (!labels.empty()) { for (int i = 0; i < labels.rows; ++i) outLabels.insert(labels.at(i, 0)); } @@ -295,6 +293,7 @@ int FaceRecognitionModel::load(const std::string& fileName) cv::Ptr tempRecognizer; FaceRecognitionModelConfig tempConfig; std::set tempLearnedLabels; + cv::Mat labels; if (algName == "Eigenfaces") { tempRecognizer = cv::face::EigenFaceRecognizer::create(); @@ -305,7 +304,7 @@ int FaceRecognitionModel::load(const std::string& fileName) MEDIA_VISION_FACE_MODEL_TYPE_EIGENFACES; tempConfig.mNumComponents = (dynamic_cast(tempRecognizer.get()))->getNumComponents(); - ParseOpenCVLabels(tempRecognizer, tempLearnedLabels); + labels = (dynamic_cast(tempRecognizer.get()))->getLabels(); } else if (algName == "Fisherfaces") { tempRecognizer = cv::face::FisherFaceRecognizer::create(); storage["resizeW"] >> tempConfig.mImgWidth; @@ -315,7 +314,7 @@ int FaceRecognitionModel::load(const std::string& fileName) MEDIA_VISION_FACE_MODEL_TYPE_FISHERFACES; tempConfig.mNumComponents = (dynamic_cast(tempRecognizer.get()))->getNumComponents(); - ParseOpenCVLabels(tempRecognizer, tempLearnedLabels); + labels = (dynamic_cast(tempRecognizer.get()))->getLabels(); } else if (algName == "LBPH") { tempRecognizer = cv::face::LBPHFaceRecognizer::create(); tempRecognizer->read(storage.root()); @@ -325,7 +324,7 @@ int FaceRecognitionModel::load(const std::string& fileName) tempConfig.mGridY = (dynamic_cast(tempRecognizer.get()))->getGridY(); tempConfig.mNeighbors = (dynamic_cast(tempRecognizer.get()))->getNeighbors(); tempConfig.mRadius = (dynamic_cast(tempRecognizer.get()))->getRadius(); - ParseOpenCVLabels(tempRecognizer, tempLearnedLabels); + labels = (dynamic_cast(tempRecognizer.get()))->getLabels(); } else { tempConfig = FaceRecognitionModelConfig(); LOGE("Failed to load face recognition model from file. File is in " @@ -335,7 +334,7 @@ int FaceRecognitionModel::load(const std::string& fileName) return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT; } - + ParseOpenCVLabels(labels, tempLearnedLabels); tempConfig.mThreshold = tempRecognizer->getThreshold(); LOGD("Recognition model of [%s] type has been loaded from file", -- 2.7.4 From a21bba49f51ac36aba0eff3426afb1d0cd79596a Mon Sep 17 00:00:00 2001 From: Tae-Young Chung Date: Tue, 19 Jun 2018 19:07:10 +0900 Subject: [PATCH 07/16] Fix OpenCV version which is required at least OpenCV should be equal to or greater than 3.4.1 Change-Id: I9e1e32ec6d627e522f59db96ecf39485f61e8c72 Signed-off-by: Tae-Young Chung --- packaging/capi-media-vision.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec index 56ee7bb..78e86c8 100644 --- a/packaging/capi-media-vision.spec +++ b/packaging/capi-media-vision.spec @@ -10,7 +10,7 @@ BuildRequires: pkgconfig(capi-media-tool) BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(capi-system-info) -BuildRequires: pkgconfig(opencv) >= 3.4.0 +BuildRequires: pkgconfig(opencv) >= 3.4.1 BuildRequires: pkgconfig(zbar) BuildRequires: pkgconfig(glib-2.0) # Change to the pkgconfig(zint) after zint package refactor -- 2.7.4 From ba24dcd299cf9ea4ac1f9a45671baa2a1f9b59e8 Mon Sep 17 00:00:00 2001 From: Tae-Young Chung Date: Wed, 20 Jun 2018 17:15:33 +0900 Subject: [PATCH 08/16] Fix build error within i586 and x86_64 Fix abs() to std::abs because call of overloaded 'abs(size)t)' is ambiguous Change-Id: I125fd34e657d38c1eddfeb3eecf94c3506faa8af Signed-off-by: Tae-Young Chung --- mv_image/image/src/Features/FeatureMatcher.cpp | 2 +- mv_image/image/src/Recognition/ImageRecognizer.cpp | 2 +- packaging/capi-media-vision.spec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mv_image/image/src/Features/FeatureMatcher.cpp b/mv_image/image/src/Features/FeatureMatcher.cpp index f7c887c..5e18b75 100644 --- a/mv_image/image/src/Features/FeatureMatcher.cpp +++ b/mv_image/image/src/Features/FeatureMatcher.cpp @@ -107,7 +107,7 @@ size_t matchesSelection( /* Swap */ std::swap(examples[leftLimit], examples[rightLimit]); } - if (abs(filterAmount - leftLimit) <= static_cast(allowableError)) + if (std::abs(filterAmount - leftLimit) <= static_cast(allowableError)) break; if (static_cast(filterAmount) > leftLimit) { requiredNumber -= leftLimit - startLeftLimit; diff --git a/mv_image/image/src/Recognition/ImageRecognizer.cpp b/mv_image/image/src/Recognition/ImageRecognizer.cpp index 2088b44..5101e2f 100644 --- a/mv_image/image/src/Recognition/ImageRecognizer.cpp +++ b/mv_image/image/src/Recognition/ImageRecognizer.cpp @@ -215,7 +215,7 @@ size_t ImageRecognizer::matchesSelection( std::swap(examples[leftLimit], examples[rightLimit]); } - if (abs(filterAmount - leftLimit) <= (int)allowableError) + if (std::abs(filterAmount - leftLimit) <= (int)allowableError) break; if ((int)filterAmount > leftLimit) { diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec index 78e86c8..3268ac1 100644 --- a/packaging/capi-media-vision.spec +++ b/packaging/capi-media-vision.spec @@ -1,7 +1,7 @@ Name: capi-media-vision Summary: Media Vision library for Tizen Native API Version: 0.4.0 -Release: 1 +Release: 2 Group: Multimedia/Framework License: Apache-2.0 and BSD-3-Clause Source0: %{name}-%{version}.tar.gz -- 2.7.4 From b68520418c88640c998a8b3732abe185161d3b7e Mon Sep 17 00:00:00 2001 From: sangho park Date: Mon, 9 Jul 2018 13:14:19 +0900 Subject: [PATCH 09/16] [UTC][capi-media-vision][NON-ACR][SVACE] WGID-279240 : add try-catch to convertSourceMV2GrayCV() internal API. WGID-347564, 347565, 347566 : add NULL checking. Change-Id: I0bcc82e109243a8028c0fd9bd47c69126320c197 Signed-off-by: sangho park --- mv_face/face/src/FaceRecognitionModel.cpp | 39 ++++++++++++++++++++----------- mv_image/image/src/mv_image_open.cpp | 9 ++++++- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/mv_face/face/src/FaceRecognitionModel.cpp b/mv_face/face/src/FaceRecognitionModel.cpp index b9f4971..0b98930 100644 --- a/mv_face/face/src/FaceRecognitionModel.cpp +++ b/mv_face/face/src/FaceRecognitionModel.cpp @@ -302,9 +302,13 @@ int FaceRecognitionModel::load(const std::string& fileName) tempRecognizer->read(storage.root()); tempConfig.mModelType = MEDIA_VISION_FACE_MODEL_TYPE_EIGENFACES; - tempConfig.mNumComponents = - (dynamic_cast(tempRecognizer.get()))->getNumComponents(); - labels = (dynamic_cast(tempRecognizer.get()))->getLabels(); + cv::face::EigenFaceRecognizer* recognizer = dynamic_cast(tempRecognizer.get()); + if (recognizer != NULL) { + tempConfig.mNumComponents = recognizer->getNumComponents(); + labels = recognizer->getLabels(); + } else { + return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT; + } } else if (algName == "Fisherfaces") { tempRecognizer = cv::face::FisherFaceRecognizer::create(); storage["resizeW"] >> tempConfig.mImgWidth; @@ -312,19 +316,28 @@ int FaceRecognitionModel::load(const std::string& fileName) tempRecognizer->read(storage.root()); tempConfig.mModelType = MEDIA_VISION_FACE_MODEL_TYPE_FISHERFACES; - tempConfig.mNumComponents = - (dynamic_cast(tempRecognizer.get()))->getNumComponents(); - labels = (dynamic_cast(tempRecognizer.get()))->getLabels(); + cv::face::FisherFaceRecognizer* recognizer = dynamic_cast(tempRecognizer.get()); + if (recognizer != NULL) { + tempConfig.mNumComponents = recognizer->getNumComponents(); + labels = recognizer->getLabels(); + } else { + return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT; + } } else if (algName == "LBPH") { tempRecognizer = cv::face::LBPHFaceRecognizer::create(); tempRecognizer->read(storage.root()); - tempConfig.mModelType = - MEDIA_VISION_FACE_MODEL_TYPE_LBPH; - tempConfig.mGridX = (dynamic_cast(tempRecognizer.get()))->getGridX(); - tempConfig.mGridY = (dynamic_cast(tempRecognizer.get()))->getGridY(); - tempConfig.mNeighbors = (dynamic_cast(tempRecognizer.get()))->getNeighbors(); - tempConfig.mRadius = (dynamic_cast(tempRecognizer.get()))->getRadius(); - labels = (dynamic_cast(tempRecognizer.get()))->getLabels(); + cv::face::LBPHFaceRecognizer* recognizer = dynamic_cast(tempRecognizer.get()); + if (recognizer != NULL) { + tempConfig.mModelType = + MEDIA_VISION_FACE_MODEL_TYPE_LBPH; + tempConfig.mGridX = recognizer->getGridX(); + tempConfig.mGridY = recognizer->getGridY(); + tempConfig.mNeighbors = recognizer->getNeighbors(); + tempConfig.mRadius = recognizer->getRadius(); + labels = recognizer->getLabels(); + } else { + return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT; + } } else { tempConfig = FaceRecognitionModelConfig(); LOGE("Failed to load face recognition model from file. File is in " diff --git a/mv_image/image/src/mv_image_open.cpp b/mv_image/image/src/mv_image_open.cpp index 04d4a9a..d0ca698 100644 --- a/mv_image/image/src/mv_image_open.cpp +++ b/mv_image/image/src/mv_image_open.cpp @@ -377,7 +377,14 @@ int convertSourceMV2GrayCV(mv_source_h mvSource, cv::Mat& cvSource) CV_MAKETYPE(depth, channelsNumber), buffer).clone(); } else {/* With conversion */ /* Class for representation the given image as cv::Mat before conversion */ - cv::Mat origin(cv::Size(width, height), CV_MAKETYPE(depth, channelsNumber), buffer); + cv::Mat origin; + + try { + origin = cv::Mat(cv::Size(width, height), + CV_MAKETYPE(depth, channelsNumber), buffer); + } catch (cv::Exception &e) { + return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT; + } try { cv::cvtColor(origin, cvSource, conversionType); -- 2.7.4 From 3bd5148b5584730bc7a12c00ccb611e2e199153d Mon Sep 17 00:00:00 2001 From: yhji Date: Tue, 24 Jul 2018 18:58:47 +0900 Subject: [PATCH 10/16] Fix Wformat build error Change-Id: I89c3483d0fac57ebc1d328a5752c776341939dcf Signed-off-by: yhji --- mv_image/image/src/Features/BasicExtractorFactory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mv_image/image/src/Features/BasicExtractorFactory.cpp b/mv_image/image/src/Features/BasicExtractorFactory.cpp index 0982be1..c788895 100644 --- a/mv_image/image/src/Features/BasicExtractorFactory.cpp +++ b/mv_image/image/src/Features/BasicExtractorFactory.cpp @@ -43,7 +43,7 @@ cv::Ptr BasicExtractorFactory::buildFeatureExtractor() detector = cv::GFTTDetector::create(); break; default: - LOGE("Unknown feature detector", __FUNCTION__); + LOGE("[%s] Unknown feature detector", __FUNCTION__); } cv::Ptr extractor; @@ -55,7 +55,7 @@ cv::Ptr BasicExtractorFactory::buildFeatureExtractor() extractor = cv::xfeatures2d::BriefDescriptorExtractor::create(); break; default: - LOGE("Unkown feature extractor", __FUNCTION__); + LOGE("[%s] Unknown feature extractor", __FUNCTION__); } featureExtractor->setFeatureDetector(detector, __kpType); -- 2.7.4 From 5d23752ea752d6c240ce8906656355e8ec3d7214 Mon Sep 17 00:00:00 2001 From: sangho park Date: Wed, 8 Aug 2018 11:29:26 +0900 Subject: [PATCH 11/16] fix Coverity issue [CID:860216] Arguments in wrong order Change-Id: Ib1d18a6f2638c440692f985a2cb862896ebb0eb2 Signed-off-by: sangho park --- mv_face/face/src/FaceTracker.cpp | 2 +- packaging/capi-media-vision.spec | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mv_face/face/src/FaceTracker.cpp b/mv_face/face/src/FaceTracker.cpp index f5427ce..9303b16 100644 --- a/mv_face/face/src/FaceTracker.cpp +++ b/mv_face/face/src/FaceTracker.cpp @@ -64,7 +64,7 @@ void FaceTracker::Params::read(const cv::FileNode& fn) mPointsInGrid = fn["pointsInGrid"]; int winSizeHeight = fn["windowSizeHeight"]; int winSizeWidth = fn["windowSizeWidth"]; - mWindowSize = Size(winSizeHeight, winSizeWidth); + mWindowSize = Size(winSizeWidth, winSizeHeight); mPyrMaxLevel = fn["pyrMaxLevel"]; } diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec index 3268ac1..5a00d3d 100644 --- a/packaging/capi-media-vision.spec +++ b/packaging/capi-media-vision.spec @@ -1,7 +1,7 @@ Name: capi-media-vision Summary: Media Vision library for Tizen Native API -Version: 0.4.0 -Release: 2 +Version: 0.4.1 +Release: 3 Group: Multimedia/Framework License: Apache-2.0 and BSD-3-Clause Source0: %{name}-%{version}.tar.gz -- 2.7.4 From 60365c37832cf624bfc7374d4fe374006a73880d Mon Sep 17 00:00:00 2001 From: Tae-Young Chung Date: Fri, 17 Aug 2018 17:48:33 +0900 Subject: [PATCH 12/16] Remove unnecessary log printing while face detection While face detection, check engine_config and print logs even though engine_config is null. This patch modify those parts. Change-Id: I07b664268b64d68d2638f61cc9d74be33827b3c5 Signed-off-by: Tae-Young Chung --- mv_face/face/src/mv_face_open.cpp | 129 +++++++++++++++++++------------------- packaging/capi-media-vision.spec | 4 +- 2 files changed, 68 insertions(+), 65 deletions(-) diff --git a/mv_face/face/src/mv_face_open.cpp b/mv_face/face/src/mv_face_open.cpp index 6531363..56571cb 100644 --- a/mv_face/face/src/mv_face_open.cpp +++ b/mv_face/face/src/mv_face_open.cpp @@ -86,83 +86,86 @@ int mv_face_detect_open( return error; } - char *haarcascadeFilepath; - error = mv_engine_config_get_string_attribute_c( - engine_cfg, - "MV_FACE_DETECTION_MODEL_FILE_PATH", - &haarcascadeFilepath); - /* default path */ + cv::Size minSize(-1, -1); + cv::Rect roi(-1, -1, -1, -1); std::string haarcascadeFilePathStr = "/usr/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml"; - - if (error == MEDIA_VISION_ERROR_NONE) { - LOGI("Haarcascade file was set as default"); - haarcascadeFilePathStr = std::string(haarcascadeFilepath); - - free(haarcascadeFilepath); - haarcascadeFilepath = NULL; - } else { - LOGE("Error occurred during face detection haarcascade file receiving." + if (engine_cfg) { + /* set face detection model */ + char *haarcascadeFilepath; + error = mv_engine_config_get_string_attribute_c( + engine_cfg, + "MV_FACE_DETECTION_MODEL_FILE_PATH", + &haarcascadeFilepath); + if (error == MEDIA_VISION_ERROR_NONE) { + LOGI("Haarcascade file was set as default"); + haarcascadeFilePathStr = std::string(haarcascadeFilepath); + + free(haarcascadeFilepath); + haarcascadeFilepath = NULL; + } else { + LOGE("Error occurred during face detection haarcascade file receiving." " (%i)", error); - } - - static FaceDetector faceDetector; - - if (!faceDetector.loadHaarcascade(haarcascadeFilePathStr)) { - LOGE("Loading Haarcascade failed"); - return MEDIA_VISION_ERROR_INVALID_PARAMETER; - } + } - cv::Rect roi(-1, -1, -1, -1); - error = mv_engine_config_get_int_attribute_c( + /* Ser roi to be detected */ + error = mv_engine_config_get_int_attribute_c( engine_cfg, MV_FACE_DETECTION_ROI_X, &roi.x); - if (error != MEDIA_VISION_ERROR_NONE) - LOGE("Error occurred during face detection roi (x) receiving." + if (error != MEDIA_VISION_ERROR_NONE) + LOGE("Error occurred during face detection roi (x) receiving." " (%i)", error); - error = mv_engine_config_get_int_attribute_c( - engine_cfg, - MV_FACE_DETECTION_ROI_Y, - &roi.y); - if (error != MEDIA_VISION_ERROR_NONE) - LOGE("Error occurred during face detection roi (y) receiving." - " (%i)", error); + error = mv_engine_config_get_int_attribute_c( + engine_cfg, + MV_FACE_DETECTION_ROI_Y, + &roi.y); + if (error != MEDIA_VISION_ERROR_NONE) + LOGE("Error occurred during face detection roi (y) receiving." + " (%i)", error); - error = mv_engine_config_get_int_attribute_c( - engine_cfg, - MV_FACE_DETECTION_ROI_WIDTH, - &roi.width); - if (error != MEDIA_VISION_ERROR_NONE) - LOGE("Error occurred during face detection roi (width) receiving." - " (%i)", error); + error = mv_engine_config_get_int_attribute_c( + engine_cfg, + MV_FACE_DETECTION_ROI_WIDTH, + &roi.width); + if (error != MEDIA_VISION_ERROR_NONE) + LOGE("Error occurred during face detection roi (width) receiving." + " (%i)", error); - error = mv_engine_config_get_int_attribute_c( - engine_cfg, - MV_FACE_DETECTION_ROI_HEIGHT, - &roi.height); - if (error != MEDIA_VISION_ERROR_NONE) - LOGE("Error occurred during face detection roi (height) receiving." - " (%i)", error); + error = mv_engine_config_get_int_attribute_c( + engine_cfg, + MV_FACE_DETECTION_ROI_HEIGHT, + &roi.height); + if (error != MEDIA_VISION_ERROR_NONE) + LOGE("Error occurred during face detection roi (height) receiving." + " (%i)", error); + + /* Set minimum size to be detected */ + error = mv_engine_config_get_int_attribute_c( + engine_cfg, + MV_FACE_DETECTION_MIN_SIZE_WIDTH, + &minSize.width); + if (error != MEDIA_VISION_ERROR_NONE) + LOGE("Error occurred during face detection minimum width receiving." + " (%i)", error); - cv::Size minSize(-1, -1); - error = mv_engine_config_get_int_attribute_c( - engine_cfg, - MV_FACE_DETECTION_MIN_SIZE_WIDTH, - &minSize.width); - if (error != MEDIA_VISION_ERROR_NONE) - LOGE("Error occurred during face detection minimum width receiving." - " (%i)", error); + error = mv_engine_config_get_int_attribute_c( + engine_cfg, + MV_FACE_DETECTION_MIN_SIZE_HEIGHT, + &minSize.height); + if (error != MEDIA_VISION_ERROR_NONE) + LOGE("Error occurred during face detection minimum height receiving." + " (%i)", error); + } - error = mv_engine_config_get_int_attribute_c( - engine_cfg, - MV_FACE_DETECTION_MIN_SIZE_HEIGHT, - &minSize.height); - if (error != MEDIA_VISION_ERROR_NONE) - LOGE("Error occurred during face detection minimum height receiving." - " (%i)", error); + static FaceDetector faceDetector; + + if (!faceDetector.loadHaarcascade(haarcascadeFilePathStr)) { + LOGE("Loading Haarcascade failed"); + return MEDIA_VISION_ERROR_INVALID_PARAMETER; + } std::vector faceLocations; if (!faceDetector.detectFaces(image, roi, minSize, faceLocations)) { diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec index 5a00d3d..0724a00 100644 --- a/packaging/capi-media-vision.spec +++ b/packaging/capi-media-vision.spec @@ -1,7 +1,7 @@ Name: capi-media-vision Summary: Media Vision library for Tizen Native API -Version: 0.4.1 -Release: 3 +Version: 0.4.2 +Release: 4 Group: Multimedia/Framework License: Apache-2.0 and BSD-3-Clause Source0: %{name}-%{version}.tar.gz -- 2.7.4 From ab7be7309241c6eef537bc2218efd4d67557de0b Mon Sep 17 00:00:00 2001 From: Tae-Young Chung Date: Wed, 12 Sep 2018 18:01:03 +0900 Subject: [PATCH 13/16] Add codes handling exception thrown by OpenCV In the worst case, the memory size over the limitation is required and then OutOfMemory exception is thrown, resulting crash. This patch handles the exception and prevents crash. Change-Id: Ie9bb0346cf53bc59d8a9da7e4758c2011cda9f1e Signed-off-by: Tae-Young Chung --- mv_face/face/src/FaceDetector.cpp | 8 +++----- mv_face/face/src/mv_face_open.cpp | 14 +++++++++++--- packaging/capi-media-vision.spec | 4 ++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/mv_face/face/src/FaceDetector.cpp b/mv_face/face/src/FaceDetector.cpp index 9ce2bbe..11d4043 100644 --- a/mv_face/face/src/FaceDetector.cpp +++ b/mv_face/face/src/FaceDetector.cpp @@ -53,8 +53,7 @@ bool FaceDetector::detectFaces( roiIsUsed = true; } - if (minSize.width > 0 && minSize.height > 0 && - minSize.width <= image.cols && minSize.height <= image.rows) { + try { m_faceCascade.detectMultiScale( intrestingRegion, faceLocations, @@ -62,9 +61,8 @@ bool FaceDetector::detectFaces( 3, 0, minSize); - - } else { - m_faceCascade.detectMultiScale(intrestingRegion, faceLocations); + } catch (cv::Exception e) { + return false; } if (roiIsUsed) { diff --git a/mv_face/face/src/mv_face_open.cpp b/mv_face/face/src/mv_face_open.cpp index 56571cb..443fd71 100644 --- a/mv_face/face/src/mv_face_open.cpp +++ b/mv_face/face/src/mv_face_open.cpp @@ -87,11 +87,13 @@ int mv_face_detect_open( } /* default path */ - cv::Size minSize(-1, -1); + cv::Size minSize(0, 0); cv::Rect roi(-1, -1, -1, -1); std::string haarcascadeFilePathStr = "/usr/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml"; if (engine_cfg) { + int minWidth, minHeight; + /* set face detection model */ char *haarcascadeFilepath; error = mv_engine_config_get_string_attribute_c( @@ -146,7 +148,7 @@ int mv_face_detect_open( error = mv_engine_config_get_int_attribute_c( engine_cfg, MV_FACE_DETECTION_MIN_SIZE_WIDTH, - &minSize.width); + &minWidth); if (error != MEDIA_VISION_ERROR_NONE) LOGE("Error occurred during face detection minimum width receiving." " (%i)", error); @@ -154,10 +156,16 @@ int mv_face_detect_open( error = mv_engine_config_get_int_attribute_c( engine_cfg, MV_FACE_DETECTION_MIN_SIZE_HEIGHT, - &minSize.height); + &minHeight); if (error != MEDIA_VISION_ERROR_NONE) LOGE("Error occurred during face detection minimum height receiving." " (%i)", error); + + if (minWidth > 0 && minHeight > 0 && + minWidth <= image.cols && minHeight <= image.rows) { + minSize.width = minWidth; + minSize.height = minHeight; + } } static FaceDetector faceDetector; diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec index 0724a00..44d163e 100644 --- a/packaging/capi-media-vision.spec +++ b/packaging/capi-media-vision.spec @@ -1,7 +1,7 @@ Name: capi-media-vision Summary: Media Vision library for Tizen Native API -Version: 0.4.2 -Release: 4 +Version: 0.4.3 +Release: 5 Group: Multimedia/Framework License: Apache-2.0 and BSD-3-Clause Source0: %{name}-%{version}.tar.gz -- 2.7.4 From 15b823b9d72e079dbe929aa591f7ffae46917832 Mon Sep 17 00:00:00 2001 From: SeokHoon Lee Date: Mon, 17 Sep 2018 16:03:18 +0900 Subject: [PATCH 14/16] Add gcov environment Signed-off-by: SeokHoon Lee Change-Id: If373936e91d972b36763afbfb4d33a36427213b9 --- packaging/capi-media-vision.spec | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec index 44d163e..bd45d97 100644 --- a/packaging/capi-media-vision.spec +++ b/packaging/capi-media-vision.spec @@ -145,6 +145,14 @@ export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" export CFLAGS+=" -DMV_CONFIG_PATH=\\\"%{TZ_SYS_RO_SHARE}/%{name}/\\\"" export CXXFLAGS+=" -DMV_CONFIG_PATH=\\\"%{TZ_SYS_RO_SHARE}/%{name}/\\\"" + +%if 0%{?gcov:1} +export CFLAGS+=" -fprofile-arcs -ftest-coverage" +export CXXFLAGS+=" -fprofile-arcs -ftest-coverage" +export FFLAGS+=" -fprofile-arcs -ftest-coverage" +export LDFLAGS+=" -lgcov" +%endif + MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` %cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER} -DTZ_SYS_BIN=%TZ_SYS_BIN \ %ifarch %arm -- 2.7.4 From 65b7d38e4f6ad85972a58fba5b0fb54c142ea879 Mon Sep 17 00:00:00 2001 From: Tae-Young Chung Date: Tue, 2 Oct 2018 17:07:13 +0900 Subject: [PATCH 15/16] Add null check after g_array_new() in image_test_suite.c Change-Id: Idfc72e069489adfe0d625b518d7a00588ac48c1e Signed-off-by: Tae-Young Chung --- test/testsuites/image/image_test_suite.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/testsuites/image/image_test_suite.c b/test/testsuites/image/image_test_suite.c index 8ff901e..962202f 100644 --- a/test/testsuites/image/image_test_suite.c +++ b/test/testsuites/image/image_test_suite.c @@ -2038,7 +2038,17 @@ int main(void) LOGI("Image Media Vision Testsuite is launched."); GArray *image_objects = g_array_new(FALSE, FALSE, sizeof(testing_object_h)); + if (image_objects == NULL) { + printf("image_objects are null!! Try again.."); + return 0; + } + GArray *image_tracking_models = g_array_new(FALSE, FALSE, sizeof(testing_object_h)); + if (image_tracking_models == NULL) { + printf("image_tracking_models are null!! Try again.."); + g_array_free(image_objects, TRUE); + return 0; + } const int options[3] = { 1, 2, 3 }; const char *names[3] = { -- 2.7.4 From 960cc2c269d121334d92c7eec8d94a7b6f0386e3 Mon Sep 17 00:00:00 2001 From: hj kim Date: Thu, 1 Nov 2018 10:18:16 +0900 Subject: [PATCH 16/16] Remove dlog from pc_dependents Change-Id: Iaa7417463be8a1a23c2d554aa82c556de4eb62d0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c6a982..a811e3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,7 @@ INCLUDE_DIRECTORIES(${INC_DIR} ${INC_SURVEILLANCE}) SET(dependents "dlog capi-media-tool capi-system-info") -SET(pc_dependents "dlog capi-media-tool") +SET(pc_dependents "capi-media-tool") INCLUDE(FindPkgConfig) pkg_check_modules(${fw_name} REQUIRED ${dependents}) -- 2.7.4