diff --git a/include/CVTracker.h b/include/CVTracker.h new file mode 100644 index 00000000..6faec3ce --- /dev/null +++ b/include/CVTracker.h @@ -0,0 +1,20 @@ + +#include +#include +#include + +using namespace cv; + + +class CVTracker { + public: + std::string trackerType; + Ptr tracker; + Rect2d bbox; + + CVTracker(); + Ptr select_tracker(std::string trackerType); + bool initTracker(Rect2d bbox, Mat &frame); + bool trackFrame(Mat &frame); + +}; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 17b73863..c11f93af 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -77,6 +77,11 @@ if (ImageMagick_FOUND) endif() +################ OPENCV ################## + +find_package( OpenCV 4 REQUIRED ) + + ################# LIBOPENSHOT-AUDIO ################### # Find JUCE-based openshot Audio libraries find_package(OpenShotAudio 0.2.0 REQUIRED) @@ -163,7 +168,8 @@ set(OPENSHOT_SOURCES QtPlayer.cpp QtTextReader.cpp Settings.cpp - Timeline.cpp) + Timeline.cpp + CVTracker.cpp) # Video effects set(EFFECTS_SOURCES @@ -365,7 +371,8 @@ endif() # Link remaining dependency libraries target_link_libraries(openshot PUBLIC ${LIBOPENSHOT_AUDIO_LIBRARIES} - ${PROFILER}) + ${PROFILER} + ${OpenCV_LIBS}) if(ImageMagick_FOUND) target_link_libraries(openshot PUBLIC ${ImageMagick_LIBRARIES}) @@ -384,6 +391,10 @@ endif() ############### CLI EXECUTABLES ################ # Create test executable add_executable(openshot-example examples/Example.cpp) +# Create test Opencv executable +add_executable( openshotCV-example examples/Example_opencv.cpp ) + + # Define path to test input files SET(TEST_MEDIA_PATH "${PROJECT_SOURCE_DIR}/src/examples/") @@ -393,9 +404,14 @@ endif() target_compile_definitions(openshot-example PRIVATE -DTEST_MEDIA_PATH="${TEST_MEDIA_PATH}" ) +target_compile_definitions(openshotCV-example PRIVATE + -DTEST_MEDIA_PATH="${TEST_MEDIA_PATH}" ) + # Link test executable to the new library target_link_libraries(openshot-example openshot) +target_link_libraries( openshotCV-example ${OpenCV_LIBS} openshot) + add_executable(openshot-html-test examples/ExampleHtml.cpp) target_link_libraries(openshot-html-test openshot Qt5::Gui) diff --git a/src/CVTracker.cpp b/src/CVTracker.cpp new file mode 100644 index 00000000..1f8866b9 --- /dev/null +++ b/src/CVTracker.cpp @@ -0,0 +1,81 @@ +#include "../include/CVTracker.h" + +using namespace cv; + + +CVTracker::CVTracker(){ + // List of tracker types in OpenCV 3.4.1 + std::string trackerTypes[8] = {"BOOSTING", "MIL", "KCF", "TLD","MEDIANFLOW", "GOTURN", "MOSSE", "CSRT"}; + // vector trackerTypes(types, std::end(types)); + + // Create a tracker + trackerType = trackerTypes[2]; + + tracker = select_tracker(trackerType); + +} + +Ptr CVTracker::select_tracker(std::string trackerType){ + Ptr t; + #if (CV_MINOR_VERSION < 3) + { + t = Tracker::create(trackerType); + } + #else + { + if (trackerType == "BOOSTING") + t = TrackerBoosting::create(); + if (trackerType == "MIL") + t = TrackerMIL::create(); + if (trackerType == "KCF") + t = TrackerKCF::create(); + if (trackerType == "TLD") + t = TrackerTLD::create(); + if (trackerType == "MEDIANFLOW") + t = TrackerMedianFlow::create(); + if (trackerType == "GOTURN") + t = TrackerGOTURN::create(); + if (trackerType == "MOSSE") + t = TrackerMOSSE::create(); + if (trackerType == "CSRT") + t = TrackerCSRT::create(); + } + #endif + + return t; +} + + +bool CVTracker::initTracker(Rect2d initial_bbox, Mat &frame){ + // Rect2d bbox(287, 23, 86, 320); + bbox = initial_bbox; + + // Uncomment the line below to select a different bounding box + // bbox = selectROI(frame, false); + // Display bounding box. + rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 ); + + tracker = select_tracker(trackerType); + + tracker->init(frame, bbox); + + return true; +} + +bool CVTracker::trackFrame(Mat &frame){ + // Update the tracking result + bool ok = tracker->update(frame, bbox); + + if (ok) + { + // Tracking success : Draw the tracked object + rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 ); + } + else + { + // Tracking failure detected. + putText(frame, "Tracking failure detected", Point(100,80), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0,0,255),2); + } + + return ok; +} diff --git a/src/examples/Boneyard Memories.mp4 b/src/examples/Boneyard Memories.mp4 new file mode 100644 index 00000000..9b6e9854 Binary files /dev/null and b/src/examples/Boneyard Memories.mp4 differ diff --git a/src/examples/Example_opencv.cpp b/src/examples/Example_opencv.cpp new file mode 100644 index 00000000..69b44d03 --- /dev/null +++ b/src/examples/Example_opencv.cpp @@ -0,0 +1,143 @@ +/** + * @file + * @brief Source file for Example Executable (example app for libopenshot) + * @author Jonathan Thomas + * + * @ref License + */ + +/* LICENSE + * + * Copyright (c) 2008-2019 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 . + */ + +#include +#include +#include +#include +#include "../../include/CVTracker.h" + + +#include "../../include/OpenShot.h" +#include "../../include/CrashHandler.h" + +using namespace openshot; +using namespace cv; + + +cv::Mat qimage2mat( std::shared_ptr& qimage) { + + cv::Mat mat = cv::Mat(qimage->height(), qimage->width(), CV_8UC4, (uchar*)qimage->bits(), qimage->bytesPerLine()); + cv::Mat mat2 = cv::Mat(mat.rows, mat.cols, CV_8UC3 ); + int from_to[] = { 0,0, 1,1, 2,2 }; + cv::mixChannels( &mat, 1, &mat2, 1, from_to, 3 ); + return mat2.clone(); +}; + + +int main(int argc, char* argv[]) { + + openshot::Settings *s = openshot::Settings::Instance(); + s->HARDWARE_DECODER = 2; // 1 VA-API, 2 NVDEC, 6 VDPAU + s->HW_DE_DEVICE_SET = 0; + + std::string input_filepath = TEST_MEDIA_PATH; + input_filepath += "Boneyard Memories.mp4"; + + openshot::FFmpegReader r9(input_filepath); + r9.Open(); + r9.DisplayInfo(); + + /* WRITER ---------------- */ + openshot::FFmpegWriter w9("metadata.mp4"); + + // Set options + w9.SetAudioOptions(true, "libmp3lame", r9.info.sample_rate, r9.info.channels, r9.info.channel_layout, 128000); + w9.SetVideoOptions(true, "libx264", r9.info.fps, 1024, 576, openshot::Fraction(1,1), false, false, 3000000); + + w9.info.metadata["title"] = "testtest"; + w9.info.metadata["artist"] = "aaa"; + w9.info.metadata["album"] = "bbb"; + w9.info.metadata["year"] = "2015"; + w9.info.metadata["description"] = "ddd"; + w9.info.metadata["comment"] = "eee"; + w9.info.metadata["comment"] = "comment"; + w9.info.metadata["copyright"] = "copyright OpenShot!"; + + // Open writer + w9.Open(); + // opencv display window + cv::namedWindow("Display Image", cv::WINDOW_NORMAL ); + + CVTracker kcfTracker; + bool trackerInit = false; + + + for (long int frame = 1100; frame <= 1500; frame++) + { + //int frame_number = (rand() % 750) + 1; + int frame_number = frame; + std::shared_ptr f = r9.GetFrame(frame_number); + + std::shared_ptr qimage = f->GetImage(); + // qimage->convertToFormat(QImage::Format_RGB888); + + // convert to opencv image + cv::Mat cvimage = qimage2mat(qimage); + cvtColor(cvimage, cvimage, CV_RGB2BGR); + + + if(!trackerInit){ + // Rect2d bbox(287, 23, 86, 320); + Rect2d bbox = selectROI("Display Image", cvimage); + + kcfTracker.initTracker(bbox, cvimage); + trackerInit = true; + } + else{ + trackerInit = kcfTracker.trackFrame(cvimage); + + } + + + // opencv code + if ( !cvimage.data ) + { + std::cout << "No image data \n"; + } + + cv::imshow("Display Image", cvimage); + + cv::waitKey(30); + + + w9.WriteFrame(f); + } + + // Close writer & reader + w9.Close(); + + // Close timeline + r9.Close(); + + std::cout << "Completed successfully!" << std::endl; + + return 0; +}