2020-06-26 10:29:08 -03:00
|
|
|
/**
|
|
|
|
|
* @file
|
|
|
|
|
* @brief Source file for Example Executable (example app for libopenshot)
|
|
|
|
|
* @author Jonathan Thomas <jonathan@openshot.org>
|
|
|
|
|
*
|
|
|
|
|
* @ref License
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* LICENSE
|
|
|
|
|
*
|
|
|
|
|
* Copyright (c) 2008-2019 OpenShot Studios, LLC
|
|
|
|
|
* <http://www.openshotstudios.com/>. 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 <http://www.openshot.org/>.
|
|
|
|
|
*
|
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <memory>
|
2020-07-09 20:26:01 -03:00
|
|
|
#include "../../include/CVTracker.h"
|
|
|
|
|
#include "../../include/CVStabilization.h"
|
2020-06-26 10:29:08 -03:00
|
|
|
|
|
|
|
|
#include "../../include/OpenShot.h"
|
|
|
|
|
#include "../../include/CrashHandler.h"
|
|
|
|
|
|
|
|
|
|
using namespace openshot;
|
2020-07-21 21:42:09 -03:00
|
|
|
using namespace std;
|
2020-06-27 19:30:15 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Show the pre-processed clip on the screen
|
2020-07-09 20:26:01 -03:00
|
|
|
void displayClip(openshot::Clip &r9){
|
2020-07-21 21:42:09 -03:00
|
|
|
|
2020-07-02 19:09:04 -03:00
|
|
|
// Opencv display window
|
|
|
|
|
cv::namedWindow("Display Image", cv::WINDOW_NORMAL );
|
|
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Get video lenght
|
2020-07-02 19:09:04 -03:00
|
|
|
int videoLenght = r9.Reader()->info.video_length;
|
|
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Loop through the clip and show it with the effects, if any
|
2020-07-02 19:09:04 -03:00
|
|
|
for (long int frame = 0; frame < videoLenght; frame++)
|
|
|
|
|
{
|
|
|
|
|
int frame_number = frame;
|
2020-07-21 21:42:09 -03:00
|
|
|
// Get the frame
|
2020-07-02 19:09:04 -03:00
|
|
|
std::shared_ptr<openshot::Frame> f = r9.GetFrame(frame_number);
|
2020-07-21 21:42:09 -03:00
|
|
|
// Grab OpenCV::Mat image
|
2020-07-02 19:09:04 -03:00
|
|
|
cv::Mat cvimage = f->GetImageCV();
|
2020-07-21 21:42:09 -03:00
|
|
|
// Convert color scheme from RGB (QImage scheme) to BGR (OpenCV scheme)
|
|
|
|
|
cv::cvtColor(cvimage, cvimage, cv::COLOR_RGB2BGR);
|
|
|
|
|
// Display the frame
|
2020-07-02 20:18:01 -03:00
|
|
|
cv::imshow("Display Image", cvimage);
|
2020-07-21 21:42:09 -03:00
|
|
|
|
|
|
|
|
// Press ESC on keyboard to exit
|
2020-07-02 19:09:04 -03:00
|
|
|
char c=(char)cv::waitKey(25);
|
|
|
|
|
if(c==27)
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-21 21:42:09 -03:00
|
|
|
// Destroy all remaining windows
|
|
|
|
|
cv::destroyAllWindows();
|
|
|
|
|
}
|
2020-07-02 19:09:04 -03:00
|
|
|
|
2020-07-22 14:05:19 -03:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
The following methods are just for getting JSON info to the pre-processing effects
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Return JSON string for the tracker effect
|
|
|
|
|
string trackerJson(cv::Rect2d r, bool onlyProtoPath){
|
|
|
|
|
// Set the tracker
|
|
|
|
|
string tracker = "KCF";
|
|
|
|
|
|
|
|
|
|
// Construct all the composition of the JSON string
|
|
|
|
|
string trackerType = "\"tracker_type\": \"" + tracker + "\"";
|
|
|
|
|
string protobuf_data_path = "\"protobuf_data_path\": \"kcf_tracker.data\"";
|
|
|
|
|
stringstream bboxCoords;
|
|
|
|
|
bboxCoords << "\"bbox\": {\"x\":"<<r.x<<", \"y\": "<<r.y<<", \"w\": "<<r.width<<", \"h\": "<<r.height<<"}";
|
|
|
|
|
|
|
|
|
|
// Return only the the protobuf path in JSON format
|
|
|
|
|
if(onlyProtoPath)
|
|
|
|
|
return "{" + protobuf_data_path + "}";
|
|
|
|
|
// Return all the parameters for the pre-processing effect
|
|
|
|
|
else
|
|
|
|
|
return "{" + protobuf_data_path + ", " + trackerType + ", " + bboxCoords.str() + "}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return JSON string for the stabilizer effect
|
|
|
|
|
string stabilizerJson(bool onlyProtoPath){
|
|
|
|
|
// Set smoothing window value
|
|
|
|
|
int smoothingWindow = 30;
|
|
|
|
|
|
|
|
|
|
// Construct all the composition of the JSON string
|
|
|
|
|
string protobuf_data_path = "\"protobuf_data_path\": \"example_stabilizer.data\"";
|
|
|
|
|
stringstream smoothing_window;
|
|
|
|
|
smoothing_window << "\"smoothing_window\": "<< smoothingWindow;
|
|
|
|
|
|
|
|
|
|
// Return only the the protobuf path in JSON format
|
|
|
|
|
if(onlyProtoPath)
|
|
|
|
|
return "{" + protobuf_data_path + "}";
|
|
|
|
|
// Return all the parameters for the pre-processing effect
|
|
|
|
|
else
|
|
|
|
|
return "{" + protobuf_data_path + ", " + smoothing_window.str() + "}";
|
2020-07-02 19:09:04 -03:00
|
|
|
}
|
2020-06-27 19:30:15 -03:00
|
|
|
|
2020-07-22 14:05:19 -03:00
|
|
|
string objectDetectionJson(bool onlyProtoPath){
|
|
|
|
|
|
|
|
|
|
// Construct all the composition of the JSON string
|
|
|
|
|
string protobuf_data_path = "\"protobuf_data_path\": \"example_object_detection.data\"";
|
|
|
|
|
|
|
|
|
|
// Return only the the protobuf path in JSON format
|
|
|
|
|
if(onlyProtoPath)
|
|
|
|
|
return "{" + protobuf_data_path + "}";
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-26 10:29:08 -03:00
|
|
|
int main(int argc, char* argv[]) {
|
|
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Set pre-processing effects
|
|
|
|
|
bool TRACK_DATA = false;
|
|
|
|
|
bool SMOOTH_VIDEO = true;
|
|
|
|
|
bool OBJECT_DETECTION_DATA = false;
|
2020-06-27 19:30:15 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Get media path
|
|
|
|
|
std::stringstream path;
|
|
|
|
|
path << TEST_MEDIA_PATH << "test.avi";
|
2020-06-26 10:29:08 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Thread controller just for the pre-processing constructors, it won't be used
|
|
|
|
|
ProcessingController processingController;
|
2020-06-26 10:29:08 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Open clip
|
|
|
|
|
openshot::Clip r9(path.str());
|
|
|
|
|
r9.Open();
|
2020-06-26 10:29:08 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Aplly tracking effect on the clip
|
|
|
|
|
if(TRACK_DATA){
|
2020-07-16 21:10:02 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Take the bounding box coordinates
|
|
|
|
|
cv::Mat roi = r9.GetFrame(0)->GetImageCV();
|
|
|
|
|
cv::Rect2d r = cv::selectROI(roi);
|
|
|
|
|
cv::destroyAllWindows();
|
2020-07-16 21:10:02 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Create a tracker object by passing a JSON string and a thread controller, this last one won't be used
|
|
|
|
|
// JSON info: path to save the tracked data, type of tracker and bbox coordinates
|
|
|
|
|
CVTracker tracker(trackerJson(r, false), processingController);
|
2020-07-16 21:10:02 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Start the tracking
|
|
|
|
|
tracker.trackClip(r9);
|
|
|
|
|
// Save the tracked data
|
|
|
|
|
tracker.SaveTrackedData();
|
2020-07-16 21:10:02 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Create a tracker effect
|
|
|
|
|
EffectBase* e = EffectInfo().CreateEffect("Tracker");
|
2020-07-16 21:10:02 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Pass a JSON string with the saved tracked data
|
|
|
|
|
// The effect will read and save the tracking in a map::<frame,data_struct>
|
|
|
|
|
e->SetJson(trackerJson(r, true));
|
|
|
|
|
// Add the effect to the clip
|
|
|
|
|
r9.AddEffect(e);
|
|
|
|
|
}
|
2020-07-16 21:10:02 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Aplly stabilizer effect on the clip
|
|
|
|
|
if(SMOOTH_VIDEO){
|
2020-07-16 21:10:02 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Create a stabilizer object by passing a JSON string and a thread controller, this last one won't be used
|
|
|
|
|
// JSON info: path to save the stabilized data and smoothing window value
|
|
|
|
|
CVStabilization stabilizer(stabilizerJson(false), processingController);
|
2020-07-16 21:10:02 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Start the stabilization
|
|
|
|
|
stabilizer.stabilizeClip(r9);
|
|
|
|
|
// Save the stabilization data
|
|
|
|
|
stabilizer.SaveStabilizedData();
|
2020-07-16 21:10:02 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Create a stabilizer effect
|
|
|
|
|
EffectBase* e = EffectInfo().CreateEffect("Stabilizer");
|
2020-07-16 21:10:02 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Pass a JSON string with the saved stabilized data
|
|
|
|
|
// The effect will read and save the stabilization in a map::<frame,data_struct>
|
|
|
|
|
e->SetJson(stabilizerJson(true));
|
|
|
|
|
// Add the effect to the clip
|
|
|
|
|
r9.AddEffect(e);
|
|
|
|
|
}
|
2020-07-16 21:10:02 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
if(OBJECT_DETECTION_DATA){
|
|
|
|
|
// CVObjectDetection objectDetection("GPU");
|
|
|
|
|
// objectDetection.ProcessClip(r9);
|
|
|
|
|
}
|
2020-06-26 10:29:08 -03:00
|
|
|
|
2020-07-21 21:42:09 -03:00
|
|
|
// Show the pre-processed clip on the screen
|
|
|
|
|
displayClip(r9);
|
|
|
|
|
|
|
|
|
|
// Close timeline
|
|
|
|
|
r9.Close();
|
2020-06-26 10:29:08 -03:00
|
|
|
|
|
|
|
|
std::cout << "Completed successfully!" << std::endl;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|