Commit cc3faa0d authored by Matteo's avatar Matteo
Browse files

update Irregularity Classes

parent 8fe0315d
...@@ -4,37 +4,79 @@ ...@@ -4,37 +4,79 @@
#include <boost/uuid/uuid_generators.hpp> #include <boost/uuid/uuid_generators.hpp>
#include "Irregularity.h" #include "Irregularity.h"
Irregularity::Irregularity(const Irregularity& other)
: id(other.id), source(other.source), time_label(other.time_label), type(other.type) {}
Irregularity::Irregularity(Source source, string time_label, IrregularityType type, string image_URI) Irregularity::Irregularity(Irregularity&& other) noexcept
{ : id(std::move(other.id)), source(other.source), time_label(std::move(other.time_label)), type(std::move(other.type)) {}
Irregularity::Irregularity(Source source, string time_label) {
this->id = boost::uuids::random_generator()(); this->id = boost::uuids::random_generator()();
this->source = source; this->source = source;
this->time_label = time_label; this->time_label = time_label;
this->type = type; this->type = std::nullopt;
this->image_URI = image_URI;
} }
Irregularity::~Irregularity() {} Irregularity::Irregularity(Source source, string time_label, IrregularityType type) {
this->id = boost::uuids::random_generator()();
this->source = source;
this->time_label = time_label;
this->type = type;
}
json Irregularity::toJSON() { json Irregularity::to_JSON() const {
json j; json j;
j["IrregularityID"] = boost::lexical_cast<string>(this->id); j["IrregularityID"] = boost::lexical_cast<string>(this->id);
j["Source"] = sourceToString(this->source); j["Source"] = sourceToString(this->source);
j["TimeLabel"] = this->time_label; j["TimeLabel"] = this->time_label;
j["IrregularityType"] = irregularityTypeToString(this->type); if (this->type.has_value())
if (!this->image_URI.empty()) j["IrregularityType"] = irregularityTypeToString(this->type.value());
j["ImageURI"] = this->image_URI;
if (this->image_URI.has_value())
j["ImageURI"] = this->image_URI.value();
if (this->audio_URI.has_value())
j["AudioURI"] = this->audio_URI.value();
return j; return j;
} }
Irregularity Irregularity::fromJSON(json j) { Irregularity Irregularity::from_JSON(const json& j) {
Source source = sourceFromString(j["Source"]);
string time_label = j["TimeLabel"];
IrregularityType type = irregularityTypeFromString(j["IrregularityType"]);
return Irregularity(source, time_label, type);
}
Source Irregularity::get_source() const {
return this->source;
}
string Irregularity::get_time_label() const {
return this->time_label;
}
std::optional<IrregularityType> Irregularity::get_type() const {
return this->type;
}
boost::uuids::uuid Irregularity::get_id() const {
return this->id;
}
std::optional<string> Irregularity::get_audio_URI() const {
return this->audio_URI;
}
Irregularity& Irregularity::set_audio_URI(string audio_URI) {
this->audio_URI = audio_URI;
return *this;
}
return Irregularity( std::optional<string> Irregularity::get_image_URI() const {
sourceFromString(j["Source"]), return this->image_URI;
j["TimeLabel"], }
irregularityTypeFromString(j["IrregularityType"]),
j["ImageURI"] Irregularity& Irregularity::set_image_URI(string image_URI) {
); this->image_URI = image_URI;
return *this;
} }
...@@ -12,18 +12,83 @@ using json = nlohmann::json; ...@@ -12,18 +12,83 @@ using json = nlohmann::json;
* @brief an irregularity of the tape detected by the system * @brief an irregularity of the tape detected by the system
* *
*/ */
struct Irregularity class Irregularity {
{ private:
boost::uuids::uuid id; boost::uuids::uuid id;
Source source; Source source;
string time_label; string time_label;
IrregularityType type; std::optional<IrregularityType> type;
string image_URI; std::optional<string> image_URI;
std::optional<string> audio_URI;
Irregularity(Source source, string time_label, IrregularityType type, string image_URI); public:
~Irregularity(); Irregularity(const Irregularity& other);
json toJSON(); Irregularity(Irregularity&& other) noexcept;
static Irregularity fromJSON(json j); Irregularity(Source source, string time_label);
Irregularity(Source source, string time_label, IrregularityType type);
~Irregularity() = default;
/**
* @brief Convert the Irregularity to a JSON object
*
* @return json
*/
json to_JSON() const;
/**
* @brief Create an Irregularity object from a JSON object
*
* @param j the JSON object
* @return Irregularity
*/
static Irregularity from_JSON(const json& j);
/**
* @brief Get the source object
*
* @return Source
*/
Source get_source() const;
/**
* @brief Get the time label object
*
* @return string
*/
string get_time_label() const;
/**
* @brief Get the type object
*
* @return IrregularityType
*/
std::optional<IrregularityType> get_type() const;
/**
* @brief Get the id object
*
* @return boost::uuids::uuid
*/
boost::uuids::uuid get_id() const;
/**
* @brief Get the audio URI object
*
* @return std::optional<string>
*/
std::optional<string> get_audio_URI() const;
/**
* @brief Get the image URI object
*
* @return std::optional<string>
*/
std::optional<string> get_image_URI() const;
/**
* @brief Set the audio URI object
*
* @param audio_URI
* @return Irregularity&
*/
Irregularity& set_audio_URI(string audio_URI);
/**
* @brief Set the image URI object
*
* @param image_URI
* @return Irregularity&
*/
Irregularity& set_image_URI(string image_URI);
}; };
#endif // IRREGULARITY_H #endif // IRREGULARITY_H
\ No newline at end of file
#include <exception> #include <exception>
#include "IrregularityFile.h" #include "IrregularityFile.h"
#include <algorithm>
#include <iterator>
#include <memory>
IrregularityFile::IrregularityFile(uint16_t offset, std::list<Irregularity> irregularities) IrregularityFile::IrregularityFile(std::optional<uint16_t> offset) : offset_(offset) {}
: offset(offset), irregularities(irregularities) {}
IrregularityFile::~IrregularityFile() {} IrregularityFile::IrregularityFile(const IrregularityFile &rhs) {
std::transform(rhs.irregularities_.begin(), rhs.irregularities_.end(),
json IrregularityFile::toJSON() { std::back_inserter(irregularities_),
[](const std::unique_ptr<Irregularity> &ptr) {
json j; return std::make_unique<Irregularity>(*ptr);
});
}
j["Offset"] = this->offset; IrregularityFile& IrregularityFile::add(std::unique_ptr<Irregularity> irregularity) {
irregularities_.push_back(std::move(irregularity));
return *this;
}
return j; IrregularityFile& IrregularityFile::remove_by_id(const boost::uuids::uuid id) {
auto it = std::find_if(irregularities_.begin(), irregularities_.end(), [&id](const std::unique_ptr<Irregularity>& irregularity) {
return irregularity->get_id() == id;
});
if (it != irregularities_.end()) {
irregularities_.erase(it);
}
return *this;
} }
IrregularityFile IrregularityFile::fromJSON(json j) { IrregularityFile& IrregularityFile::sort() {
throw "Not implemented"; std::sort(irregularities_.begin(), irregularities_.end(), [](const std::unique_ptr<Irregularity>& a, const std::unique_ptr<Irregularity>& b) {
return a->get_time_label() < b->get_time_label();
});
return *this;
} }
uint16_t IrregularityFile::getOffset() const { std::optional<uint16_t> IrregularityFile::get_offset() const {
return this->offset; return offset_;
} }
std::list<Irregularity> IrregularityFile::getIrregularities() const { std::vector<std::unique_ptr<Irregularity>>::iterator IrregularityFile::begin() {
return this->irregularities; return irregularities_.begin();
} }
IrregularityFile& IrregularityFile::add(const Irregularity irregularity) { std::vector<std::unique_ptr<Irregularity>>::iterator IrregularityFile::end() {
this->irregularities.push_back(irregularity); return irregularities_.end();
return *this;
} }
IrregularityFile& IrregularityFile::remove_by_id(const boost::uuids::uuid id) { json IrregularityFile::toJSON() const {
for (auto it = this->irregularities.begin(); it != this->irregularities.end(); ++it) { json j;
if (it->id == id) { j["Offset"] = offset_.value_or(0);
this->irregularities.erase(it); j["Irregularities"] = json::array();
break; for (const auto& irregularity : irregularities_) {
} j["Irregularities"].push_back(irregularity->to_JSON());
} }
return *this; return j;
} }
IrregularityFile& IrregularityFile::sort() { IrregularityFile IrregularityFile::fromJSON(const json j) {
this->irregularities.sort([](const Irregularity& a, const Irregularity& b) { if (!j.contains("Offset") || !j.contains("Irregularities")) {
return a.time_label < b.time_label; throw std::invalid_argument("Invalid JSON");
}); }
return *this; IrregularityFile irregularity_file(j["Offset"].get<uint16_t>());
} for (const auto& irregularity : j["Irregularities"]) {
\ No newline at end of file irregularity_file.add(std::make_unique<Irregularity>(Irregularity::from_JSON(irregularity)));
}
return irregularity_file;
}
#ifndef IRREGULARITY_FILE_H #ifndef IRREGULARITY_FILE_H
#define IRREGULARITY_FILE_H #define IRREGULARITY_FILE_H
#include <list>
#include <vector>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include "Irregularity.h" #include "Irregularity.h"
#include <optional>
using json = nlohmann::json; using json = nlohmann::json;
...@@ -11,25 +13,71 @@ using json = nlohmann::json; ...@@ -11,25 +13,71 @@ using json = nlohmann::json;
* @brief An IrregularityFile is a collection of Irregularities detected on a tape. * @brief An IrregularityFile is a collection of Irregularities detected on a tape.
* *
*/ */
class IrregularityFile class IrregularityFile {
{
private:
/* data */
uint16_t offset;
std::list<Irregularity> irregularities;
public: public:
IrregularityFile(uint16_t offset, std::list<Irregularity> irregularities); /**
~IrregularityFile(); * @brief Create an IrregularityFile object from a JSON object
*
* @param j
* @return IrregularityFile
*/
static IrregularityFile fromJSON(const json j); static IrregularityFile fromJSON(const json j);
json toJSON(); /**
* @brief Convert the IrregularityFile to a JSON object
uint16_t getOffset() const; *
std::list<Irregularity> getIrregularities() const; * @return json
IrregularityFile& add(const Irregularity irregularity); */
json toJSON() const;
IrregularityFile(std::optional<uint16_t> offset = std::nullopt);
/**
* @brief Copy constructor
*
* @param rhs
*/
IrregularityFile(const IrregularityFile &rhs);
~IrregularityFile() {};
/**
* @brief Add an Irregularity to the IrregularityFile
*
* @param irregularity
* @return IrregularityFile&
*/
IrregularityFile& add(std::unique_ptr<Irregularity> irregularity);
/**
* @brief Remove an Irregularity from the IrregularityFile
*
* @param id
* @return IrregularityFile&
*/
IrregularityFile& remove_by_id(const boost::uuids::uuid id); IrregularityFile& remove_by_id(const boost::uuids::uuid id);
/**
* @brief Sort the IrregularityFile by time_label
*
* @return IrregularityFile&
*/
IrregularityFile& sort(); IrregularityFile& sort();
/**
* @brief Get the offset object
*
* @return std::optional<uint16_t>
*/
std::optional<uint16_t> get_offset() const;
/**
* @brief Get an iterator to the beginning of the IrregularityFile
*
* @return std::vector<std::unique_ptr<Irregularity>>::iterator
*/
std::vector<std::unique_ptr<Irregularity>>::iterator begin();
/**
* @brief Get an iterator to the end of the IrregularityFile
*
* @return std::vector<std::unique_ptr<Irregularity>>::iterator
*/
std::vector<std::unique_ptr<Irregularity>>::iterator end();
private:
std::optional<uint16_t> offset_;
std::vector<std::unique_ptr<Irregularity>> irregularities_;
}; };
#endif // IRREGULARITY_FILE_H #endif // IRREGULARITY_FILE_HPP
\ No newline at end of file
#include <stdexcept> #include <stdexcept>
#include "enums.h" #include "enums.h"
std::string sourceToString(Source source) std::string sourceToString(Source source) {
{
switch (source) { switch (source) {
case Audio: case Audio:
return "a"; return "a";
...@@ -15,8 +14,7 @@ std::string sourceToString(Source source) ...@@ -15,8 +14,7 @@ std::string sourceToString(Source source)
} }
} }
Source sourceFromString(std::string source) Source sourceFromString(std::string source) {
{
if (source == "a") if (source == "a")
return Audio; return Audio;
else if (source == "v") else if (source == "v")
...@@ -27,8 +25,7 @@ Source sourceFromString(std::string source) ...@@ -27,8 +25,7 @@ Source sourceFromString(std::string source)
throw std::invalid_argument("Invalid Source"); throw std::invalid_argument("Invalid Source");
} }
std::string irregularityTypeToString(IrregularityType type) std::string irregularityTypeToString(IrregularityType type) {
{
switch (type) { switch (type) {
case BRANDS_ON_TAPE: case BRANDS_ON_TAPE:
return "b"; return "b";
...@@ -63,8 +60,7 @@ std::string irregularityTypeToString(IrregularityType type) ...@@ -63,8 +60,7 @@ std::string irregularityTypeToString(IrregularityType type)
} }
} }
IrregularityType irregularityTypeFromString(std::string type) IrregularityType irregularityTypeFromString(std::string type) {
{
if (type == "b") if (type == "b")
return BRANDS_ON_TAPE; return BRANDS_ON_TAPE;
else if (type == "sp") else if (type == "sp")
......
...@@ -26,11 +26,7 @@ ...@@ -26,11 +26,7 @@
* An Irregularity can be detected by the Audio analyser, the Video analyser or both. * An Irregularity can be detected by the Audio analyser, the Video analyser or both.
* *
*/ */
enum Source{ enum Source { Audio, Video, Both };
Audio,
Video,
Both
};
/** /**
* @enum IrregularityType * @enum IrregularityType
......
/** /**
* @mainpage MPAI CAE-ARP Video Analyser
* @file main.cpp * @file main.cpp
* MPAI CAE-ARP Video Analyser. * MPAI CAE-ARP Video Analyser.
* *
...@@ -10,7 +11,8 @@ ...@@ -10,7 +11,8 @@
* WARNING: * WARNING:
* Currently, this program is only compatible with the Studer A810 and videos recorded in PAL standard. * Currently, this program is only compatible with the Studer A810 and videos recorded in PAL standard.
* *
* @authors Nadir Dalla Pozza <nadir.dallapozza@unipd.it>, Matteo Spanio <dev2@audioinnova.com> * @author Nadir Dalla Pozza <nadir.dallapozza@unipd.it>
* @author Matteo Spanio <dev2@audioinnova.com>
* @copyright 2023, Audio Innova S.r.l. * @copyright 2023, Audio Innova S.r.l.
* @credits Niccolò Pretto, Nadir Dalla Pozza, Sergio Canazza * @credits Niccolò Pretto, Nadir Dalla Pozza, Sergio Canazza
* @license GPL v3.0 * @license GPL v3.0
...@@ -50,6 +52,8 @@ ...@@ -50,6 +52,8 @@
#include "lib/files.h" #include "lib/files.h"
#include "lib/colors.h" #include "lib/colors.h"
#include "lib/time.h" #include "lib/time.h"
#include "lib/Irregularity.h"
#include "lib/IrregularityFile.h"
using namespace cv; using namespace cv;
using namespace std; using namespace std;
...@@ -639,12 +643,12 @@ void processing(cv::VideoCapture videoCapture) { ...@@ -639,12 +643,12 @@ void processing(cv::VideoCapture videoCapture) {
if (frame.empty()) { if (frame.empty()) {
cout << endl << "Empty frame!" << endl; cout << endl << "Empty frame!" << endl;
videoCapture.release(); videoCapture.release();
break; return;
} }
int msToEnd = video_length_ms - video_current_ms; int msToEnd = video_length_ms - video_current_ms;
if (video_current_ms == 0) // With OpenCV library, this happens at the last few frames of the video before realising that "frame" is empty. if (video_current_ms == 0) // With OpenCV library, this happens at the last few frames of the video before realising that "frame" is empty.
break; return;
// Variables to display program status // Variables to display program status
int secToEnd = msToEnd / 1000; int secToEnd = msToEnd / 1000;
...@@ -691,27 +695,9 @@ void processing(cv::VideoCapture videoCapture) { ...@@ -691,27 +695,9 @@ void processing(cv::VideoCapture videoCapture) {
cv::imwrite(irregularityImagesPath / irregularityImageFilename, oddFrame); cv::imwrite(irregularityImagesPath / irregularityImageFilename, oddFrame);
// Append Irregularity information to JSON // Append Irregularity information to JSON
boost::uuids::uuid uuid = boost::uuids::random_generator()(); Irregularity irreg = Irregularity(Source::Video, timeLabel);
irregularityFileOutput1["Irregularities"] += { irregularityFileOutput1["Irregularities"] += irreg.to_JSON();
{ irregularityFileOutput2["Irregularities"] += irreg.set_image_URI(irregularityImagesPath.string() + "/" + irregularityImageFilename).to_JSON();
"IrregularityID", boost::lexical_cast<string>(uuid)
}, {
"Source", "v"
}, {
"TimeLabel", timeLabel
}
};
irregularityFileOutput2["Irregularities"] += {
{
"IrregularityID", boost::lexical_cast<string>(uuid)
}, {
"Source", "v"
}, {
"TimeLabel", timeLabel
}, {
"ImageURI", irregularityImagesPath.string() + "/" + irregularityImageFilename
}
};
lastSaved = video_current_ms; lastSaved = video_current_ms;
savedFrames++; savedFrames++;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment