You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
409 lines
16 KiB
409 lines
16 KiB
9 years ago
|
//------------------------------------------------------------------------------
|
||
|
//
|
||
|
// Project: Anonymizer
|
||
|
//
|
||
|
// Brno University of Technology
|
||
|
// Faculty of Information Technology
|
||
|
//
|
||
|
//------------------------------------------------------------------------------
|
||
|
//
|
||
|
// This project was financially supported by project VG20102015006 funds
|
||
|
// provided by Ministry of the Interior of the Czech republic.
|
||
|
//
|
||
|
//------------------------------------------------------------------------------
|
||
|
/*!
|
||
|
|
||
|
@file videotracker.h
|
||
|
@brief Header file
|
||
|
@details Details
|
||
|
@authors Martin Borek (mborekcz@gmail.com)
|
||
|
@authors Filip Orsag (orsag@fit.vutbr.cz)
|
||
|
@date 2014-2015
|
||
|
@note This project was supported by MV CR project VG20102015006.
|
||
|
@copyright BUT OPEN SOURCE LICENCE (see License.txt)
|
||
|
|
||
|
*/
|
||
|
|
||
|
#ifndef VIDEOTRACKER_H
|
||
|
#define VIDEOTRACKER_H
|
||
|
|
||
|
#include <opencv/cv.h>
|
||
|
#include <opencv/cvaux.h>
|
||
|
#include <opencv/cxcore.h>
|
||
|
#include <opencv/highgui.h>
|
||
|
|
||
|
#include <QObject>
|
||
|
#include <QProgressDialog>
|
||
|
#include <QApplication>
|
||
|
|
||
|
#include <memory>
|
||
|
|
||
|
#include "ffmpegplayer.h"
|
||
|
#include "trackingalgorithm.h"
|
||
|
#include "trackedobject.h"
|
||
|
#include "videoframe.h"
|
||
|
#include "selection.h"
|
||
|
|
||
|
#include <cereal/types/vector.hpp>
|
||
|
#include <cereal/types/memory.hpp> // for shared_ptr
|
||
|
|
||
|
struct OutputException : public std::exception{};
|
||
|
struct UserCanceledException : public std::exception{};
|
||
|
|
||
|
class VideoTracker
|
||
|
{
|
||
|
|
||
|
public:
|
||
|
// CEREAL serialization
|
||
|
template<class Archive>
|
||
|
void serialize(Archive &archive)
|
||
|
{
|
||
|
archive(CEREAL_NVP(trackedObjects));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Constructor
|
||
|
*/
|
||
|
VideoTracker();
|
||
|
|
||
|
/**
|
||
|
* Constructor
|
||
|
* @param videoAddr Path to a video file
|
||
|
* @param progressDialog QT progress dialog for displaying information about video opening
|
||
|
*/
|
||
|
explicit VideoTracker(std::string const &videoAddr, QProgressDialog const *progressDialog);
|
||
|
|
||
|
/**
|
||
|
* Destructor
|
||
|
*/
|
||
|
~VideoTracker();
|
||
|
|
||
|
/**
|
||
|
* Loads a new video file.
|
||
|
* @param videoAddr Path to a video file
|
||
|
* @param progressDialog QT progress dialog for displaying information about video opening
|
||
|
*/
|
||
|
void load_video(std::string const &videoAddr, QProgressDialog const *progressDialog);
|
||
|
|
||
|
/**
|
||
|
* Returns frames per second value of the video.
|
||
|
* @return Frames per second
|
||
|
*/
|
||
|
double get_fps() const;
|
||
|
|
||
|
/**
|
||
|
* Returns information about number of frames.
|
||
|
* @return Number of frames
|
||
|
*/
|
||
|
unsigned long get_frame_count() const;
|
||
|
|
||
|
/**
|
||
|
* Returns information about video length.
|
||
|
* @return Video length in milliseconds
|
||
|
*/
|
||
|
unsigned long get_total_time() const;
|
||
|
|
||
|
/**
|
||
|
* Returns timestamp of the current frame.
|
||
|
* @return Timestamp
|
||
|
*/
|
||
|
int64_t get_frame_timestamp() const;
|
||
|
|
||
|
/**
|
||
|
* Returns time position of the current frame.
|
||
|
* @return Time position in milliseconds
|
||
|
*/
|
||
|
unsigned long get_time_position() const;
|
||
|
|
||
|
/**
|
||
|
* Returns frame number of the current frame.
|
||
|
* @return Frame number
|
||
|
*/
|
||
|
unsigned long get_frame_number() const;
|
||
|
|
||
|
/**
|
||
|
* Returns number of tracked objects
|
||
|
* @return Number of tracked objects
|
||
|
*/
|
||
|
unsigned int get_objects_count() const;
|
||
|
|
||
|
/**
|
||
|
* Tracks a new object.
|
||
|
* @param objectAppearance Object appearance
|
||
|
* @param objectName Object name
|
||
|
* @param initialPosition Initial object position
|
||
|
* @param initialTimestamp Initial timestamp
|
||
|
* @param initialTimePosition Initial time position
|
||
|
* @param initialFrameNumber Initial frame number
|
||
|
* @param endTimestampSet Is end timestamp set?
|
||
|
* @param endTimestamp End timestamp
|
||
|
* @param endTimePosition End time position
|
||
|
* @param endFrameNumber End frame number
|
||
|
* @return Object ID; First objest has ID 1. If frame at initialTimestamp is not read, -1 is returned;
|
||
|
*/
|
||
|
int add_object(const Characteristics &objectAppearance, const std::string &objectName,
|
||
|
Selection initialPosition, int64_t initialTimestamp, unsigned long initialTimePosition,
|
||
|
unsigned long initialFrameNumber, bool endTimestampSet=false, int64_t endTimestamp=0,
|
||
|
unsigned long endTimePosition=0, unsigned long endFrameNumber=0);
|
||
|
|
||
|
/**
|
||
|
* Reads a frame by its time position and returns it.
|
||
|
* @param imgFrame Altered read frame (contains tracked objects) converted to be displayed in QT
|
||
|
* @param originalImgFrame Read frame converted to be displayed in QT.
|
||
|
* @param includeOriginal Should be original frame read? If not, originalImgFrame does not contain a valid frame.
|
||
|
* @param time Time position
|
||
|
* @param progressDialog QT progress dialog for showing an information about tracking objects process
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_frame_by_time(QImage &imgFrame, QImage &originalImgFrame, bool includeOriginal, int64_t time, QProgressDialog *progressDialog);
|
||
|
|
||
|
/**
|
||
|
* Reads a frame by its timestamp and returns it.
|
||
|
* @param imgFrame Altered read frame (contains tracked objects) converted to be displayed in QT
|
||
|
* @param originalImgFrame Read frame converted to be displayed in QT.
|
||
|
* @param includeOriginal Should be original frame read? If not, originalImgFrame does not contain a valid frame.
|
||
|
* @param timestamp Timestamp
|
||
|
* @param progressDialog QT progress dialog for showing an information about tracking objects process
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_frame_by_timestamp(QImage &imgFrame, QImage &originalImgFrame, bool includeOriginal, int64_t timestamp, QProgressDialog *progressDialog);
|
||
|
|
||
|
/**
|
||
|
* Reads a frame by its frame number (index) and returns it.
|
||
|
* @param imgFrame Altered read frame (contains tracked objects) converted to be displayed in QT
|
||
|
* @param originalImgFrame Read frame converted to be displayed in QT.
|
||
|
* @param includeOriginal Should be original frame read? If not, originalImgFrame does not contain a valid frame.
|
||
|
* @param frameNumber Frame number (index)
|
||
|
* @param progressDialog QT progress dialog for showing an information about tracking objects process
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_frame_by_number(QImage &imgFrame, QImage &originalImgFrame, bool includeOriginal, unsigned long frameNumber, QProgressDialog *progressDialog);
|
||
|
|
||
|
/**
|
||
|
* Reads a frame following to the current one returns it.
|
||
|
* @param imgFrame Altered read frame (contains tracked objects) converted to be displayed in QT
|
||
|
* @param originalImgFrame Read frame converted to be displayed in QT.
|
||
|
* @param includeOriginal Should be original frame read? If not, originalImgFrame does not contain a valid frame.
|
||
|
* @param progressDialog QT progress dialog for showing an information about tracking objects process
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_next_frame(QImage &imgFrame, QImage &originalImgFrame, bool includeOriginal, QProgressDialog *progressDialog);
|
||
|
|
||
|
/**
|
||
|
* Reads a frame preceding to the current one returns it.
|
||
|
* @param imgFrame Altered read frame (contains tracked objects) converted to be displayed in QT
|
||
|
* @param originalImgFrame Read frame converted to be displayed in QT.
|
||
|
* @param includeOriginal Should be original frame read? If not, originalImgFrame does not contain a valid frame.
|
||
|
* @param progressDialog QT progress dialog for showing an information about tracking objects process
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_previous_frame(QImage &imgFrame, QImage &originalImgFrame, bool includeOriginal, QProgressDialog *progressDialog);
|
||
|
|
||
|
/**
|
||
|
* Gets the current frame and returns it.
|
||
|
* @param imgFrame Altered read frame (contains tracked objects) converted to be displayed in QT
|
||
|
* @param originalImgFrame Read frame converted to be displayed in QT.
|
||
|
* @param includeOriginal Should be original frame read? If not, originalImgFrame does not contain a valid frame.
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_current_frame(QImage &imgFrame, QImage &originalImgFrame, bool includeOriginal);
|
||
|
|
||
|
/**
|
||
|
* Reads the first frame and returns it.
|
||
|
* @param imgFrame Altered read frame (contains tracked objects) converted to be displayed in QT
|
||
|
* @param originalImgFrame Read frame converted to be displayed in QT.
|
||
|
* @param includeOriginal Should be original frame read? If not, originalImgFrame does not contain a valid frame.
|
||
|
* @param progressDialog QT progress dialog for showing an information about tracking objects process
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_first_frame(QImage &imgFrame, QImage &originalImgFrame, bool includeOriginal, QProgressDialog *progressDialog);
|
||
|
|
||
|
/**
|
||
|
* Creates an output media file including all tracked objects.
|
||
|
* Throws UserCanceledException when user clicked "Cancel" button in the progress dialog
|
||
|
* Mind there are two progress dialogs. One is in track_all() and displays infinet progress
|
||
|
* bar when counting objects positions. The second progress dialog (fileProgressDialog shows percentage of
|
||
|
* creating the output file. When the first one (in track_all()) is canceled, the second one should be
|
||
|
* canceled too
|
||
|
|
||
|
* @param filename Output filename
|
||
|
* @param fileProgressDialog QT progress dialog for showing an information about creating the file progress
|
||
|
* @param trackingProgressDialog QT progress dialog for showing an information about tracking objects process
|
||
|
* @param inFileExtension Input file extensions
|
||
|
*/
|
||
|
void create_output(std::string const &filename, QProgressDialog &fileProgressDialog,
|
||
|
QProgressDialog *trackingProgressDialog, std::string inFileExtension);
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Returns appearance of the object.
|
||
|
* @param objectID Object ID
|
||
|
* @return Object appearance
|
||
|
*/
|
||
|
Characteristics get_object_appearance(unsigned int objectID) const;
|
||
|
|
||
|
/**
|
||
|
* Returns trajectory sections of the object.
|
||
|
* @param objectID Object ID
|
||
|
* @return Trajectory section of the object
|
||
|
*/
|
||
|
std::map<int64_t, TrajectorySection> const &get_object_trajectory_sections(unsigned int objectID) const;
|
||
|
|
||
|
/**
|
||
|
* Returns computed trajectory of the object.
|
||
|
* @param objectID Object ID
|
||
|
* @return Trajectory of the object
|
||
|
*/
|
||
|
std::map<int64_t, TrajectoryEntry> const &get_object_trajectory(unsigned int objectID) const;
|
||
|
|
||
|
/**
|
||
|
* Changes appearance of the object.
|
||
|
* @param objectID Object ID
|
||
|
* @param newAppearance New appearance of the object
|
||
|
*/
|
||
|
bool change_object_appearance(unsigned int objectID, Characteristics const &newAppearance);
|
||
|
|
||
|
/**
|
||
|
* Rewinds the video to its beginning by seeking its first packet.
|
||
|
*/
|
||
|
void seek_first_packet();
|
||
|
|
||
|
// int64_t get_object_end_timestamp(unsigned int objectID, bool &isSet);
|
||
|
|
||
|
/**
|
||
|
* Return information about the end of the object.
|
||
|
* @param objectID Object ID
|
||
|
* @param timestamp Frame timestamp
|
||
|
* @param timePosition Time position
|
||
|
* @param frameNumber Frame number (index)
|
||
|
* @return True if end is set, false if it is not.
|
||
|
*/
|
||
|
bool get_object_end(unsigned int objectID, int64_t ×tamp, unsigned long &timePosition, unsigned long &frameNumber);
|
||
|
|
||
|
/**
|
||
|
* Changes a trajectory section of the object.
|
||
|
* @param objectID Object ID
|
||
|
* @param oldTimestamp Old timestamp of the section
|
||
|
* @param newTimestamp New timestamp of the section
|
||
|
* @param position Object position at the first frame of the section
|
||
|
* @param timePosition Time position of the section
|
||
|
* @param frameNumber Frame number of the section
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool change_object_trajectory_section(unsigned int objectID, int64_t oldTimestamp, int64_t newTimestamp, Selection position, unsigned long timePosition, unsigned long frameNumber);
|
||
|
|
||
|
/**
|
||
|
* Changes the end frame of the object. If set==false, the end frame will be unset and the object
|
||
|
* will be tracked till the end of the video. newTimestamp and timePosition are valid onlt if set==true.
|
||
|
* @param objectID Object ID
|
||
|
* @param set Set / Unset last frame
|
||
|
* @param newTimestamp Timestamp of the last frame
|
||
|
* @param timePosition Time position of the last frame
|
||
|
* @param frameNumber Frame number of the last frame
|
||
|
* @return False if given timestamp is lower than the timestamp of Beginning.
|
||
|
*/
|
||
|
bool change_object_end_frame(unsigned int objectID, bool set, int64_t newTimestamp=0, unsigned long timePosition=0, unsigned long frameNumber=0);
|
||
|
|
||
|
/**
|
||
|
* Deletes a trajectory section of the object
|
||
|
* @param objectID Object ID
|
||
|
* @param timestamp Trajectory section to be deleted begins at this timestamp
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool delete_object_trajectory_section(unsigned int objectID, int64_t timestamp);
|
||
|
|
||
|
/**
|
||
|
* Sets a trajectory section of the object.
|
||
|
* @param objectID Object ID
|
||
|
* @param newTimestamp New timestamp of the section
|
||
|
* @param position Object position at the first frame of the section
|
||
|
* @param timePosition Time position of the section
|
||
|
* @param frameNumber Frame number of the section
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool set_object_trajectory_section(unsigned int objectID, int64_t newTimestamp, Selection position, unsigned long timePosition, unsigned long frameNumber);
|
||
|
|
||
|
/**
|
||
|
* Returns name of the object.
|
||
|
* @param objectID Object ID
|
||
|
* @return Object name
|
||
|
*/
|
||
|
std::string get_object_name(unsigned int objectID);
|
||
|
|
||
|
/**
|
||
|
* Returns names of all objects.
|
||
|
* @return Names of all objects
|
||
|
*/
|
||
|
std::vector<std::string> get_all_objects_names();
|
||
|
|
||
|
/**
|
||
|
* Sets name of the object.
|
||
|
* @param objectID Object ID
|
||
|
* @param newName New object name
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
void set_object_name(unsigned int objectID, std::string newName);
|
||
|
|
||
|
/**
|
||
|
* Removes the object
|
||
|
* @param objectID Object ID
|
||
|
*/
|
||
|
void delete_object(unsigned int objectID);
|
||
|
|
||
|
/**
|
||
|
* Computes all trajectory for the tracked object
|
||
|
* @param objectID ObjectID
|
||
|
* @param progressDialog QT progress dialog for showing an information about tracking object process
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool track_object(unsigned int objectID, QProgressDialog *progressDialog);
|
||
|
|
||
|
/**
|
||
|
* Erases a part of the computed trajectory. This is necessary after deserialization (with CEREAL)
|
||
|
* as track_next() initializes correct sections only when the trajectory's last frame is the last
|
||
|
* frame of the previous section.
|
||
|
* @param objectID ObjectID
|
||
|
*/
|
||
|
void erase_object_trajectories_to_comply();
|
||
|
|
||
|
private:
|
||
|
/**
|
||
|
* Converts cv::Mat format (OpenCV frame) to QImage (QT)
|
||
|
* @param src Source frame in cv::Mat
|
||
|
* @return Frame for QT
|
||
|
*/
|
||
|
QImage Mat2QImage(cv::Mat const &src) const;
|
||
|
|
||
|
// previousTimestamp can be used only when previousTimestampSet==true
|
||
|
|
||
|
/**
|
||
|
|
||
|
* Draws tracking mark to the result cv::Mat. If current frame was not yet processed, processes tracking till this frame.
|
||
|
* @param originalFrame Original frame
|
||
|
* @param result Altered frame; with drawn tracked objects
|
||
|
* @param progressDialog QT progress dialog for showing an information about tracking objects process
|
||
|
* @param previousTimestampSet Used only with get_next_frame(). True - this is the following frame to the one given the last time.
|
||
|
* @param previousTimestamp Timestamp of the preceding frame. This is used only if previousTimestampSet==true.
|
||
|
* @return Returns true if successful
|
||
|
*/
|
||
|
bool track_frame(VideoFrame const *originalFrame, cv::Mat &result, QProgressDialog *progressDialog=nullptr, bool previousTimestampSet=false, int64_t previousTimestamp=0);
|
||
|
|
||
|
/**
|
||
|
* Tracks all frames. This is called when an output media file is being created.
|
||
|
* @param progressDialog QT progress dialog for showing an information about tracking objects process
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool track_all(QProgressDialog *progressDialog);
|
||
|
|
||
|
private:
|
||
|
QApplication *qApplication; // Is used for updating progress bars
|
||
|
std::shared_ptr<TrackedObject> a;
|
||
|
FFmpegPlayer *player;
|
||
|
VideoFrame *currentFrame;
|
||
|
VideoFrame *tempFrame;
|
||
|
|
||
|
std::vector<std::shared_ptr<TrackedObject>> trackedObjects;
|
||
|
};
|
||
|
|
||
|
#endif // VIDEOTRACKER_H
|