Commit c862755d authored by Matteo's avatar Matteo
Browse files

refactor main func

parent 7021d2ce
#include <filesystem>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;
using namespace std;
using json = nlohmann::json; using json = nlohmann::json;
namespace fs = std::filesystem;
void extractIrregularityImagesForAudio(std::string outputPath, const std::string videoPath, json irregularityFileInput, void extractIrregularityImagesForAudio(std::string outputPath, const std::string videoPath, json irregularityFileInput,
json &irregularityFileOutput2) { json &irregularityFileOutput2) {
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
* @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
* @version 1.1.1 * @version 1.1.2
* @status Production * @status Production
*/ */
#include <stdlib.h> #include <stdlib.h>
...@@ -58,6 +58,10 @@ ...@@ -58,6 +58,10 @@
#include "opencv2/xfeatures2d.hpp" #include "opencv2/xfeatures2d.hpp"
#include "utility.h" #include "utility.h"
#define A_IRREG_FILE_1 "AudioAnalyser_IrregularityFileOutput1.json"
#define V_IRREG_FILE_1 "VideoAnalyser_IrregularityFileOutput1.json"
#define V_IRREG_FILE_2 "VideoAnalyser_IrregularityFileOutput2.json"
using namespace cv; using namespace cv;
using namespace std; using namespace std;
using utility::Frame; using utility::Frame;
...@@ -109,12 +113,14 @@ RotatedRect rect, rectTape, rectCapstan; ...@@ -109,12 +113,14 @@ RotatedRect rect, rectTape, rectCapstan;
void pprint(string text, string color) { cout << color << text << END << endl; } void pprint(string text, string color) { cout << color << text << END << endl; }
struct Args { struct Args {
fs::path workingPath; /**< The working path where all input files are stored and where all output files will be saved */ fs::path
workingPath; /**< The working path where all input files are stored and where all output files will be saved */
string filesName; /**< The name of the preservation files to be considered */ string filesName; /**< The name of the preservation files to be considered */
bool brands; /**< True if tape presents brands on its surface */ bool brands; /**< True if tape presents brands on its surface */
float speed; /**< The speed at which the tape was read */ float speed; /**< The speed at which the tape was read */
Args(fs::path workingPath, string filesName, bool brands, float speed) { Args(fs::path workingPath, string filesName, bool brands, float speed) {
if (speed != 7.5 && speed != 15) throw invalid_argument("Speed must be 7.5 or 15");
this->workingPath = workingPath; this->workingPath = workingPath;
this->filesName = filesName; this->filesName = filesName;
this->brands = brands; this->brands = brands;
...@@ -174,14 +180,43 @@ static const string READING_HEAD_IMG = "input/readingHead.png"; ...@@ -174,14 +180,43 @@ static const string READING_HEAD_IMG = "input/readingHead.png";
static const string CAPSTAN_TEMPLATE_IMG = "input/capstanBERIO058prova.png"; static const string CAPSTAN_TEMPLATE_IMG = "input/capstanBERIO058prova.png";
static const string CONFIG_FILE = "config/config.json"; static const string CONFIG_FILE = "config/config.json";
/**
* @brief Get the next frame object
*
* Whenever we find an Irregularity, we want to skip a lenght equal to the
* Studer reading head (3 cm = 1.18 inches).
* Note the following considerations:
* - since we are analysing video at 25 fps a frame occurs every 40 ms
* - at 15 ips we cross 3 cm of tape in 79 ms (2 frames)
* - at 7.5 ips we cross 3 cm of tape in 157 ms (4 frames)
* The considered lengths are the widths of the tape areas.
* The following condition constitutes a valid approach if the tape areas
* have widths always equal to the reading head
*
* @param cap VideoCapture object
* @param speed tape reading speed
* @return Frame
*/
Frame get_next_frame(VideoCapture& cap, float speed, bool skip = false) {
if (skip) {
int ms_to_skip = speed == 15 ? 79 : 157;
cap.set(CAP_PROP_POS_MSEC, cap.get(CAP_PROP_POS_MSEC) + ms_to_skip);
}
Frame frame;
cap >> frame;
return frame;
}
double rotatedRectArea(RotatedRect rect) { return rect.size.width * rect.size.height; } double rotatedRectArea(RotatedRect rect) { return rect.size.width * rect.size.height; }
/** /**
* @fn std::tuple<int, int, double, double, vector<Vec4f>, vector<Vec4f>> * @fn std::tuple<int, int, double, double, vector<Vec4f>, vector<Vec4f>>
* findObject(Mat model, SceneObject object) * findObject(Mat model, SceneObject object)
* @brief Find the model in the scene using the Generalized Hough Transform. It * @brief Find the model in the scene using the Generalized Hough Transform.
* returns the best matches. Find the best matches for positive and negative * It returns the best matches. Find the best matches for positive and negative
* angles. If there are more than one shapes, then choose the one with the * angles. If there are more than one shape, then choose the one with the
* highest score. If there are more than one with the same highest score, then * highest score. If there are more than one with the same highest score, then
* arbitrarily choose the latest * arbitrarily choose the latest
* *
...@@ -309,9 +344,7 @@ bool findProcessingAreas(Mat myFrame, SceneObject tape, SceneObject capstan) { ...@@ -309,9 +344,7 @@ bool findProcessingAreas(Mat myFrame, SceneObject tape, SceneObject capstan) {
return false; return false;
} }
/*********************************************************************************************/ /************************************ TAPE AREA DETECTION ****************/
/************************************ TAPE AREA DETECTION
/*********************************************************************************************/
// Compute area basing on reading head detection // Compute area basing on reading head detection
Vec4f positionTape(rect.center.x, rect.center.y + rect.size.height / 2 + 20 * (rect.size.width / 200), 1, Vec4f positionTape(rect.center.x, rect.center.y + rect.size.height / 2 + 20 * (rect.size.width / 200), 1,
...@@ -319,13 +352,11 @@ bool findProcessingAreas(Mat myFrame, SceneObject tape, SceneObject capstan) { ...@@ -319,13 +352,11 @@ bool findProcessingAreas(Mat myFrame, SceneObject tape, SceneObject capstan) {
rectTape = utility::drawShapes(myFrame, positionTape, Scalar(0, 255 - indexPos * 64, 0), rect.size.width, rectTape = utility::drawShapes(myFrame, positionTape, Scalar(0, 255 - indexPos * 64, 0), rect.size.width,
50 * (rect.size.width / 200), 0, 0, 1); 50 * (rect.size.width / 200), 0, 0, 1);
/*********************************************************************************************/ /************************************* CAPSTAN DETECTION ******************/
/************************************* CAPSTAN DETECTION
/*********************************************************************************************/
// Read template image - it is smaller than before, therefore there is no // Read template image - it is smaller than before, therefore there is no
// need to downsample // need to downsample
Mat templateShape = imread(CAPSTAN_TEMPLATE_IMG, IMREAD_GRAYSCALE); Mat templateShape = cv::imread(CAPSTAN_TEMPLATE_IMG, IMREAD_GRAYSCALE);
if (useSURF) { if (useSURF) {
// Step 1: Detect the keypoints using SURF Detector, compute the // Step 1: Detect the keypoints using SURF Detector, compute the
...@@ -353,7 +384,7 @@ bool findProcessingAreas(Mat myFrame, SceneObject tape, SceneObject capstan) { ...@@ -353,7 +384,7 @@ bool findProcessingAreas(Mat myFrame, SceneObject tape, SceneObject capstan) {
} }
// Draw matches // Draw matches
Mat img_matches; Mat img_matches;
drawMatches(templateShape, keypoints_object, halved_gray_current_frame, keypoints_scene, good_matches, cv::drawMatches(templateShape, keypoints_object, halved_gray_current_frame, keypoints_scene, good_matches,
img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(), img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(),
DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
// Localize the object // Localize the object
...@@ -364,7 +395,7 @@ bool findProcessingAreas(Mat myFrame, SceneObject tape, SceneObject capstan) { ...@@ -364,7 +395,7 @@ bool findProcessingAreas(Mat myFrame, SceneObject tape, SceneObject capstan) {
obj.push_back(keypoints_object[good_matches[i].queryIdx].pt); obj.push_back(keypoints_object[good_matches[i].queryIdx].pt);
scene.push_back(keypoints_scene[good_matches[i].trainIdx].pt); scene.push_back(keypoints_scene[good_matches[i].trainIdx].pt);
} }
Mat H = findHomography(obj, scene, RANSAC); Mat H = cv::findHomography(obj, scene, RANSAC);
// Get the corners from the image_1 ( the object to be "detected" ) // Get the corners from the image_1 ( the object to be "detected" )
vector<Point2f> obj_corners(4); vector<Point2f> obj_corners(4);
obj_corners[0] = Point2f(0, 0); obj_corners[0] = Point2f(0, 0);
...@@ -372,7 +403,7 @@ bool findProcessingAreas(Mat myFrame, SceneObject tape, SceneObject capstan) { ...@@ -372,7 +403,7 @@ bool findProcessingAreas(Mat myFrame, SceneObject tape, SceneObject capstan) {
obj_corners[2] = Point2f((float)templateShape.cols, (float)templateShape.rows); obj_corners[2] = Point2f((float)templateShape.cols, (float)templateShape.rows);
obj_corners[3] = Point2f(0, (float)templateShape.rows); obj_corners[3] = Point2f(0, (float)templateShape.rows);
vector<Point2f> scene_corners(4); vector<Point2f> scene_corners(4);
perspectiveTransform(obj_corners, scene_corners, H); cv::perspectiveTransform(obj_corners, scene_corners, H);
// Find average // Find average
float capstanX = (scene_corners[0].x + scene_corners[1].x + scene_corners[2].x + scene_corners[3].x) / 4; float capstanX = (scene_corners[0].x + scene_corners[1].x + scene_corners[2].x + scene_corners[3].x) / 4;
...@@ -625,15 +656,18 @@ void processing(cv::VideoCapture videoCapture, SceneObject capstan, SceneObject ...@@ -625,15 +656,18 @@ void processing(cv::VideoCapture videoCapture, SceneObject capstan, SceneObject
int video_current_ms = videoCapture.get(CAP_PROP_POS_MSEC); int video_current_ms = videoCapture.get(CAP_PROP_POS_MSEC);
// counters // counters
int savedFrames = 0; int savedFrames = 0;
int unsavedFrames = 0;
float lastSaved = -160; float lastSaved = -160;
// Whenever we find an Irregularity, we want to skip a lenght equal to the /* Whenever we find an Irregularity, we want to skip a lenght equal to the
// Studer reading head (3 cm = 1.18 inches). * Studer reading head (3 cm = 1.18 inches).
int savingRate = 79; // [ms]. Time taken to cross 3 cm at 15 ips, or 1.5 cm at 7.5 ips. * Note the following considerations:
// The considered lengths are the widths of the tape areas. * - since we are analysing video at 25 fps a frame occurs every 40 ms
// The following condition constitutes a valid approach if the tape areas * - at 15 ips we cross 3 cm of tape in 79 ms (2 frames)
// have widths always equal to the reading head * - at 7.5 ips we cross 3 cm of tape in 157 ms (4 frames)
if (args.speed == 7.5) savingRate = 157; // Time taken to cross 3 cm at 7.5 ips * The considered lengths are the widths of the tape areas.
* The following condition constitutes a valid approach if the tape areas
* have widths always equal to the reading head
*/
int savingRate = args.speed == 7.5 ? 157 : 79; // [ms]
// The first frame of the video won't be processed // The first frame of the video won't be processed
cv::Mat prevFrame; cv::Mat prevFrame;
...@@ -641,6 +675,10 @@ void processing(cv::VideoCapture videoCapture, SceneObject capstan, SceneObject ...@@ -641,6 +675,10 @@ void processing(cv::VideoCapture videoCapture, SceneObject capstan, SceneObject
firstInstant = video_length_ms - video_current_ms; firstInstant = video_length_ms - video_current_ms;
while (videoCapture.isOpened()) { while (videoCapture.isOpened()) {
Frame currentFrame = get_next_frame(videoCapture, args.speed);
video_current_ms = videoCapture.get(CAP_PROP_POS_MSEC);
Frame frame; Frame frame;
videoCapture >> frame; videoCapture >> frame;
video_current_ms = videoCapture.get(CAP_PROP_POS_MSEC); video_current_ms = videoCapture.get(CAP_PROP_POS_MSEC);
...@@ -671,23 +709,11 @@ void processing(cv::VideoCapture videoCapture, SceneObject capstan, SceneObject ...@@ -671,23 +709,11 @@ void processing(cv::VideoCapture videoCapture, SceneObject capstan, SceneObject
// An Irregularity has been found! // An Irregularity has been found!
auto [odd_frame, even_frame] = frame.deinterlace(); auto [odd_frame, even_frame] = frame.deinterlace();
// Extract the image corresponding to the ROIs
Point2f pts[4];
savingPinchRoller ? rectCapstan.points(pts) : rectTape.points(pts);
Frame subImage(cv::Mat(frame, cv::Rect(100, min(pts[1].y, pts[2].y), frame.cols - 100,
static_cast<int>(rectTape.size.height))));
// the following comment was in the previous code, if some errors
// occur, add this correction in the deinterlace method If the found
// rectangle is of odd height, we must increase evenSubImage height
// by 1, otherwise we have segmentation_fault!!!
auto [oddSubImage, evenSubImage] = subImage.deinterlace();
string timeLabel = getTimeLabel(video_current_ms, ":"); string timeLabel = getTimeLabel(video_current_ms, ":");
string safeTimeLabel = getTimeLabel(video_current_ms, "-"); string safeTimeLabel = getTimeLabel(video_current_ms, "-");
string irregularityImageFilename = to_string(savedFrames) + "_" + safeTimeLabel + ".jpg"; string irregularityImageFilename = to_string(savedFrames) + "_" + safeTimeLabel + ".jpg";
cv::imwrite(irregularityImagesPath / irregularityImageFilename, odd_frame); cv::imwrite(irregularityImagesPath / irregularityImageFilename, odd_frame);
// Append Irregularity information to JSON // Append Irregularity information to JSON
Irregularity irreg = Irregularity(Source::Video, timeLabel); Irregularity irreg = Irregularity(Source::Video, timeLabel);
...@@ -697,10 +723,8 @@ void processing(cv::VideoCapture videoCapture, SceneObject capstan, SceneObject ...@@ -697,10 +723,8 @@ void processing(cv::VideoCapture videoCapture, SceneObject capstan, SceneObject
lastSaved = video_current_ms; lastSaved = video_current_ms;
savedFrames++; savedFrames++;
} else {
unsavedFrames++;
} }
prevFrame = frame; prevFrame = frame;
} }
} }
...@@ -725,12 +749,11 @@ void processing(cv::VideoCapture videoCapture, SceneObject capstan, SceneObject ...@@ -725,12 +749,11 @@ void processing(cv::VideoCapture videoCapture, SceneObject capstan, SceneObject
* @return int program status. * @return int program status.
*/ */
int main(int argc, char** argv) { int main(int argc, char** argv) {
Args args = argc > 1 ? Args::from_cli(argc, argv) : Args::from_file(CONFIG_FILE); const Args args = argc > 1 ? Args::from_cli(argc, argv) : Args::from_file(CONFIG_FILE);
SceneObject capstan = SceneObject::from_file(CONFIG_FILE, Object::CAPSTAN); SceneObject capstan = SceneObject::from_file(CONFIG_FILE, Object::CAPSTAN);
SceneObject tape = SceneObject::from_file(CONFIG_FILE, Object::TAPE); SceneObject tape = SceneObject::from_file(CONFIG_FILE, Object::TAPE);
json irregularityFileInput; json irregularityFileInput;
fs::path irregularityFileInputPath;
cv::Mat myFrame; cv::Mat myFrame;
const fs::path VIDEO_PATH = args.workingPath / "PreservationAudioVisualFile" / args.filesName; const fs::path VIDEO_PATH = args.workingPath / "PreservationAudioVisualFile" / args.filesName;
...@@ -741,7 +764,7 @@ int main(int argc, char** argv) { ...@@ -741,7 +764,7 @@ int main(int argc, char** argv) {
std::exit(EXIT_FAILURE); std::exit(EXIT_FAILURE);
} }
irregularityFileInputPath = args.workingPath / "temp" / fileName / "AudioAnalyser_IrregularityFileOutput1.json"; const fs::path irregularityFileInputPath = args.workingPath / "temp" / fileName / A_IRREG_FILE_1;
// Input JSON check // Input JSON check
ifstream iJSON(irregularityFileInputPath); ifstream iJSON(irregularityFileInputPath);
...@@ -750,24 +773,9 @@ int main(int argc, char** argv) { ...@@ -750,24 +773,9 @@ int main(int argc, char** argv) {
<< RED << irregularityFileInputPath.string() << " cannot be found or opened." << END << endl; << RED << irregularityFileInputPath.string() << " cannot be found or opened." << END << endl;
std::exit(EXIT_FAILURE); std::exit(EXIT_FAILURE);
} }
if (args.speed != 7.5 && args.speed != 15) {
cerr << RED << BOLD << "config.json error!" << END << endl // Read input JSON
<< RED << "Speed parameter must be 7.5 or 15 ips." << END << endl; iJSON >> irregularityFileInput;
std::exit(EXIT_FAILURE);
}
if (tape.threshold.percentual < 0 || tape.threshold.percentual > 100) {
cerr << RED << BOLD << "config.json error!" << END << endl
<< RED << "TapeThresholdPercentual parameter must be a percentage value." << END << endl;
std::exit(EXIT_FAILURE);
}
if (capstan.threshold.percentual < 0 || capstan.threshold.percentual > 100) {
cerr << RED << BOLD << "config.json error!" << END << endl
<< RED
<< "CapstanThresholdPercentual parameter must be a percentage "
"value."
<< END << endl;
std::exit(EXIT_FAILURE);
}
// Adjust input paramenters (considering given ones as pertinent to a speed reference = 7.5) // Adjust input paramenters (considering given ones as pertinent to a speed reference = 7.5)
if (args.brands) { if (args.brands) {
...@@ -785,23 +793,14 @@ int main(int argc, char** argv) { ...@@ -785,23 +793,14 @@ int main(int argc, char** argv) {
cout << " ThresholdPercentualCapstan: " << capstan.threshold.percentual << endl; cout << " ThresholdPercentualCapstan: " << capstan.threshold.percentual << endl;
cout << endl; cout << endl;
// Read input JSON
iJSON >> irregularityFileInput;
/*********************************************************************************************/
/*********************************** MAKE OUTPUT DIRECTORY
/*********************************************************************************************/
// Make directory with fileName name // Make directory with fileName name
outputPath = args.workingPath / "temp" / fileName; outputPath = args.workingPath / "temp" / fileName;
int outputFileNameDirectory = create_directory(outputPath); fs::create_directory(outputPath);
irregularityImagesPath = outputPath / "IrregularityImages"; irregularityImagesPath = outputPath / "IrregularityImages";
int fullFrameDirectory = fs::create_directory(irregularityImagesPath); fs::create_directory(irregularityImagesPath);
/*********************************************************************************************/ /************************************** AREAS DETECTION *********************************/
/************************************** AREAS DETECTION
/*********************************************************************************************/
cv::VideoCapture videoCapture(VIDEO_PATH); cv::VideoCapture videoCapture(VIDEO_PATH);
if (!videoCapture.isOpened()) { if (!videoCapture.isOpened()) {
...@@ -827,11 +826,9 @@ int main(int argc, char** argv) { ...@@ -827,11 +826,9 @@ int main(int argc, char** argv) {
std::exit(EXIT_FAILURE); std::exit(EXIT_FAILURE);
} }
/*********************************************************************************************/ /**************************************** PROCESSING **************************/
/**************************************** PROCESSING
/*********************************************************************************************/
pprint("\nProcessing...", CYAN); pprint("Processing...", CYAN);
// Processing timer // Processing timer
time_t startTimer, endTimer; time_t startTimer, endTimer;
...@@ -846,18 +843,14 @@ int main(int argc, char** argv) { ...@@ -846,18 +843,14 @@ int main(int argc, char** argv) {
string result("Processing elapsed time: " + to_string((int)min) + ":" + to_string((int)sec)); string result("Processing elapsed time: " + to_string((int)min) + ":" + to_string((int)sec));
cout << endl << result << endl; cout << endl << result << endl;
/*********************************************************************************************/ /************************************* IRREGULARITY FILES *****************************/
/************************************* IRREGULARITY FILES
/*********************************************************************************************/
fs::path outputFile1Name = outputPath / "VideoAnalyser_IrregularityFileOutput1.json"; files::saveFile(outputPath / V_IRREG_FILE_1, irregularityFileOutput1.dump(4), false);
files::saveFile(outputFile1Name, irregularityFileOutput1.dump(4), false);
// Irregularities to extract for the AudioAnalyser and to the TapeIrregularityClassifier // Irregularities to extract for the AudioAnalyser and to the TapeIrregularityClassifier
extractIrregularityImagesForAudio(outputPath, VIDEO_PATH, irregularityFileInput, irregularityFileOutput2); extractIrregularityImagesForAudio(outputPath, VIDEO_PATH, irregularityFileInput, irregularityFileOutput2);
fs::path outputFile2Name = outputPath / "VideoAnalyser_IrregularityFileOutput2.json"; files::saveFile(outputPath / V_IRREG_FILE_2, irregularityFileOutput2.dump(4), false);
files::saveFile(outputFile2Name, irregularityFileOutput2.dump(4), false);
return 0; return EXIT_SUCCESS;
} }
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
using namespace cv; using namespace cv;
using namespace std; using namespace std;
namespace fs = std::filesystem;
using json = nlohmann::json; using json = nlohmann::json;
...@@ -208,6 +209,15 @@ cv::Mat utility::difference(cv::Mat& prevFrame, cv::Mat& currentFrame) { ...@@ -208,6 +209,15 @@ cv::Mat utility::difference(cv::Mat& prevFrame, cv::Mat& currentFrame) {
return diff; return diff;
} }
Threshold::Threshold(float percentual, int angle, int scale, int pos) {
if (percentual < 0 || percentual > 100) throw std::invalid_argument("Percentual must be between 0 and 100");
this->percentual = percentual;
this->angle = angle;
this->scale = scale;
this->pos = pos;
}
SceneObject::SceneObject(int minDist, Threshold threshold) { SceneObject::SceneObject(int minDist, Threshold threshold) {
this->minDist = minDist; this->minDist = minDist;
this->threshold = threshold; this->threshold = threshold;
...@@ -220,9 +230,9 @@ SceneObject SceneObject::from_file(fs::path path, Object obj) { ...@@ -220,9 +230,9 @@ SceneObject SceneObject::from_file(fs::path path, Object obj) {
if (obj == Object::TAPE) { if (obj == Object::TAPE) {
return SceneObject(j["MinDist"], return SceneObject(j["MinDist"],
Threshold{j["TapeThresholdPercentual"], j["AngleThresh"], j["ScaleThresh"], j["PosThresh"]}); Threshold(j["TapeThresholdPercentual"], j["AngleThresh"], j["ScaleThresh"], j["PosThresh"]));
} else { } else {
return SceneObject(j["MinDistCapstan"], Threshold{j["CapstanThresholdPercentual"], j["AngleThreshCapstan"], return SceneObject(j["MinDistCapstan"], Threshold(j["CapstanThresholdPercentual"], j["AngleThreshCapstan"],
j["ScaleThreshCapstan"], j["PosThreshCapstan"]}); j["ScaleThreshCapstan"], j["PosThreshCapstan"]));
} }
} }
\ No newline at end of file
#include <filesystem>
#include <opencv2/core/core.hpp> #include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp> #include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgcodecs.hpp> #include <opencv2/imgcodecs.hpp>
...@@ -147,6 +148,13 @@ struct Threshold { ...@@ -147,6 +148,13 @@ struct Threshold {
int scale; /**< The scale votes threshold for the detection of the object */ int scale; /**< The scale votes threshold for the detection of the object */
int pos; /**< The position votes threshold for the detection of the object int pos; /**< The position votes threshold for the detection of the object
*/ */
Threshold(){};
/**
* @brief Construct a new Threshold object
* @throws std::invalid_argument if the percentual is not in the range [0, 1]
*/
Threshold(float percentual, int angle, int scale, int pos);
}; };
/** /**
...@@ -167,6 +175,7 @@ struct SceneObject { ...@@ -167,6 +175,7 @@ struct SceneObject {
objects for the detection of the reading head */ objects for the detection of the reading head */
Threshold threshold; /**< the threshold values used to detect the object */ Threshold threshold; /**< the threshold values used to detect the object */
SceneObject(){};
SceneObject(int minDist, Threshold threshold); SceneObject(int minDist, Threshold threshold);
~SceneObject() = default; ~SceneObject() = default;
/** /**
......
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