From 813c5175ca19965efbc7e830e80e3dcb97fbf4f9 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Tue, 4 May 2021 07:33:47 -0400 Subject: [PATCH] OpenCV: Adapt to API changes in OpenCV 4.5.2+ (#639) * CVTracker: Handle API changes in OpenCV The former cv::Tracker API we've been using is now cv::legacy::Tracker, starting in OpenCV 4.5.1. * CVTracker: Move some includes, add std:: prefixes * Move ClipProcessingJobs into openshot NS * OpenCV 4.5.1 message and auto-disabling * Add fstream includes, explicit std:: namespace Work around a MacOS bug where bare fstream resolves to the wrong class. Co-authored-by: Brenno Co-authored-by: Brenno A. C. Caldato --- src/CMakeLists.txt | 4 +-- src/CVObjectDetection.cpp | 4 +++ src/CVStabilization.cpp | 13 +++++++-- src/CVTracker.cpp | 40 +++++++++++++++----------- src/CVTracker.h | 14 +++++---- src/ClipProcessingJobs.cpp | 18 +++++++----- src/ClipProcessingJobs.h | 12 ++++---- src/OpenCVUtilities.h | 50 +++++++++++++++++++++++++++++++++ src/effects/ObjectDetection.cpp | 7 +++-- src/effects/Stabilizer.cpp | 10 +++++-- src/effects/Tracker.cpp | 14 +++++++-- src/effects/Tracker.h | 10 +++---- tests/Point.cpp | 3 +- 13 files changed, 144 insertions(+), 55 deletions(-) create mode 100644 src/OpenCVUtilities.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4bd09e74..625384cf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -402,7 +402,7 @@ if(ENABLE_OPENCV) set(ENABLE_OPENCV FALSE CACHE BOOL "Build with OpenCV algorithms (requires Protobuf 3)" FORCE) # If we have version 4.5.1, all hope is lost - elseif(OpenCV_VERSION VERSION_EQUAL 4.5.1) + elseif(OpenCV_VERSION VERSION_EQUAL "4.5.1") message(WARNING [[Incompatible OpenCV version detected OpenCV version 4.5.1 contains header errors which make it unable to be used with OpenShot. OpenCV support wil be disabled. Upgrade to OpenCV 4.5.2+ or downgrade to 4.5.0 or earlier, to enable OpenCV. See https://github.com/opencv/opencv/issues/19260]]) @@ -431,7 +431,7 @@ See https://github.com/opencv/opencv/issues/19260]]) mark_as_advanced(OPENCV_VERSION_STR) # We may need to use Tracker as opencv::legacy::Tracker - if(OpenCV_VERSION VERSION_GREATER_EQUAL 4.5.2) + if(OpenCV_VERSION VERSION_GREATER "4.5.1") target_compile_definitions(openshot PUBLIC USE_LEGACY_TRACKER=1) endif() diff --git a/src/CVObjectDetection.cpp b/src/CVObjectDetection.cpp index 29a36631..b6f5c247 100644 --- a/src/CVObjectDetection.cpp +++ b/src/CVObjectDetection.cpp @@ -28,6 +28,10 @@ * along with OpenShot Library. If not, see . */ +#include +#include +#include + #include "CVObjectDetection.h" #include diff --git a/src/CVStabilization.cpp b/src/CVStabilization.cpp index 3076ada8..3600954f 100644 --- a/src/CVStabilization.cpp +++ b/src/CVStabilization.cpp @@ -28,6 +28,10 @@ * along with OpenShot Library. If not, see . */ +#include +#include +#include + #include "CVStabilization.h" #include @@ -276,6 +280,8 @@ std::map CVStabilization::GenNewCamPosition(std::map . */ -#include "CVTracker.h" +#include +#include +#include + #include -using namespace std; +#include "OpenCVUtilities.h" +#include "CVTracker.h" + using namespace openshot; using google::protobuf::util::TimeUtil; - // Constructor CVTracker::CVTracker(std::string processInfoJson, ProcessingController &processingController) : processingController(&processingController), json_interval(false){ @@ -45,25 +49,24 @@ CVTracker::CVTracker(std::string processInfoJson, ProcessingController &processi } // Set desirable tracker method -cv::Ptr CVTracker::selectTracker(std::string trackerType){ - cv::Ptr t; +cv::Ptr CVTracker::selectTracker(std::string trackerType){ if (trackerType == "BOOSTING") - t = cv::TrackerBoosting::create(); + return OPENCV_TRACKER_NS::TrackerBoosting::create(); if (trackerType == "MIL") - t = cv::TrackerMIL::create(); + return OPENCV_TRACKER_NS::TrackerMIL::create(); if (trackerType == "KCF") - t = cv::TrackerKCF::create(); + return OPENCV_TRACKER_NS::TrackerKCF::create(); if (trackerType == "TLD") - t = cv::TrackerTLD::create(); + return OPENCV_TRACKER_NS::TrackerTLD::create(); if (trackerType == "MEDIANFLOW") - t = cv::TrackerMedianFlow::create(); + return OPENCV_TRACKER_NS::TrackerMedianFlow::create(); if (trackerType == "MOSSE") - t = cv::TrackerMOSSE::create(); + return OPENCV_TRACKER_NS::TrackerMOSSE::create(); if (trackerType == "CSRT") - t = cv::TrackerCSRT::create(); + return OPENCV_TRACKER_NS::TrackerCSRT::create(); - return t; + return nullptr; } // Track object in the hole clip or in a given interval @@ -197,6 +200,8 @@ bool CVTracker::trackFrame(cv::Mat &frame, size_t frameId){ } bool CVTracker::SaveTrackedData(){ + using std::ios; + // Create tracker message pb_tracker::Tracker trackerMessage; @@ -214,7 +219,7 @@ bool CVTracker::SaveTrackedData(){ // Write the new message to disk. std::fstream output(protobuf_data_path, ios::out | ios::trunc | ios::binary); if (!trackerMessage.SerializeToOstream(&output)) { - cerr << "Failed to write protobuf message." << endl; + std::cerr << "Failed to write protobuf message." << std::endl; return false; } } @@ -314,14 +319,16 @@ void CVTracker::SetJsonValue(const Json::Value root) { // Load protobuf data file bool CVTracker::_LoadTrackedData(){ + using std::ios; + // Create tracker message pb_tracker::Tracker trackerMessage; { // Read the existing tracker message. - fstream input(protobuf_data_path, ios::in | ios::binary); + std::fstream input(protobuf_data_path, ios::in | ios::binary); if (!trackerMessage.ParseFromIstream(&input)) { - cerr << "Failed to parse protobuf message." << endl; + std::cerr << "Failed to parse protobuf message." << std::endl; return false; } } @@ -353,4 +360,3 @@ bool CVTracker::_LoadTrackedData(){ return true; } - diff --git a/src/CVTracker.h b/src/CVTracker.h index 6a806ba5..4430bd4b 100644 --- a/src/CVTracker.h +++ b/src/CVTracker.h @@ -31,19 +31,21 @@ #ifndef OPENSHOT_CVTRACKER_H #define OPENSHOT_CVTRACKER_H -#define int64 opencv_broken_int -#define uint64 opencv_broken_uint +#include "OpenCVUtilities.h" + +#define int64 int64_t +#define uint64 uint64_t #include #include #include #undef uint64 #undef int64 -#include #include "Clip.h" #include "KeyFrame.h" #include "Frame.h" #include "Json.h" + #include "ProcessingController.h" #include "protobuf_messages/trackerdata.pb.h" @@ -87,7 +89,7 @@ namespace openshot private: std::map trackedDataById; // Save tracked data std::string trackerType; // Name of the chosen tracker - cv::Ptr tracker; // Pointer of the selected tracker + cv::Ptr tracker; // Pointer of the selected tracker cv::Rect2d bbox; // Bounding box coords SortTracker sort; @@ -116,8 +118,8 @@ namespace openshot // Constructor CVTracker(std::string processInfoJson, ProcessingController &processingController); - /// Set desirable tracker method - cv::Ptr selectTracker(std::string trackerType); + // Set desirable tracker method + cv::Ptr selectTracker(std::string trackerType); /// Track object in the hole clip or in a given interval /// diff --git a/src/ClipProcessingJobs.cpp b/src/ClipProcessingJobs.cpp index fb64fd78..b8d7e00a 100644 --- a/src/ClipProcessingJobs.cpp +++ b/src/ClipProcessingJobs.cpp @@ -1,7 +1,9 @@ #include "ClipProcessingJobs.h" +namespace openshot { + // Constructor responsible to choose processing type and apply to clip -ClipProcessingJobs::ClipProcessingJobs(std::string processingType, std::string processInfoJson) : +ClipProcessingJobs::ClipProcessingJobs(std::string processingType, std::string processInfoJson) : processingType(processingType), processInfoJson(processInfoJson){ } @@ -20,7 +22,7 @@ void ClipProcessingJobs::processClip(Clip& clip, std::string json){ } } -// Apply object tracking to clip +// Apply object tracking to clip void ClipProcessingJobs::trackClip(Clip& clip, ProcessingController& controller){ // Create CVTracker object @@ -46,7 +48,7 @@ void ClipProcessingJobs::trackClip(Clip& clip, ProcessingController& controller) // Apply object detection to clip void ClipProcessingJobs::detectObjectsClip(Clip& clip, ProcessingController& controller){ // create CVObjectDetection object - CVObjectDetection objDetector(processInfoJson, controller); + CVObjectDetection objDetector(processInfoJson, controller); // Start object detection process objDetector.detectObjectsClip(clip); @@ -66,7 +68,7 @@ void ClipProcessingJobs::detectObjectsClip(Clip& clip, ProcessingController& con void ClipProcessingJobs::stabilizeClip(Clip& clip, ProcessingController& controller){ // create CVStabilization object - CVStabilization stabilizer(processInfoJson, controller); + CVStabilization stabilizer(processInfoJson, controller); // Start stabilization process stabilizer.stabilizeClip(clip); @@ -84,13 +86,13 @@ void ClipProcessingJobs::stabilizeClip(Clip& clip, ProcessingController& control } } -// Get processing progress while iterating on the clip +// Get processing progress while iterating on the clip int ClipProcessingJobs::GetProgress(){ return (int)processingController.GetProgress(); } -// Check if processing finished +// Check if processing finished bool ClipProcessingJobs::IsDone(){ if(processingController.GetFinished()){ @@ -112,4 +114,6 @@ bool ClipProcessingJobs::GetError(){ // get the error message std::string ClipProcessingJobs::GetErrorMessage(){ return processingController.GetErrorMessage(); -} \ No newline at end of file +} + +} // namespace openshot diff --git a/src/ClipProcessingJobs.h b/src/ClipProcessingJobs.h index 2a34d46e..afea1ffa 100644 --- a/src/ClipProcessingJobs.h +++ b/src/ClipProcessingJobs.h @@ -35,7 +35,7 @@ #include #include #undef uint64 - #undef int64 + #undef int64 #include "CVStabilization.h" #include "CVTracker.h" @@ -46,7 +46,7 @@ #include "ProcessingController.h" #include "Clip.h" -using namespace openshot; +namespace openshot { // Constructor responsible to choose processing type and apply to clip class ClipProcessingJobs{ @@ -63,7 +63,7 @@ class ClipProcessingJobs{ /// Will handle a Thread safely comutication between ClipProcessingJobs and the processing effect classes ProcessingController processingController; - // Apply object tracking to clip + // Apply object tracking to clip void trackClip(Clip& clip, ProcessingController& controller); // Apply stabilization to clip void stabilizeClip(Clip& clip, ProcessingController& controller); @@ -74,7 +74,7 @@ class ClipProcessingJobs{ public: // Constructor ClipProcessingJobs(std::string processingType, std::string processInfoJson); - // Process clip accordingly to processingType + // Process clip accordingly to processingType void processClip(Clip& clip, std::string json); // Thread related variables and methods @@ -83,6 +83,6 @@ class ClipProcessingJobs{ void CancelProcessing(); bool GetError(); std::string GetErrorMessage(); +}; - -}; \ No newline at end of file +} // namespace openshot diff --git a/src/OpenCVUtilities.h b/src/OpenCVUtilities.h new file mode 100644 index 00000000..1c5793ec --- /dev/null +++ b/src/OpenCVUtilities.h @@ -0,0 +1,50 @@ +/** + * @file + * @brief Header file for OpenCVUtilities (set some common macros) + * @author FeRD (Frank Dana) + * @author Jonathan Thomas + * + * @ref License + */ + +/* LICENSE + * + * Copyright (c) 2008-2021 OpenShot Studios, LLC + * . This file is part of + * OpenShot Library (libopenshot), an open-source project dedicated to + * delivering high quality video editing and animation solutions to the + * world. For more information visit . + * + * OpenShot Library (libopenshot) is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * OpenShot Library (libopenshot) is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with OpenShot Library. If not, see . + */ + +#ifndef OPENSHOT_OPENCV_UTILITIES_H +#define OPENSHOT_OPENCV_UTILITIES_H + +#define int64 int64_t +#define uint64 uint64_t +#if USE_LEGACY_TRACKER + #include + #include + #define OPENCV_TRACKER_TYPE cv::legacy::Tracker + #define OPENCV_TRACKER_NS cv::legacy +#else + #include + #define OPENCV_TRACKER_TYPE cv::Tracker + #define OPENCV_TRACKER_NS cv +#endif +#undef int64 +#undef uint64 + +#endif // OPENSHOT_OPENCV_UTILITIES_H diff --git a/src/effects/ObjectDetection.cpp b/src/effects/ObjectDetection.cpp index 146a28b4..8f5d3ca1 100644 --- a/src/effects/ObjectDetection.cpp +++ b/src/effects/ObjectDetection.cpp @@ -28,6 +28,9 @@ * along with OpenShot Library. If not, see . */ +#include +#include + #include "effects/ObjectDetection.h" #include "effects/Tracker.h" #include "Exceptions.h" @@ -135,9 +138,9 @@ bool ObjectDetection::LoadObjDetectdData(std::string inputFilePath){ { // Read the existing tracker message. - fstream input(inputFilePath, ios::in | ios::binary); + std::fstream input(inputFilePath, std::ios::in | std::ios::binary); if (!objMessage.ParseFromIstream(&input)) { - cerr << "Failed to parse protobuf message." << endl; + std::cerr << "Failed to parse protobuf message." << std::endl; return false; } } diff --git a/src/effects/Stabilizer.cpp b/src/effects/Stabilizer.cpp index 69634571..83472b30 100644 --- a/src/effects/Stabilizer.cpp +++ b/src/effects/Stabilizer.cpp @@ -28,6 +28,10 @@ * along with OpenShot Library. If not, see . */ +#include +#include +#include + #include "effects/Stabilizer.h" #include "Exceptions.h" #include @@ -115,14 +119,14 @@ std::shared_ptr Stabilizer::GetFrame(std::shared_ptr frame, int64_ // Load protobuf data file bool Stabilizer::LoadStabilizedData(std::string inputFilePath){ - + using std::ios; // Create stabilization message pb_stabilize::Stabilization stabilizationMessage; // Read the existing tracker message. - fstream input(inputFilePath, ios::in | ios::binary); + std::fstream input(inputFilePath, ios::in | ios::binary); if (!stabilizationMessage.ParseFromIstream(&input)) { - cerr << "Failed to parse protobuf message." << endl; + std::cerr << "Failed to parse protobuf message." << std::endl; return false; } diff --git a/src/effects/Tracker.cpp b/src/effects/Tracker.cpp index b0d73e5b..26be9d16 100644 --- a/src/effects/Tracker.cpp +++ b/src/effects/Tracker.cpp @@ -28,8 +28,14 @@ * along with OpenShot Library. If not, see . */ +#include +#include +#include +#include + #include "effects/Tracker.h" #include "Exceptions.h" + #include using namespace std; @@ -104,14 +110,16 @@ std::shared_ptr Tracker::GetFrame(std::shared_ptr frame, int64_t f // Load protobuf data file bool Tracker::LoadTrackedData(std::string inputFilePath){ + using std::ios; + // Create tracker message pb_tracker::Tracker trackerMessage; { // Read the existing tracker message. - fstream input(inputFilePath, ios::in | ios::binary); + std::fstream input(inputFilePath, ios::in | ios::binary); if (!trackerMessage.ParseFromIstream(&input)) { - cerr << "Failed to parse protobuf message." << endl; + std::cerr << "Failed to parse protobuf message." << std::endl; return false; } } @@ -202,7 +210,7 @@ void Tracker::SetJsonValue(const Json::Value root) { protobuf_data_path = (root["protobuf_data_path"].asString()); if(!LoadTrackedData(protobuf_data_path)){ - std::cout<<"Invalid protobuf data path"; + std::cerr << "Invalid protobuf data path\n"; protobuf_data_path = ""; } } diff --git a/src/effects/Tracker.h b/src/effects/Tracker.h index 68f18e83..e1f4cab4 100644 --- a/src/effects/Tracker.h +++ b/src/effects/Tracker.h @@ -31,15 +31,15 @@ #ifndef OPENSHOT_TRACKER_EFFECT_H #define OPENSHOT_TRACKER_EFFECT_H +#include +#include +#include + #include "../EffectBase.h" -#include -#include -#include -#include -#include "../Color.h" #include "../Json.h" #include "../KeyFrame.h" + #include "protobuf_messages/trackerdata.pb.h" // Tracking info struct diff --git a/tests/Point.cpp b/tests/Point.cpp index ec208698..310606d8 100644 --- a/tests/Point.cpp +++ b/tests/Point.cpp @@ -29,13 +29,14 @@ */ #include - +#include #include "Point.h" #include "Enums.h" #include "Exceptions.h" #include "Coordinate.h" #include "Json.h" + TEST_CASE( "default constructor", "[libopenshot][point]" ) { openshot::Point p;