From 4c5c1c7024e4724d18057b71fd3dd6b5110d0cff Mon Sep 17 00:00:00 2001 From: Richard Broker Date: Wed, 26 Aug 2020 22:32:46 +0100 Subject: [PATCH 01/19] Issue #28, use more smart pointers (mostly in Client) --- AITracker/src/model.cpp | 52 ++++++++++-------------- AITracker/src/model.h | 18 ++++----- Client/src/Main.cpp | 10 ++--- Client/src/camera/CameraFactory.cpp | 11 +++--- Client/src/camera/CameraFactory.h | 4 +- Client/src/presenter/presenter.cpp | 57 +++++++++------------------ Client/src/presenter/presenter.h | 25 ++++++------ Client/src/tracker/ITrackerWrapper.h | 6 +-- Client/src/tracker/TrackerFactory.cpp | 19 ++++----- Client/src/tracker/TrackerFactory.h | 3 +- Client/src/tracker/TrackerWrapper.cpp | 7 ++-- Client/src/tracker/TrackerWrapper.h | 8 ++-- 12 files changed, 92 insertions(+), 128 deletions(-) diff --git a/AITracker/src/model.cpp b/AITracker/src/model.cpp index 7b0e6e7..07b8194 100644 --- a/AITracker/src/model.cpp +++ b/AITracker/src/model.cpp @@ -8,26 +8,23 @@ -Tracker::Tracker(PositionSolver* solver, std::wstring& detection_model_path, std::wstring& landmark_model_path): +Tracker::Tracker(std::unique_ptr&& solver, std::wstring& detection_model_path, std::wstring& landmark_model_path): improc() { - - this->solver = solver; - - - session_options = new Ort::SessionOptions(); - session_options->SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED); - session_options->SetInterOpNumThreads(1); - session_options->SetInterOpNumThreads(1); - allocator = new Ort::AllocatorWithDefaultOptions(); - memory_info = (Ort::MemoryInfo*)allocator->GetInfo(); - enviro = new Ort::Env(ORT_LOGGING_LEVEL_WARNING, "env"); - - enviro->DisableTelemetryEvents(); + this->solver = std::move(solver); + + auto session_options = Ort::SessionOptions(); + session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED); + session_options.SetInterOpNumThreads(1); + session_options.SetInterOpNumThreads(1); + allocator = std::make_unique(); - session = new Ort::Session(*enviro, detection_model_path.data(), *session_options); - session_lm = new Ort::Session(*enviro, landmark_model_path.data(), *session_options); + enviro = std::make_unique(ORT_LOGGING_LEVEL_WARNING, "env"); + enviro->DisableTelemetryEvents(); + + session = std::make_unique(*enviro, detection_model_path.data(), session_options); + session_lm = std::make_unique(*enviro, landmark_model_path.data(), session_options); tensor_input_size = tensor_input_dims[1] * tensor_input_dims[2] * tensor_input_dims[3]; @@ -37,16 +34,7 @@ Tracker::Tracker(PositionSolver* solver, std::wstring& detection_model_path, std landmarks_output_node_names = {"output"}; } -Tracker::~Tracker() -{ - delete this->session_options; - delete this->enviro; - delete this->session; - delete this->session_lm; - delete this->solver; -} - -void Tracker::predict(cv::Mat& image, FaceData& face_data, IFilter* filter) +void Tracker::predict(cv::Mat& image, FaceData& face_data, const std::unique_ptr& filter) { cv::Mat img_copy = image.clone(); img_copy.convertTo(img_copy, CV_32F); @@ -95,7 +83,7 @@ void Tracker::detect_face(const cv::Mat& image, FaceData& face_data) improc.normalize(resized); improc.transpose((float*)resized.data, buffer_data); - Ort::Value input_tensor = Ort::Value::CreateTensor(*memory_info, buffer_data, tensor_input_size, tensor_input_dims, 4); + Ort::Value input_tensor = Ort::Value::CreateTensor(allocator->GetInfo(), buffer_data, tensor_input_size, tensor_input_dims, 4); auto output_tensors = session->Run(Ort::RunOptions{ nullptr }, @@ -107,7 +95,7 @@ void Tracker::detect_face(const cv::Mat& image, FaceData& face_data) cv::Mat out(4, tensor_detection_output_dims, CV_32F, output_arr); cv::Mat maxpool(4, tensor_detection_output_dims, CV_32F, maxpool_arr); - + cv::Mat first(56, 56, CV_32F, out.ptr(0,0)); cv::Mat second(56, 56, CV_32F, out.ptr(0,1)); @@ -123,7 +111,7 @@ void Tracker::detect_face(const cv::Mat& image, FaceData& face_data) face_data.face_detected = c > .6 ? true : false; - + if (face_data.face_detected) { float face[] = { x - r, y - r, 2 * r, 2 * r }; @@ -144,7 +132,7 @@ void Tracker::detect_face(const cv::Mat& image, FaceData& face_data) face_data.face_coords[2] = face[2]; face_data.face_coords[3] = face[3]; } - + } @@ -156,10 +144,10 @@ void Tracker::detect_landmarks(const cv::Mat& image, int x0, int y0, float scale improc.normalize(resized); improc.transpose((float*)resized.data, buffer_data); - Ort::Value input_tensor = Ort::Value::CreateTensor(*memory_info, buffer_data, tensor_input_size, tensor_input_dims, 4); + Ort::Value input_tensor = Ort::Value::CreateTensor(allocator->GetInfo(), buffer_data, tensor_input_size, tensor_input_dims, 4); - auto output_tensors = session_lm->Run(Ort::RunOptions{ nullptr }, + auto output_tensors = session_lm->Run(Ort::RunOptions{ nullptr }, landmarks_input_node_names.data(), &input_tensor, 1, landmarks_output_node_names.data(), 1); float* output_arr = output_tensors[0].GetTensorMutableData(); diff --git a/AITracker/src/model.h b/AITracker/src/model.h index f193ce9..8081180 100644 --- a/AITracker/src/model.h +++ b/AITracker/src/model.h @@ -11,22 +11,20 @@ class Tracker { public: - PositionSolver* solver; + std::unique_ptr solver; - Tracker(PositionSolver* solver, std::wstring& detection_model_path, std::wstring& landmark_model_path); - ~Tracker(); - void predict(cv::Mat& image, FaceData& face_data, IFilter *filter=nullptr); + Tracker(std::unique_ptr&& solver, std::wstring& detection_model_path, std::wstring& landmark_model_path); + + void predict(cv::Mat& image, FaceData& face_data, const std::unique_ptr& filter = {}); private: ImageProcessor improc; std::string detection_model_path; - Ort::Env* enviro; - Ort::SessionOptions* session_options; - Ort::Session* session; - Ort::Session* session_lm; - Ort::AllocatorWithDefaultOptions* allocator; - Ort::MemoryInfo* memory_info; + std::unique_ptr enviro; + std::unique_ptr session; + std::unique_ptr session_lm; + std::unique_ptr allocator; std::vector detection_input_node_names; std::vector detection_output_node_names; diff --git a/Client/src/Main.cpp b/Client/src/Main.cpp index b864c5a..893cbd0 100644 --- a/Client/src/Main.cpp +++ b/Client/src/Main.cpp @@ -13,7 +13,7 @@ int main(int argc, char *argv[]) { - + SetEnvironmentVariable(LPWSTR("OMP_NUM_THREADS"), LPWSTR("1")); omp_set_num_threads(1); // Disable ONNX paralelization so we dont steal all cpu cores. omp_set_dynamic(0); @@ -27,10 +27,10 @@ int main(int argc, char *argv[]) WindowMain w; w.show(); - ConfigMgr conf_mgr("./prefs.ini"); - TrackerFactory t_factory("./models/"); - - Presenter p((IView&)w, &t_factory, (ConfigMgr*)&conf_mgr); + auto conf_mgr = std::make_unique("./prefs.ini"); + auto t_factory = std::make_unique("./models/"); + + Presenter p((IView&)w, std::move(t_factory), std::move(conf_mgr)); return app.exec(); } diff --git a/Client/src/camera/CameraFactory.cpp b/Client/src/camera/CameraFactory.cpp index cad3cf4..3287383 100644 --- a/Client/src/camera/CameraFactory.cpp +++ b/Client/src/camera/CameraFactory.cpp @@ -4,15 +4,15 @@ #include "OCVCamera.h" #include "NullCamera.h" -Camera* CameraFactory::buildCamera(int width, int height, int exposure, int gain) +std::unique_ptr CameraFactory::buildCamera(int width, int height, int exposure, int gain) { - Camera *camera = NULL; + std::unique_ptr camera; bool error = false; bool has_ps3 = true; try { - camera = new Ps3Camera(640, 480, 30); + camera = std::make_unique(640, 480, 30); } catch (std::exception) { has_ps3 = false; @@ -21,7 +21,7 @@ Camera* CameraFactory::buildCamera(int width, int height, int exposure, int gain if (!has_ps3) { try { - camera = new OCVCamera(width, height); + camera = std::make_unique(width, height); } catch (std::exception) { @@ -31,8 +31,7 @@ Camera* CameraFactory::buildCamera(int width, int height, int exposure, int gain if (error) { - delete camera; - camera = new NullCamera; + camera = std::make_unique(); } CameraSettings cam_settings; diff --git a/Client/src/camera/CameraFactory.h b/Client/src/camera/CameraFactory.h index 3dd0dbe..84f4163 100644 --- a/Client/src/camera/CameraFactory.h +++ b/Client/src/camera/CameraFactory.h @@ -1,10 +1,12 @@ #pragma once +#include + #include "Camera.h" class CameraFactory { public: - Camera* buildCamera(int width, int height, int exposure=-1, int gain=-1); + std::unique_ptr buildCamera(int width, int height, int exposure=-1, int gain=-1); }; diff --git a/Client/src/presenter/presenter.cpp b/Client/src/presenter/presenter.cpp index 1ea8877..f931ea2 100644 --- a/Client/src/presenter/presenter.cpp +++ b/Client/src/presenter/presenter.cpp @@ -1,25 +1,24 @@ -#include "presenter.h" +#include #include + +#include "presenter.h" #include "opencv.hpp" #include "../model/IPResolver.h" #include "../camera/CameraFactory.h" -Presenter::Presenter(IView& view, TrackerFactory* t_factory, ConfigMgr* conf_mgr) +Presenter::Presenter(IView& view, std::unique_ptr&& t_factory, std::unique_ptr&& conf_mgr) { - this->conf_mgr = conf_mgr; - state = conf_mgr->getConfig(); + this->tracker_factory = std::move(t_factory); + this->conf_mgr = std::move(conf_mgr); + state = this->conf_mgr->getConfig(); this->view = &view; this->view->connect_presenter(this); this->paint = state.show_video_feed; - this->filter = nullptr; - - this->tracker_factory = t_factory; - // Init available model names to show in the GUI this->tracker_factory->get_model_names(state.model_names); @@ -57,24 +56,14 @@ Presenter::Presenter(IView& view, TrackerFactory* t_factory, ConfigMgr* conf_mgr sync_ui_inputs(); } -Presenter::~Presenter() -{ - delete this->udp_sender; - delete this->camera; - delete this->t; - delete this->filter; -} - - void Presenter::init_sender(std::string &ip, int port) { // Updata only if needed. - if (this->udp_sender != NULL) + if (this->udp_sender) + { if (ip != this->udp_sender->ip && port != this->udp_sender->port) return; - - if (this->udp_sender != NULL) - delete(this->udp_sender); + } std::string ip_str = ip; int port_dest = port; @@ -86,7 +75,7 @@ void Presenter::init_sender(std::string &ip, int port) state.ip = ip; state.port = port; - this->udp_sender = new UDPSender(ip_str.data(), port_dest); + this->udp_sender = std::make_unique(ip_str.data(), port_dest); } void Presenter::init_tracker(int type) @@ -99,9 +88,6 @@ void Presenter::init_tracker(int type) #ifdef _DEBUG std::cout << "Resetting old tracker" << std::endl; #endif - - delete t; - this->t = tracker_factory->buildTracker(camera->width, camera->height, state.prior_distance, @@ -128,7 +114,7 @@ void Presenter::run_loop() FaceData d = FaceData(); int video_frame_buff_size = camera->width * camera->height * 3; - uint8_t *video_tex_pixels = new uint8_t[video_frame_buff_size]; + auto video_tex_pixels = std::make_unique(video_frame_buff_size); cv::Scalar color_blue(255, 0, 0); @@ -141,8 +127,8 @@ void Presenter::run_loop() while(run) { - camera->get_frame(video_tex_pixels); - cv::Mat mat(camera->height, camera->width, CV_8UC3, video_tex_pixels); + camera->get_frame(video_tex_pixels.get()); + cv::Mat mat(camera->height, camera->width, CV_8UC3, video_tex_pixels.get()); t->predict(mat, d, this->filter); @@ -160,7 +146,7 @@ void Presenter::run_loop() cv::Point p2(d.face_coords[2], d.face_coords[3]); cv::rectangle(mat, p1, p2, color_blue, 1); } - + update_tracking_data(d); send_data(buffer_data); } @@ -175,7 +161,7 @@ void Presenter::run_loop() } camera->stop_camera(); - delete[] video_tex_pixels; + video_tex_pixels; } @@ -196,16 +182,11 @@ void Presenter::update_stabilizer(const ConfigData& data) this->state.use_landmark_stab = data.use_landmark_stab; if (!state.use_landmark_stab) { - if (this->filter != nullptr) - { - delete this->filter; - this->filter = nullptr; - } + this->filter.reset(); } else { - if (this->filter == nullptr) - this->filter = new EAFilter(66 * 2); + this->filter = std::make_unique(66 * 2); } } @@ -253,7 +234,7 @@ void Presenter::save_prefs(const ConfigData& data) int port = data.port; init_sender(ip_str, port); - // Rebuild tracker if needed. This also will take care of updating the + // Rebuild tracker if needed. This also will take care of updating the // state/distance parameter init_tracker(data.selected_model); diff --git a/Client/src/presenter/presenter.h b/Client/src/presenter/presenter.h index e6f23d4..f35247e 100644 --- a/Client/src/presenter/presenter.h +++ b/Client/src/presenter/presenter.h @@ -17,16 +17,16 @@ class Presenter : IPresenter { private: FaceData face_data; - UDPSender *udp_sender = NULL; - TrackerFactory *tracker_factory = NULL; - ITrackerWrapper *t = NULL; - Camera *camera = NULL; + std::unique_ptr udp_sender; + std::unique_ptr tracker_factory; + std::unique_ptr t; + std::unique_ptr camera; // Current program's state + config. ConfigData state; - + // Filter which will be aplied to the tracking. - IFilter *filter; + std::unique_ptr filter; IView* view; @@ -34,7 +34,7 @@ class Presenter : IPresenter bool run = false; // Whether the main recognition loop has to paint the recognized landmarks bool paint = true; - + /** * Gets the current configuration state and sets the GUI to match it. */ @@ -49,12 +49,12 @@ class Presenter : IPresenter /** * Uses the tracker factory to build a new tracker. If the requested one is of the - * same type as the old one, the call will be ignored. + * same type as the old one, the call will be ignored. * This method updates the application state. * @param type Type ID of the desired model (Fast, medium, heavy) */ void init_tracker(int type); - + /** * Uses the internal UDP sender to send the facedata to opentrack. */ @@ -78,12 +78,11 @@ class Presenter : IPresenter * Updates the stabilizer applied to the recognized facial landmarks. */ void update_stabilizer(const ConfigData &data); - + public: - ConfigMgr* conf_mgr; + std::unique_ptr conf_mgr; - Presenter(IView& view, TrackerFactory* t_factory, ConfigMgr* conf_mgr); - ~Presenter(); + Presenter(IView& view, std::unique_ptr&& t_factory, std::unique_ptr&& conf_mgr); //IPresenter void toggle_tracking(); diff --git a/Client/src/tracker/ITrackerWrapper.h b/Client/src/tracker/ITrackerWrapper.h index 1119b7b..2a2c8d0 100644 --- a/Client/src/tracker/ITrackerWrapper.h +++ b/Client/src/tracker/ITrackerWrapper.h @@ -6,10 +6,10 @@ /** -* Possible model types. +* Possible model types. * TRACKER_FAST = Less weights. Lighter, but could have less precission * TRACKER_MED = Half the way. Could offer a good tradeoff. -* TRACKER_FULL = The heaviest. Could perform the best but also eats more CPU. +* TRACKER_FULL = The heaviest. Could perform the best but also eats more CPU. */ enum class TRACKER_TYPE { @@ -29,7 +29,7 @@ class ITrackerWrapper * @param face_data Where the results of the recognition will be stored * @param filter Optional filter/operation which will be executed (if != nullptr) on the extracted facial landmarks. */ - virtual void predict(cv::Mat& image, FaceData& face_data, IFilter* filter)=0; + virtual void predict(cv::Mat& image, FaceData& face_data, const std::unique_ptr& filter) = 0; virtual void update_distance_param(float new_distance) = 0; virtual TRACKER_TYPE get_type()=0; }; diff --git a/Client/src/tracker/TrackerFactory.cpp b/Client/src/tracker/TrackerFactory.cpp index 41fc7b3..ce9db22 100644 --- a/Client/src/tracker/TrackerFactory.cpp +++ b/Client/src/tracker/TrackerFactory.cpp @@ -6,7 +6,7 @@ #include "TrackerWrapper.h" -ITrackerWrapper* TrackerFactory::buildTracker(int im_width, int im_height, float distance, TRACKER_TYPE type) +std::unique_ptr TrackerFactory::buildTracker(int im_width, int im_height, float distance, TRACKER_TYPE type) { std::string landmark_path = model_dir; std::string detect_path = model_dir + "detection.onnx"; @@ -26,18 +26,18 @@ ITrackerWrapper* TrackerFactory::buildTracker(int im_width, int im_height, float landmark_path += "lm_m.onnx"; break; } - + std::wstring detect_wstr = std::wstring_convert>().from_bytes(detect_path); std::wstring landmark_wstr = std::wstring_convert>().from_bytes(landmark_path); - PositionSolver* solver = new PositionSolver(im_width, im_height, 0, 0, distance); + auto solver = std::make_unique(im_width, im_height, 0, 0, distance); - Tracker* t = nullptr; + std::unique_ptr t; try { - t = new Tracker( - solver, + t = std::make_unique( + std::move(solver), detect_wstr, landmark_wstr ); @@ -47,13 +47,10 @@ ITrackerWrapper* TrackerFactory::buildTracker(int im_width, int im_height, float #ifdef _DEBUG std::cout << "PROBLEM BUILDING TRACKER \n" << e.what() << std::endl; #endif - delete solver; - t = nullptr; + t.reset(); } - TrackerWrapper* wrapped = new TrackerWrapper(t, type); - - return (ITrackerWrapper*)wrapped; + return std::make_unique(std::move(t), type); } diff --git a/Client/src/tracker/TrackerFactory.h b/Client/src/tracker/TrackerFactory.h index 510f48a..cbbaaea 100644 --- a/Client/src/tracker/TrackerFactory.h +++ b/Client/src/tracker/TrackerFactory.h @@ -2,6 +2,7 @@ #include "ITrackerWrapper.h" #include +#include #include @@ -14,7 +15,7 @@ class TrackerFactory std::string model_dir; public: TrackerFactory(std::string modeldir); - ITrackerWrapper* buildTracker(int im_width, int im_height, float distance, TRACKER_TYPE type= TRACKER_TYPE::TRACKER_FAST); + std::unique_ptr buildTracker(int im_width, int im_height, float distance, TRACKER_TYPE type= TRACKER_TYPE::TRACKER_FAST); /** * Set the list with the string identifiers of the available models. diff --git a/Client/src/tracker/TrackerWrapper.cpp b/Client/src/tracker/TrackerWrapper.cpp index cb053bf..70782fc 100644 --- a/Client/src/tracker/TrackerWrapper.cpp +++ b/Client/src/tracker/TrackerWrapper.cpp @@ -1,18 +1,17 @@ #include "TrackerWrapper.h" -TrackerWrapper::TrackerWrapper(Tracker* model, TRACKER_TYPE type) +TrackerWrapper::TrackerWrapper(std::unique_ptr&& model, TRACKER_TYPE type) { - this->model = model; + this->model = std::move(model); this->type = type; } TrackerWrapper::~TrackerWrapper() { - delete this->model; } -void TrackerWrapper::predict(cv::Mat& image, FaceData& face_data, IFilter* filter) +void TrackerWrapper::predict(cv::Mat& image, FaceData& face_data, const std::unique_ptr& filter) { model->predict(image, face_data, filter); } diff --git a/Client/src/tracker/TrackerWrapper.h b/Client/src/tracker/TrackerWrapper.h index 8779284..5ded067 100644 --- a/Client/src/tracker/TrackerWrapper.h +++ b/Client/src/tracker/TrackerWrapper.h @@ -5,18 +5,18 @@ // Just to decouple the model library from the application. -class TrackerWrapper:ITrackerWrapper +class TrackerWrapper : public ITrackerWrapper { private: TRACKER_TYPE type; - Tracker* model; + std::unique_ptr model; public: - TrackerWrapper(Tracker* model, TRACKER_TYPE type); + TrackerWrapper(std::unique_ptr&& model, TRACKER_TYPE type); ~TrackerWrapper() override; // Inherited via ITrackerWrapper - virtual void predict(cv::Mat& image, FaceData& face_data, IFilter* filter) override; + virtual void predict(cv::Mat& image, FaceData& face_data, const std::unique_ptr& filter = {}) override; void update_distance_param(float new_distance) override; virtual TRACKER_TYPE get_type() override; }; From bacea1a75e35c6935254b0ecbd6c3bba2f30c5fc Mon Sep 17 00:00:00 2001 From: Richard Broker Date: Wed, 26 Aug 2020 22:37:22 +0100 Subject: [PATCH 02/19] fix tabs/spaces issue --- AITracker/src/model.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AITracker/src/model.cpp b/AITracker/src/model.cpp index 07b8194..52829ad 100644 --- a/AITracker/src/model.cpp +++ b/AITracker/src/model.cpp @@ -14,7 +14,7 @@ Tracker::Tracker(std::unique_ptr&& solver, std::wstring& detecti this->solver = std::move(solver); - auto session_options = Ort::SessionOptions(); + auto session_options = Ort::SessionOptions(); session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED); session_options.SetInterOpNumThreads(1); session_options.SetInterOpNumThreads(1); @@ -23,7 +23,7 @@ Tracker::Tracker(std::unique_ptr&& solver, std::wstring& detecti enviro = std::make_unique(ORT_LOGGING_LEVEL_WARNING, "env"); enviro->DisableTelemetryEvents(); - session = std::make_unique(*enviro, detection_model_path.data(), session_options); + session = std::make_unique(*enviro, detection_model_path.data(), session_options); session_lm = std::make_unique(*enviro, landmark_model_path.data(), session_options); tensor_input_size = tensor_input_dims[1] * tensor_input_dims[2] * tensor_input_dims[3]; From 61519281f566866b92e2f7e61f0fa20114bc4fd8 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Thu, 27 Aug 2020 17:22:48 +0200 Subject: [PATCH 03/19] Flip X and Y axes in order to no configure them in Opentrack. --- Client/src/presenter/presenter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Client/src/presenter/presenter.cpp b/Client/src/presenter/presenter.cpp index 1ea8877..dd1174f 100644 --- a/Client/src/presenter/presenter.cpp +++ b/Client/src/presenter/presenter.cpp @@ -181,8 +181,8 @@ void Presenter::run_loop() void Presenter::update_tracking_data(FaceData& facedata) { - this->state.x = facedata.translation[0] * 10; - this->state.y = facedata.translation[1] * 10; + this->state.x = facedata.translation[1] * 10; + this->state.y = facedata.translation[0] * 10; this->state.z = facedata.translation[2] * 10; this->state.yaw = facedata.rotation[1]; // Yaw this->state.pitch = facedata.rotation[0]; //Pitch From 2a2955fecd708198c6efa7bf7f5404fe92df42ed Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Thu, 27 Aug 2020 18:05:29 +0200 Subject: [PATCH 04/19] Explicitly initialize the facial landmark coords to 0. --- AITracker/src/data.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/AITracker/src/data.cpp b/AITracker/src/data.cpp index 6bbb842..b92f58d 100644 --- a/AITracker/src/data.cpp +++ b/AITracker/src/data.cpp @@ -1,6 +1,7 @@ #include "data.h" -FaceData::FaceData() +FaceData::FaceData(): + landmark_coords{0} { rotation = new double[3]{ 0,0,0 }; translation = new double[3]{ 0,0,0 }; @@ -22,15 +23,6 @@ std::string FaceData::to_string() std::to_string(this->translation[1]) + ", Z: " + std::to_string(this->translation[2]) ; - - /*datastring += - std::string("\n\Crop coords: ") + - std::to_string(this->face_coords[0]) + ", " + - std::to_string(this->face_coords[1]) + ", " + - std::to_string(this->face_coords[2]) + ", " + - std::to_string(this->face_coords[3]); - */ - return datastring; } From 92f9ec21c668520784fb52f6ee85c8bd7fb03767 Mon Sep 17 00:00:00 2001 From: Richard Broker Date: Thu, 27 Aug 2020 17:27:39 +0100 Subject: [PATCH 05/19] Address review comments --- AITracker/src/model.cpp | 22 ++++++++++------------ AITracker/src/model.h | 3 ++- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/AITracker/src/model.cpp b/AITracker/src/model.cpp index 52829ad..c6c0cae 100644 --- a/AITracker/src/model.cpp +++ b/AITracker/src/model.cpp @@ -9,29 +9,27 @@ Tracker::Tracker(std::unique_ptr&& solver, std::wstring& detection_model_path, std::wstring& landmark_model_path): - improc() + improc(), + memory_info(allocator.GetInfo()), + enviro(std::make_unique(ORT_LOGGING_LEVEL_WARNING, "env")), + detection_input_node_names{ "input" }, + detection_output_node_names{ "output", "maxpool" }, + landmarks_input_node_names{ "input" }, + landmarks_output_node_names{ "output" } { this->solver = std::move(solver); - auto session_options = Ort::SessionOptions(); session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED); session_options.SetInterOpNumThreads(1); - session_options.SetInterOpNumThreads(1); - allocator = std::make_unique(); + session_options.SetIntraOpNumThreads(1); - enviro = std::make_unique(ORT_LOGGING_LEVEL_WARNING, "env"); enviro->DisableTelemetryEvents(); session = std::make_unique(*enviro, detection_model_path.data(), session_options); session_lm = std::make_unique(*enviro, landmark_model_path.data(), session_options); tensor_input_size = tensor_input_dims[1] * tensor_input_dims[2] * tensor_input_dims[3]; - - detection_input_node_names = {"input"}; - detection_output_node_names = {"output", "maxpool"}; - landmarks_input_node_names = {"input"}; - landmarks_output_node_names = {"output"}; } void Tracker::predict(cv::Mat& image, FaceData& face_data, const std::unique_ptr& filter) @@ -83,7 +81,7 @@ void Tracker::detect_face(const cv::Mat& image, FaceData& face_data) improc.normalize(resized); improc.transpose((float*)resized.data, buffer_data); - Ort::Value input_tensor = Ort::Value::CreateTensor(allocator->GetInfo(), buffer_data, tensor_input_size, tensor_input_dims, 4); + Ort::Value input_tensor = Ort::Value::CreateTensor(memory_info, buffer_data, tensor_input_size, tensor_input_dims, 4); auto output_tensors = session->Run(Ort::RunOptions{ nullptr }, @@ -144,7 +142,7 @@ void Tracker::detect_landmarks(const cv::Mat& image, int x0, int y0, float scale improc.normalize(resized); improc.transpose((float*)resized.data, buffer_data); - Ort::Value input_tensor = Ort::Value::CreateTensor(allocator->GetInfo(), buffer_data, tensor_input_size, tensor_input_dims, 4); + Ort::Value input_tensor = Ort::Value::CreateTensor(memory_info, buffer_data, tensor_input_size, tensor_input_dims, 4); auto output_tensors = session_lm->Run(Ort::RunOptions{ nullptr }, diff --git a/AITracker/src/model.h b/AITracker/src/model.h index 8081180..320d200 100644 --- a/AITracker/src/model.h +++ b/AITracker/src/model.h @@ -19,12 +19,13 @@ class Tracker private: ImageProcessor improc; + Ort::AllocatorWithDefaultOptions allocator = {}; + const OrtMemoryInfo* memory_info; std::string detection_model_path; std::unique_ptr enviro; std::unique_ptr session; std::unique_ptr session_lm; - std::unique_ptr allocator; std::vector detection_input_node_names; std::vector detection_output_node_names; From 303545956ff34be9671370f7cd5c266b874e1617 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Thu, 27 Aug 2020 22:31:45 +0200 Subject: [PATCH 06/19] Started to add a new window which will contain the programs configuration. --- Client/Client.vcxproj | 9 +- Client/Client.vcxproj.filters | 14 +++ Client/src/view/ConfigWindow.cpp | 16 +++ Client/src/view/ConfigWindow.h | 19 +++ Client/src/view/ConfigWindow.ui | 207 +++++++++++++++++++++++++++++++ Client/src/view/MainWindow.ui | 12 +- Client/src/view/WindowMain.cpp | 16 ++- Client/src/view/WindowMain.h | 8 +- Client/src/view/i_view.h | 7 ++ Client/src/view/qml.qrc | 1 + 10 files changed, 292 insertions(+), 17 deletions(-) create mode 100644 Client/src/view/ConfigWindow.cpp create mode 100644 Client/src/view/ConfigWindow.h create mode 100644 Client/src/view/ConfigWindow.ui diff --git a/Client/Client.vcxproj b/Client/Client.vcxproj index c3e157d..317d470 100644 --- a/Client/Client.vcxproj +++ b/Client/Client.vcxproj @@ -72,7 +72,7 @@ - $(Qt_INCLUDEPATH_);$(SolutionDir)Dependencies\libusb\include\libusb-1.0;$(SolutionDir)Dependencies\OpenCV\include\;$(SolutionDir)Dependencies\onnxruntime\include\;$(SolutionDir)AITracker\src\;$(ProjectDir)Include;$(QTDIR)\include;$(QTDIR)\include\QtUiTools;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtQuick;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtQml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;$(Platform)\$(Configuration)\uic;$(Platform)\$(Configuration)\moc;%(AdditionalIncludeDirectories) + $(Qt_INCLUDEPATH_);$(SolutionDir)Dependencies\libusb\include\libusb-1.0;$(SolutionDir)Dependencies\OpenCV\include\;$(SolutionDir)Dependencies\onnxruntime\include\;$(SolutionDir)AITracker\src\;$(ProjectDir)Include;$(QTDIR)\include;$(QTDIR)\include\QtUiTools;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtQuick;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtQml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;$(Platform)\$(Configuration)\uic;$(Platform)\$(Configuration)\moc;.\;%(AdditionalIncludeDirectories) $(Qt_LIBPATH_);$(SolutionDir)Dependencies\libusb\MS64\static;$(SolutionDir)Dependencies\OpenCV\lib;$(SolutionDir)Dependencies\onnxruntime\lib\;%(AdditionalLibraryDirectories) @@ -86,7 +86,7 @@ - $(Qt_INCLUDEPATH_);$(ProjectDir)Dependencies\OpenCV\include\;$(SolutionDir)Dependencies\libusb\include\libusb-1.0;$(SolutionDir)Dependencies\OpenCV\include\;$(SolutionDir)Dependencies\onnxruntime\include\;$(SolutionDir)AITracker\src\;$(ProjectDir)Include;%(AdditionalIncludeDirectories) + $(Qt_INCLUDEPATH_);$(ProjectDir)Dependencies\OpenCV\include\;$(SolutionDir)Dependencies\libusb\include\libusb-1.0;$(SolutionDir)Dependencies\OpenCV\include\;$(SolutionDir)Dependencies\onnxruntime\include\;$(SolutionDir)AITracker\src\;$(ProjectDir)Include;.\;%(AdditionalIncludeDirectories) $(Qt_LIBPATH_);C:\Users\Alvaro\source\repos\Camera\Dependencies\libusb\MS64\static;C:\Users\Alvaro\source\repos\Camera\Dependencies\OpenCV\lib;$(SolutionDir)Dependencies\onnxruntime\lib\;%(AdditionalLibraryDirectories) @@ -105,7 +105,7 @@ $(Qt_LIBS_);opencv_world430d.lib;onnxruntime.lib;Ws2_32.lib;legacy_stdio_definitions.lib;libusb-1.0.lib;%(AdditionalDependencies) - $(Qt_INCLUDEPATH_);$(SolutionDir)Dependencies\libusb\include\libusb-1.0;$(SolutionDir)Dependencies\OpenCV\include\;$(SolutionDir)Dependencies\onnxruntime\include\;$(SolutionDir)PS3Driver\include\;$(SolutionDir)AITracker\src\;$(ProjectDir)Include;$(QTDIR)\include;$(QTDIR)\include\QtUiTools;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtQuick;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtQml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;$(Platform)\$(Configuration)\uic;$(Platform)\$(Configuration)\moc;%(AdditionalIncludeDirectories) + $(Qt_INCLUDEPATH_);$(SolutionDir)Dependencies\libusb\include\libusb-1.0;$(SolutionDir)Dependencies\OpenCV\include\;$(SolutionDir)Dependencies\onnxruntime\include\;$(SolutionDir)PS3Driver\include\;$(SolutionDir)AITracker\src\;$(ProjectDir)Include;$(QTDIR)\include;$(QTDIR)\include\QtUiTools;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtQuick;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtQml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;$(Platform)\$(Configuration)\uic;$(Platform)\$(Configuration)\moc;.\;%(AdditionalIncludeDirectories) true @@ -183,6 +183,7 @@ + @@ -193,6 +194,7 @@ + @@ -210,6 +212,7 @@ + diff --git a/Client/Client.vcxproj.filters b/Client/Client.vcxproj.filters index a320f84..6ebae61 100644 --- a/Client/Client.vcxproj.filters +++ b/Client/Client.vcxproj.filters @@ -28,6 +28,9 @@ Source Files + + Source Files + @@ -70,6 +73,9 @@ + + Header Files + @@ -79,6 +85,9 @@ + + Form Files + @@ -96,6 +105,11 @@ qrc;* false + + {99349809-55BA-4b9d-BF79-8FDBB0286EB3} + ui + true + diff --git a/Client/src/view/ConfigWindow.cpp b/Client/src/view/ConfigWindow.cpp new file mode 100644 index 0000000..7cefcf3 --- /dev/null +++ b/Client/src/view/ConfigWindow.cpp @@ -0,0 +1,16 @@ +#include "ConfigWindow.h" + +ConfigWindow::ConfigWindow(QWidget *parent) + : QWidget(parent) +{ + ui.setupUi(this); +} + +ConfigWindow::~ConfigWindow() +{ +} + +void register_observer(QWidget* parent) +{ + +} \ No newline at end of file diff --git a/Client/src/view/ConfigWindow.h b/Client/src/view/ConfigWindow.h new file mode 100644 index 0000000..9a2510f --- /dev/null +++ b/Client/src/view/ConfigWindow.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include "ui_ConfigWindow.h" + +#include "i_view.h" + +class ConfigWindow : public QWidget +{ + Q_OBJECT + +public: + ConfigWindow(QWidget *parent = Q_NULLPTR); + ~ConfigWindow(); + void subscribe(IObserver observer); + +private: + Ui::ConfigWindow ui; +}; diff --git a/Client/src/view/ConfigWindow.ui b/Client/src/view/ConfigWindow.ui new file mode 100644 index 0000000..4f84bd0 --- /dev/null +++ b/Client/src/view/ConfigWindow.ui @@ -0,0 +1,207 @@ + + + Configuration + + + Qt::WindowModal + + + + 0 + 0 + 237 + 336 + + + + ConfigWindow + + + + + 10 + 20 + 191 + 231 + + + + Camera + + + + + 20 + 160 + 131 + 20 + + + + 1 + + + 64 + + + Qt::Horizontal + + + false + + + false + + + QSlider::TicksAbove + + + + + + 20 + 140 + 47 + 13 + + + + Gain + + + + + + 20 + 180 + 47 + 13 + + + + Exposure + + + + + + 20 + 200 + 131 + 20 + + + + 254 + + + 144 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + + + + 20 + 20 + 131 + 111 + + + + + + + Width + + + + + + + 640 + + + 3000 + + + 640 + + + + + + + Height + + + + + + + FPS + + + + + + + 480 + + + 3000 + + + 480 + + + + + + + 15 + + + 120 + + + 30 + + + + + + + Input ID + + + + + + + + + + + + + 20 + 280 + 171 + 31 + + + + Apply + + + + + + + diff --git a/Client/src/view/MainWindow.ui b/Client/src/view/MainWindow.ui index 2676e68..fd390df 100644 --- a/Client/src/view/MainWindow.ui +++ b/Client/src/view/MainWindow.ui @@ -7,7 +7,7 @@ 0 0 420 - 583 + 590 @@ -439,15 +439,9 @@ - + - <html><head/><body><p align="center"><span style=" font-size:7pt; color:#6b6b6b;">X: Y: Z: Pitch: Yaw: Roll:</span></p></body></html> - - - Qt::RichText - - - Qt::AlignCenter + 🔧 Configuration⚙️ diff --git a/Client/src/view/WindowMain.cpp b/Client/src/view/WindowMain.cpp index 927435a..ff968cb 100644 --- a/Client/src/view/WindowMain.cpp +++ b/Client/src/view/WindowMain.cpp @@ -4,24 +4,28 @@ #include #include + WindowMain::WindowMain(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); this->layout()->setSizeConstraint(QLayout::SetFixedSize); + this->conf_win = new ConfigWindow(); + this->conf_win->show(); + this->presenter = NULL; + btn_track = findChild("trackBtn"); tracking_frame = findChild("cameraView"); - tracking_info = findChild("trackerInfoLbl"); - tracking_info->setHidden(true); gp_box_prefs = findChild("prefsGroupbox"); gp_box_address = gp_box_prefs->findChild("sendGroupbox"); gp_box_priors = gp_box_prefs->findChild("paramsGroupBox"); btn_save = gp_box_prefs->findChild("saveBtn"); + btn_config = findChild("btnConfig"); cb_modelType = gp_box_priors->findChild("modeltypeSelect"); check_video_preview = findChild("chkVideoPreview"); @@ -29,6 +33,7 @@ WindowMain::WindowMain(QWidget *parent) connect(btn_track, SIGNAL(released()), this, SLOT(onTrackClick())); connect(btn_save, SIGNAL(released()), this, SLOT(onSaveClick())); + connect(btn_config, SIGNAL(released()), this, SLOT(onSaveClick())); connect(check_video_preview, SIGNAL(released()), this, SLOT(onSaveClick())); statusBar()->setSizeGripEnabled(false); @@ -108,7 +113,7 @@ void WindowMain::set_tracking_mode(bool is_tracking) void WindowMain::update_view_state(ConfigData conf) { set_inputs(conf); - show_tracking_data(conf); + //show_tracking_data(conf); if (!conf.show_video_feed) { @@ -182,6 +187,11 @@ void WindowMain::onSaveClick() presenter->save_prefs(config); } +void WindowMain::onConfigClick() +{ + +} + void WindowMain::readjust_size() { findChild("centralwidget")->adjustSize(); diff --git a/Client/src/view/WindowMain.h b/Client/src/view/WindowMain.h index 09b05ab..4ea009e 100644 --- a/Client/src/view/WindowMain.h +++ b/Client/src/view/WindowMain.h @@ -11,10 +11,12 @@ #include "ui_MainWindow.h" +#include "ConfigWindow.h" + class Presenter; -class WindowMain : public QMainWindow, IView +class WindowMain : public QMainWindow, IView, IObserver { Q_OBJECT @@ -38,12 +40,13 @@ class WindowMain : public QMainWindow, IView private: Ui::MainWindow ui; - QPushButton *btn_track, *btn_save; + QPushButton *btn_track, *btn_save, *btn_config; QLabel *tracking_frame, *tracking_info; QGroupBox *gp_box_prefs, *gp_box_address, *gp_box_priors; QCheckBox *check_video_preview, *check_stabilization_landmarks; QComboBox* cb_modelType; + ConfigWindow *conf_win; /** * Compacting the window to the content. */ @@ -58,4 +61,5 @@ class WindowMain : public QMainWindow, IView private slots: void onTrackClick(); void onSaveClick(); + void onConfigClick(); }; diff --git a/Client/src/view/i_view.h b/Client/src/view/i_view.h index f28618e..106ccf4 100644 --- a/Client/src/view/i_view.h +++ b/Client/src/view/i_view.h @@ -54,4 +54,11 @@ class IView { * For showing dialogs or alerts to the user. */ virtual void show_message(const char* msg, MSG_SEVERITY severity) = 0; +}; + + +class IObserver +{ +public: + virtual void notify() = 0; }; \ No newline at end of file diff --git a/Client/src/view/qml.qrc b/Client/src/view/qml.qrc index 06ffe6c..e9989e1 100644 --- a/Client/src/view/qml.qrc +++ b/Client/src/view/qml.qrc @@ -1,5 +1,6 @@ MainWindow.ui + ConfigWindow.ui From 1568630f52c487728f1fdc9310595cb18cd54d88 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Fri, 28 Aug 2020 09:10:44 +0200 Subject: [PATCH 07/19] Connected configwindow + WindowMain. --- Client/Client.vcxproj | 8 ++-- Client/Client.vcxproj.filters | 14 ++++--- Client/src/view/ConfigWindow.cpp | 72 ++++++++++++++++++++++++++++++-- Client/src/view/ConfigWindow.h | 37 ++++++++++++++-- Client/src/view/ConfigWindow.ui | 6 +-- Client/src/view/WindowMain.cpp | 37 +++++++++++++--- Client/src/view/WindowMain.h | 5 ++- Client/src/view/i_view.h | 9 +++- 8 files changed, 159 insertions(+), 29 deletions(-) diff --git a/Client/Client.vcxproj b/Client/Client.vcxproj index 317d470..0be4f4a 100644 --- a/Client/Client.vcxproj +++ b/Client/Client.vcxproj @@ -193,10 +193,6 @@ - - - - @@ -232,6 +228,10 @@ + + + + diff --git a/Client/Client.vcxproj.filters b/Client/Client.vcxproj.filters index 6ebae61..3d5e4f6 100644 --- a/Client/Client.vcxproj.filters +++ b/Client/Client.vcxproj.filters @@ -83,12 +83,6 @@ Resource Files - - - - Form Files - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} @@ -118,4 +112,12 @@ + + + Form Files + + + Form Files + + \ No newline at end of file diff --git a/Client/src/view/ConfigWindow.cpp b/Client/src/view/ConfigWindow.cpp index 7cefcf3..48a0aea 100644 --- a/Client/src/view/ConfigWindow.cpp +++ b/Client/src/view/ConfigWindow.cpp @@ -1,16 +1,80 @@ #include "ConfigWindow.h" -ConfigWindow::ConfigWindow(QWidget *parent) +ConfigWindow::ConfigWindow(IRootView *prev_window, QWidget *parent) : QWidget(parent) { ui.setupUi(this); + + + this->parentView = prev_window; + + // References to UI objects + gp_box_camera_prefs = findChild("gbCamera"); + + btn_apply = findChild("applyBtn"); + + input_camera = gp_box_camera_prefs->findChild("cameraIdSelector"); + width_selector = gp_box_camera_prefs->findChild("imgWidthSelector"); + height_selector = gp_box_camera_prefs->findChild("imgHeightSelector"); + fps_selector = gp_box_camera_prefs->findChild("fpsSelector"); + gain_slider = gp_box_camera_prefs->findChild("sliderGain"); + exposure_slider = gp_box_camera_prefs->findChild("sliderExposure"); + + + connect(btn_apply, SIGNAL(released()), this, SLOT(onApplyClick())); } ConfigWindow::~ConfigWindow() +{} + + +void ConfigWindow::onApplyClick() { + parentView->notify((IView*)this); +} + + +void ConfigWindow::connect_presenter(IPresenter* presenter) { } + +void ConfigWindow::paint_video_frame(cv::Mat& img) { } + +void ConfigWindow::show_tracking_data(ConfigData conf) { } + +void ConfigWindow::set_tracking_mode(bool is_tracking) { + set_enabled(!is_tracking); } -void register_observer(QWidget* parent) +ConfigData ConfigWindow::get_inputs() { - -} \ No newline at end of file + ConfigData conf = ConfigData(); + conf.cam_gain = gain_slider->value(); + conf.cam_exposure = exposure_slider->value(); + conf.video_fps = fps_selector->value(); + conf.video_width = width_selector->value(); + conf.video_height = height_selector->value(); + //TODO: Add cameras + + return conf; +} + +void ConfigWindow::update_view_state(ConfigData conf) +{ + gain_slider->setValue(conf.cam_gain); + exposure_slider->setValue(conf.cam_exposure); + fps_selector->setValue(conf.video_fps); + width_selector->setValue(conf.video_width); + height_selector->setValue(conf.video_height); + + //TODO: Add available cameras to input_camera + input_camera->addItem("0", QVariant('0')); + input_camera->addItem("1", QVariant('1')); + +} + +void ConfigWindow::set_enabled(bool enabled) +{ + gp_box_camera_prefs->setEnabled(enabled); + btn_apply->setEnabled(enabled); +} + +void ConfigWindow::show_message(const char* msg, MSG_SEVERITY severity){} \ No newline at end of file diff --git a/Client/src/view/ConfigWindow.h b/Client/src/view/ConfigWindow.h index 9a2510f..21d046b 100644 --- a/Client/src/view/ConfigWindow.h +++ b/Client/src/view/ConfigWindow.h @@ -1,19 +1,48 @@ #pragma once -#include #include "ui_ConfigWindow.h" +#include +#include +/*#include +#include +#include */ + + #include "i_view.h" -class ConfigWindow : public QWidget + +class ConfigWindow : public QWidget, IView { Q_OBJECT public: - ConfigWindow(QWidget *parent = Q_NULLPTR); + ConfigWindow(IRootView *prev_window, QWidget *parent = Q_NULLPTR); ~ConfigWindow(); - void subscribe(IObserver observer); + + // Inherited via IView + virtual void connect_presenter(IPresenter* presenter) override; + virtual void paint_video_frame(cv::Mat& img) override; + virtual void show_tracking_data(ConfigData conf) override; + virtual void set_tracking_mode(bool is_tracking) override; + virtual ConfigData get_inputs() override; + virtual void update_view_state(ConfigData conf) override; + virtual void set_enabled(bool enabled) override; + virtual void show_message(const char* msg, MSG_SEVERITY severity) override; private: Ui::ConfigWindow ui; + + IRootView *parentView; + + QPushButton *btn_apply; + QComboBox *input_camera; + + QGroupBox *gp_box_camera_prefs; + + QSpinBox *width_selector, *height_selector, *fps_selector; + QSlider *gain_slider, *exposure_slider; + +private slots: + void onApplyClick(); }; diff --git a/Client/src/view/ConfigWindow.ui b/Client/src/view/ConfigWindow.ui index 4f84bd0..ba78922 100644 --- a/Client/src/view/ConfigWindow.ui +++ b/Client/src/view/ConfigWindow.ui @@ -1,7 +1,7 @@ - Configuration - + ConfigWindow + Qt::WindowModal @@ -182,7 +182,7 @@ - + diff --git a/Client/src/view/WindowMain.cpp b/Client/src/view/WindowMain.cpp index ff968cb..51386c5 100644 --- a/Client/src/view/WindowMain.cpp +++ b/Client/src/view/WindowMain.cpp @@ -11,8 +11,8 @@ WindowMain::WindowMain(QWidget *parent) ui.setupUi(this); this->layout()->setSizeConstraint(QLayout::SetFixedSize); - this->conf_win = new ConfigWindow(); - this->conf_win->show(); + this->conf_win = new ConfigWindow(this); + this->conf_win->hide(); this->presenter = NULL; @@ -33,7 +33,7 @@ WindowMain::WindowMain(QWidget *parent) connect(btn_track, SIGNAL(released()), this, SLOT(onTrackClick())); connect(btn_save, SIGNAL(released()), this, SLOT(onSaveClick())); - connect(btn_config, SIGNAL(released()), this, SLOT(onSaveClick())); + connect(btn_config, SIGNAL(released()), this, SLOT(onConfigClick())); connect(check_video_preview, SIGNAL(released()), this, SLOT(onSaveClick())); statusBar()->setSizeGripEnabled(false); @@ -105,6 +105,8 @@ void WindowMain::set_tracking_mode(bool is_tracking) tracking_frame->setPixmap(QPixmap()); tracking_frame->setText("No video input"); } + + conf_win->set_tracking_mode(is_tracking); } @@ -153,6 +155,8 @@ void WindowMain::set_inputs(const ConfigData data) cb_modelType->addItem(QString(s.data())); cb_modelType->setCurrentIndex(data.selected_model); check_stabilization_landmarks->setChecked(data.use_landmark_stab); + + this->conf_win->update_view_state(data); } void WindowMain::show_message(const char* msg, MSG_SEVERITY severity) @@ -174,6 +178,8 @@ void WindowMain::show_message(const char* msg, MSG_SEVERITY severity) void WindowMain::set_enabled(bool enabled) { btn_track->setEnabled(enabled); + + conf_win->set_enabled(enabled); } void WindowMain::onTrackClick() @@ -183,17 +189,38 @@ void WindowMain::onTrackClick() void WindowMain::onSaveClick() { + // Obtain inputs of children windows + ConfigData conf_child = conf_win->get_inputs(); + + // Merge with config from this window ConfigData config = get_inputs(); - presenter->save_prefs(config); + + conf_child.ip = config.ip; + conf_child.port = config.port; + conf_child.prior_distance = config.prior_distance; + conf_child.show_video_feed = config.show_video_feed; + conf_child.selected_model = config.selected_model; + conf_child.use_landmark_stab = config.use_landmark_stab; + + presenter->save_prefs(conf_child); + + std::cout << "Saved changes" << std::endl; } void WindowMain::onConfigClick() { - + this->conf_win->show(); + std::cout << "Config" << std::endl; } void WindowMain::readjust_size() { findChild("centralwidget")->adjustSize(); adjustSize(); +} + + +void WindowMain::notify(IView* self) +{ + this->onSaveClick(); } \ No newline at end of file diff --git a/Client/src/view/WindowMain.h b/Client/src/view/WindowMain.h index 4ea009e..5c614b8 100644 --- a/Client/src/view/WindowMain.h +++ b/Client/src/view/WindowMain.h @@ -16,7 +16,7 @@ class Presenter; -class WindowMain : public QMainWindow, IView, IObserver +class WindowMain : public QMainWindow, IView, IRootView { Q_OBJECT @@ -37,6 +37,9 @@ class WindowMain : public QMainWindow, IView, IObserver void set_enabled(bool enabled); void show_message(const char* msg, MSG_SEVERITY severity); + //IRootView + void notify(IView *self); + private: Ui::MainWindow ui; diff --git a/Client/src/view/i_view.h b/Client/src/view/i_view.h index 106ccf4..d361de3 100644 --- a/Client/src/view/i_view.h +++ b/Client/src/view/i_view.h @@ -57,8 +57,13 @@ class IView { }; -class IObserver + +/** +* Must be implemented by the Main View (or any root view) so its children can comunicate back on input fields +* changed. +*/ +class IRootView { public: - virtual void notify() = 0; + virtual void notify(IView *self) = 0; }; \ No newline at end of file From 513efe8ebc70b390f3e8caf8fd30ff9ac2882894 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Fri, 28 Aug 2020 19:18:09 +0200 Subject: [PATCH 08/19] Now, instead of building a camera in the presenter, we build a list with all the available ones. --- Client/src/Main.cpp | 1 + Client/src/camera/CameraFactory.cpp | 31 ++++++++++++++-- Client/src/camera/CameraFactory.h | 4 ++- Client/src/camera/CameraSettings.cpp | 6 ++++ Client/src/camera/CameraSettings.h | 3 ++ Client/src/camera/OCVCamera.cpp | 10 +++--- Client/src/camera/OCVCamera.h | 3 +- Client/src/model/Config.cpp | 4 +++ Client/src/model/Config.h | 2 ++ Client/src/presenter/presenter.cpp | 54 ++++++++++++++++++---------- Client/src/presenter/presenter.h | 3 +- Client/src/view/ConfigWindow.cpp | 14 +++----- 12 files changed, 96 insertions(+), 39 deletions(-) diff --git a/Client/src/Main.cpp b/Client/src/Main.cpp index 893cbd0..7d4bb49 100644 --- a/Client/src/Main.cpp +++ b/Client/src/Main.cpp @@ -11,6 +11,7 @@ #include "tracker/TrackerFactory.h" + int main(int argc, char *argv[]) { diff --git a/Client/src/camera/CameraFactory.cpp b/Client/src/camera/CameraFactory.cpp index 3287383..3e762bb 100644 --- a/Client/src/camera/CameraFactory.cpp +++ b/Client/src/camera/CameraFactory.cpp @@ -4,7 +4,7 @@ #include "OCVCamera.h" #include "NullCamera.h" -std::unique_ptr CameraFactory::buildCamera(int width, int height, int exposure, int gain) +std::unique_ptr CameraFactory::buildCamera(int width, int height, int cam_index, int exposure, int gain) { std::unique_ptr camera; bool error = false; @@ -21,7 +21,7 @@ std::unique_ptr CameraFactory::buildCamera(int width, int height, int ex if (!has_ps3) { try { - camera = std::make_unique(width, height); + camera = std::make_unique(width, height,60, cam_index); } catch (std::exception) { @@ -40,4 +40,29 @@ std::unique_ptr CameraFactory::buildCamera(int width, int height, int ex camera->set_settings(cam_settings); return camera; -} \ No newline at end of file +} + + +std::vector> CameraFactory::getCameras() +{ + std::vector> cams; + + cams.clear(); + + for (int i = 0; i < 10; i++) + { + try + { + //c = &OCVCamera(640, 480, 30, i); + std::shared_ptr c = std::make_shared(640, 480, 30, i); + cams.push_back(std::move(c)); + std::cout << "Found ID: " << i << std::endl; + } + catch (const std::exception&) + { + std::cout << "Not found device" << i << std::endl; + } + } + + return cams; +} diff --git a/Client/src/camera/CameraFactory.h b/Client/src/camera/CameraFactory.h index 84f4163..8e6f18c 100644 --- a/Client/src/camera/CameraFactory.h +++ b/Client/src/camera/CameraFactory.h @@ -1,12 +1,14 @@ #pragma once #include +#include #include "Camera.h" class CameraFactory { public: - std::unique_ptr buildCamera(int width, int height, int exposure=-1, int gain=-1); + std::unique_ptr buildCamera(int width, int height, int cam_index = 0, int exposure=-1, int gain=-1); + std::vector> getCameras(); }; diff --git a/Client/src/camera/CameraSettings.cpp b/Client/src/camera/CameraSettings.cpp index ffc5a20..afa15d9 100644 --- a/Client/src/camera/CameraSettings.cpp +++ b/Client/src/camera/CameraSettings.cpp @@ -5,12 +5,18 @@ CameraSettings::CameraSettings() { exposure = -1; gain = -1; + width = 640; + height = 480; + fps = 30; } CameraSettings::CameraSettings(CameraSettings& settings) { exposure = settings.exposure; gain = settings.gain; + fps = settings.fps; + width = settings.width; + height = settings.width; } CameraSettings::~CameraSettings() diff --git a/Client/src/camera/CameraSettings.h b/Client/src/camera/CameraSettings.h index 3f79f21..6f91341 100644 --- a/Client/src/camera/CameraSettings.h +++ b/Client/src/camera/CameraSettings.h @@ -4,6 +4,9 @@ struct CameraSettings { int exposure; int gain; + int fps; + int width; + int height; CameraSettings(); CameraSettings(CameraSettings& settings); diff --git a/Client/src/camera/OCVCamera.cpp b/Client/src/camera/OCVCamera.cpp index e0a76db..e22eae0 100644 --- a/Client/src/camera/OCVCamera.cpp +++ b/Client/src/camera/OCVCamera.cpp @@ -1,10 +1,11 @@ #include "OCVCamera.h" -OCVCamera::OCVCamera(int width, int height, int fps) : +OCVCamera::OCVCamera(int width, int height, int fps, int index) : Camera(width, height, fps), size(0, 0), - cap() + cap(), + cam_index(index) { CV_BACKEND = cv::CAP_DSHOW; if (!is_camera_available()) @@ -28,7 +29,7 @@ bool OCVCamera::is_camera_available() { bool available = false; - cap.open(0, CV_BACKEND); + cap.open(cam_index, CV_BACKEND); available = cap.isOpened(); if (available) { @@ -40,7 +41,7 @@ bool OCVCamera::is_camera_available() void OCVCamera::start_camera() { - cap.open(0, CV_BACKEND); + cap.open(cam_index, CV_BACKEND); if (!cap.isOpened()) { throw std::runtime_error("No compatible camera found."); @@ -58,7 +59,6 @@ void OCVCamera::get_frame(uint8_t* buffer) cap.read(frame); //Scale maintaining aspect ratio. If distorted, the model will get confused. //TODO: Maybe cropping (width,height) section from the center is better. - //cv::resize(frame, frame, size, w_scale, w_scale); cv::resize(frame, frame, size, w_scale, w_scale); cv::flip(frame, frame, 1); for (int i = 0; i < frame.cols * frame.rows * 3; i++) diff --git a/Client/src/camera/OCVCamera.h b/Client/src/camera/OCVCamera.h index c374d09..a1adbf1 100644 --- a/Client/src/camera/OCVCamera.h +++ b/Client/src/camera/OCVCamera.h @@ -9,12 +9,13 @@ class OCVCamera : public Camera cv::Size size; float w_scale; int cam_native_width; + int cam_index; int CV_BACKEND; bool is_camera_available(); public: - OCVCamera(int width = 640, int height = 480, int fps = 30); + OCVCamera(int width = 640, int height = 480, int fps = 30, int index = 0); ~OCVCamera(); void start_camera(); void stop_camera(); diff --git a/Client/src/model/Config.cpp b/Client/src/model/Config.cpp index 94dbe2f..a9b1cd3 100644 --- a/Client/src/model/Config.cpp +++ b/Client/src/model/Config.cpp @@ -14,6 +14,8 @@ ConfigData ConfigData::getGenericConfig() conf.prior_distance = .6; conf.show_video_feed = true; conf.selected_model = 0; + conf.selected_camera = 0; + conf.num_cameras_detected = 0; conf.video_width = 640; conf.video_height = 480; conf.video_fps = 30; @@ -52,6 +54,7 @@ void ConfigMgr::updateConfig(const ConfigData& data) conf.setValue("fps", data.video_fps); conf.setValue("cam_exposure", data.cam_exposure); conf.setValue("cam_gain", data.cam_gain); + conf.setValue("selected_camera", data.selected_camera); } ConfigData ConfigMgr::getConfig() @@ -65,6 +68,7 @@ ConfigData ConfigMgr::getConfig() c.show_video_feed = conf.value("video_feed", true).toBool(); c.use_landmark_stab = conf.value("stabilize_landmarks", true).toBool(); c.selected_model = conf.value("model", 0).toInt(); + c.selected_camera = conf.value("selected_camera", 0).toInt(); c.video_width = conf.value("video_width", 640).toInt(); c.video_height = conf.value("video_height", 480).toInt(); c.video_fps = conf.value("fps", 30).toInt(); diff --git a/Client/src/model/Config.h b/Client/src/model/Config.h index d92cd79..21f3a73 100644 --- a/Client/src/model/Config.h +++ b/Client/src/model/Config.h @@ -21,6 +21,8 @@ struct ConfigData float x, y, z, yaw, pitch, roll; + int selected_camera; + int num_cameras_detected; int cam_exposure; int cam_gain; diff --git a/Client/src/presenter/presenter.cpp b/Client/src/presenter/presenter.cpp index 820264b..6b074f8 100644 --- a/Client/src/presenter/presenter.cpp +++ b/Client/src/presenter/presenter.cpp @@ -27,9 +27,13 @@ Presenter::Presenter(IView& view, std::unique_ptr&& t_factory, s CameraFactory camfactory; - camera = camfactory.buildCamera(state.video_width, state.video_height, state.cam_exposure, state.cam_gain); - if (!camera->is_valid) + all_cameras = camfactory.getCameras(); + + ///camera = camfactory.buildCamera(state.video_width, state.selected_camera, state.video_height, state.cam_exposure, state.cam_gain); + + //if (!camera->is_valid) + if (all_cameras.size() == 0) { std::cout << "[ERROR] NO CAMERAS AVAILABLE" << std::endl; this->view->set_enabled(false); @@ -37,6 +41,11 @@ Presenter::Presenter(IView& view, std::unique_ptr&& t_factory, s } else { + // Choose the camera index we want + //camera = std::move(all_cameras[state.selected_camera]); + //Change the number of available cameras + state.num_cameras_detected = (int)all_cameras.size(); + // Request sockets (UDP Sender) only if needed. std::string ip_str = state.ip; int port = state.port; @@ -81,6 +90,7 @@ void Presenter::init_sender(std::string &ip, int port) void Presenter::init_tracker(int type) { TRACKER_TYPE newtype = tracker_factory->get_type(type); + if (t != nullptr) { if (newtype != t->get_type()) @@ -88,21 +98,23 @@ void Presenter::init_tracker(int type) #ifdef _DEBUG std::cout << "Resetting old tracker" << std::endl; #endif - this->t = tracker_factory->buildTracker(camera->width, - camera->height, - state.prior_distance, - tracker_factory->get_type(type)); + this->t = tracker_factory-> + buildTracker(all_cameras[state.selected_camera]->width, + all_cameras[state.selected_camera]->height, + (float)state.prior_distance, + tracker_factory->get_type(type) + ); } else { - this->t->update_distance_param(this->state.prior_distance); + this->t->update_distance_param((float)(this->state.prior_distance)); } } else { - this->t = tracker_factory->buildTracker(camera->width, - camera->height, - state.prior_distance, + this->t = tracker_factory->buildTracker(all_cameras[state.selected_camera]->width, + all_cameras[state.selected_camera]->height, + (float)state.prior_distance, tracker_factory->get_type(type)); } state.selected_model = type; @@ -113,7 +125,9 @@ void Presenter::run_loop() { FaceData d = FaceData(); - int video_frame_buff_size = camera->width * camera->height * 3; + auto cam = all_cameras[state.selected_camera]; + + int video_frame_buff_size = cam->width * cam->height * 3; auto video_tex_pixels = std::make_unique(video_frame_buff_size); @@ -122,13 +136,13 @@ void Presenter::run_loop() double buffer_data[6]; - camera->start_camera(); + cam->start_camera(); while(run) { - camera->get_frame(video_tex_pixels.get()); - cv::Mat mat(camera->height, camera->width, CV_8UC3, video_tex_pixels.get()); + cam->get_frame(video_tex_pixels.get()); + cv::Mat mat(cam->height, cam->width, CV_8UC3, video_tex_pixels.get()); t->predict(mat, d, this->filter); @@ -160,8 +174,7 @@ void Presenter::run_loop() cv::waitKey(1000/state.video_fps); } - camera->stop_camera(); - video_tex_pixels; + cam->stop_camera(); } @@ -234,6 +247,8 @@ void Presenter::save_prefs(const ConfigData& data) int port = data.port; init_sender(ip_str, port); + this->state.selected_camera = data.selected_camera; + // Rebuild tracker if needed. This also will take care of updating the // state/distance parameter init_tracker(data.selected_model); @@ -253,7 +268,8 @@ void Presenter::close_program() { //Assure we stop tracking loop. run = false; - // Assure the camera is released (some cameras have a "recording LED" which can be annoying to have on) - camera->stop_camera(); - // The remaining resources will be released on destructor. + // Assure all cameras are released (some cameras have a "recording LED" which can be annoying to have on) + + for(std::shared_ptr cam : all_cameras) + cam->stop_camera(); } \ No newline at end of file diff --git a/Client/src/presenter/presenter.h b/Client/src/presenter/presenter.h index f35247e..7df5509 100644 --- a/Client/src/presenter/presenter.h +++ b/Client/src/presenter/presenter.h @@ -20,7 +20,8 @@ class Presenter : IPresenter std::unique_ptr udp_sender; std::unique_ptr tracker_factory; std::unique_ptr t; - std::unique_ptr camera; + //std::unique_ptr camera; + std::vector> all_cameras; // Current program's state + config. ConfigData state; diff --git a/Client/src/view/ConfigWindow.cpp b/Client/src/view/ConfigWindow.cpp index 48a0aea..ce58624 100644 --- a/Client/src/view/ConfigWindow.cpp +++ b/Client/src/view/ConfigWindow.cpp @@ -5,7 +5,6 @@ ConfigWindow::ConfigWindow(IRootView *prev_window, QWidget *parent) { ui.setupUi(this); - this->parentView = prev_window; // References to UI objects @@ -20,7 +19,6 @@ ConfigWindow::ConfigWindow(IRootView *prev_window, QWidget *parent) gain_slider = gp_box_camera_prefs->findChild("sliderGain"); exposure_slider = gp_box_camera_prefs->findChild("sliderExposure"); - connect(btn_apply, SIGNAL(released()), this, SLOT(onApplyClick())); } @@ -52,8 +50,7 @@ ConfigData ConfigWindow::get_inputs() conf.video_fps = fps_selector->value(); conf.video_width = width_selector->value(); conf.video_height = height_selector->value(); - //TODO: Add cameras - + conf.selected_camera = input_camera->currentIndex(); return conf; } @@ -64,11 +61,10 @@ void ConfigWindow::update_view_state(ConfigData conf) fps_selector->setValue(conf.video_fps); width_selector->setValue(conf.video_width); height_selector->setValue(conf.video_height); - - //TODO: Add available cameras to input_camera - input_camera->addItem("0", QVariant('0')); - input_camera->addItem("1", QVariant('1')); - + input_camera->clear(); + for (int i = 0; i < conf.num_cameras_detected; i++) + input_camera->addItem(QString("Camera %1").arg(i), i); + input_camera->setCurrentIndex(conf.selected_camera); } void ConfigWindow::set_enabled(bool enabled) From a73d01fae869f139fa6278480acc2c0244d19df3 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Fri, 28 Aug 2020 21:26:07 +0200 Subject: [PATCH 09/19] Update camera parameters --- Client/src/camera/CameraFactory.cpp | 21 ++++++++-------- Client/src/camera/CameraFactory.h | 3 ++- Client/src/camera/OCVCamera.cpp | 2 +- Client/src/presenter/presenter.cpp | 39 ++++++++++++++++++++++------- Client/src/presenter/presenter.h | 12 +++++++++ Client/src/view/ConfigWindow.cpp | 1 + Client/src/view/WindowMain.cpp | 1 - 7 files changed, 57 insertions(+), 22 deletions(-) diff --git a/Client/src/camera/CameraFactory.cpp b/Client/src/camera/CameraFactory.cpp index 3e762bb..4ca6412 100644 --- a/Client/src/camera/CameraFactory.cpp +++ b/Client/src/camera/CameraFactory.cpp @@ -12,7 +12,7 @@ std::unique_ptr CameraFactory::buildCamera(int width, int height, int ca try { - camera = std::make_unique(640, 480, 30); + camera = std::make_unique(640, 480, 60); } catch (std::exception) { has_ps3 = false; @@ -34,26 +34,27 @@ std::unique_ptr CameraFactory::buildCamera(int width, int height, int ca camera = std::make_unique(); } - CameraSettings cam_settings; - cam_settings.exposure = exposure; - cam_settings.gain = gain; - camera->set_settings(cam_settings); - return camera; } -std::vector> CameraFactory::getCameras() +std::vector> CameraFactory::getCameras(CameraSettings& settings) { std::vector> cams; - cams.clear(); + // Search first for any PS3 camera. + try + { + cams.push_back(std::make_shared(640, 480, 60)); + cams[0]->set_settings(settings); + } + catch (std::exception){} + - for (int i = 0; i < 10; i++) + for (int i = 0; i < 5; i++) { try { - //c = &OCVCamera(640, 480, 30, i); std::shared_ptr c = std::make_shared(640, 480, 30, i); cams.push_back(std::move(c)); std::cout << "Found ID: " << i << std::endl; diff --git a/Client/src/camera/CameraFactory.h b/Client/src/camera/CameraFactory.h index 8e6f18c..9547098 100644 --- a/Client/src/camera/CameraFactory.h +++ b/Client/src/camera/CameraFactory.h @@ -4,11 +4,12 @@ #include #include "Camera.h" +#include "CameraSettings.h" class CameraFactory { public: std::unique_ptr buildCamera(int width, int height, int cam_index = 0, int exposure=-1, int gain=-1); - std::vector> getCameras(); + std::vector> getCameras(CameraSettings& settings); }; diff --git a/Client/src/camera/OCVCamera.cpp b/Client/src/camera/OCVCamera.cpp index e22eae0..f629bf8 100644 --- a/Client/src/camera/OCVCamera.cpp +++ b/Client/src/camera/OCVCamera.cpp @@ -68,7 +68,7 @@ void OCVCamera::get_frame(uint8_t* buffer) void OCVCamera::set_settings(CameraSettings& settings) { - //TODO + //this->width = settings } CameraSettings OCVCamera::get_settings() diff --git a/Client/src/presenter/presenter.cpp b/Client/src/presenter/presenter.cpp index 6b074f8..08e17b5 100644 --- a/Client/src/presenter/presenter.cpp +++ b/Client/src/presenter/presenter.cpp @@ -26,13 +26,13 @@ Presenter::Presenter(IView& view, std::unique_ptr&& t_factory, s update_stabilizer(state); - CameraFactory camfactory; - - all_cameras = camfactory.getCameras(); + /* + ;*/ - ///camera = camfactory.buildCamera(state.video_width, state.selected_camera, state.video_height, state.cam_exposure, state.cam_gain); + CameraFactory camfactory; + CameraSettings camera_settings = build_camera_params(); + all_cameras = camfactory.getCameras(camera_settings); - //if (!camera->is_valid) if (all_cameras.size() == 0) { std::cout << "[ERROR] NO CAMERAS AVAILABLE" << std::endl; @@ -41,8 +41,6 @@ Presenter::Presenter(IView& view, std::unique_ptr&& t_factory, s } else { - // Choose the camera index we want - //camera = std::move(all_cameras[state.selected_camera]); //Change the number of available cameras state.num_cameras_detected = (int)all_cameras.size(); @@ -98,6 +96,7 @@ void Presenter::init_tracker(int type) #ifdef _DEBUG std::cout << "Resetting old tracker" << std::endl; #endif + this->t.release(); this->t = tracker_factory-> buildTracker(all_cameras[state.selected_camera]->width, all_cameras[state.selected_camera]->height, @@ -203,6 +202,22 @@ void Presenter::update_stabilizer(const ConfigData& data) } } +CameraSettings Presenter::build_camera_params() +{ + CameraSettings camera_settings; + camera_settings.exposure = state.cam_exposure; + camera_settings.gain = state.cam_gain; + camera_settings.fps = state.video_fps; + camera_settings.width = state.video_width; + camera_settings.height = state.video_height; + return camera_settings; +} + +void Presenter::update_camera_params() +{ + all_cameras[state.selected_camera]->set_settings(build_camera_params()); +} + void Presenter::send_data(double* buffer_data) { @@ -247,7 +262,14 @@ void Presenter::save_prefs(const ConfigData& data) int port = data.port; init_sender(ip_str, port); - this->state.selected_camera = data.selected_camera; + state.selected_camera = data.selected_camera; + state.cam_exposure = data.cam_exposure; + state.cam_gain = data.cam_gain; + state.video_fps = data.video_fps; + state.video_height = data.video_height; + state.video_width = data.video_width; + update_camera_params(); + // Rebuild tracker if needed. This also will take care of updating the // state/distance parameter @@ -269,7 +291,6 @@ void Presenter::close_program() //Assure we stop tracking loop. run = false; // Assure all cameras are released (some cameras have a "recording LED" which can be annoying to have on) - for(std::shared_ptr cam : all_cameras) cam->stop_camera(); } \ No newline at end of file diff --git a/Client/src/presenter/presenter.h b/Client/src/presenter/presenter.h index 7df5509..9d22109 100644 --- a/Client/src/presenter/presenter.h +++ b/Client/src/presenter/presenter.h @@ -80,6 +80,18 @@ class Presenter : IPresenter */ void update_stabilizer(const ConfigData &data); + /** + * Helper function. Returns a CameraSettings config given the current application + * state + * @returns camera config given the application state + */ + CameraSettings build_camera_params(); + + /** + * Updates the condifuration of the currently selected camera + */ + void update_camera_params(); + public: std::unique_ptr conf_mgr; diff --git a/Client/src/view/ConfigWindow.cpp b/Client/src/view/ConfigWindow.cpp index ce58624..f9de1d1 100644 --- a/Client/src/view/ConfigWindow.cpp +++ b/Client/src/view/ConfigWindow.cpp @@ -56,6 +56,7 @@ ConfigData ConfigWindow::get_inputs() void ConfigWindow::update_view_state(ConfigData conf) { + std::cout << conf.cam_gain << std::endl; gain_slider->setValue(conf.cam_gain); exposure_slider->setValue(conf.cam_exposure); fps_selector->setValue(conf.video_fps); diff --git a/Client/src/view/WindowMain.cpp b/Client/src/view/WindowMain.cpp index 51386c5..57d24c2 100644 --- a/Client/src/view/WindowMain.cpp +++ b/Client/src/view/WindowMain.cpp @@ -210,7 +210,6 @@ void WindowMain::onSaveClick() void WindowMain::onConfigClick() { this->conf_win->show(); - std::cout << "Config" << std::endl; } void WindowMain::readjust_size() From 62cfc66b033ca7943ac9ee044ff2d7ceaf29abc6 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Fri, 28 Aug 2020 22:24:43 +0200 Subject: [PATCH 10/19] Add changes in preferences to OpenCV camera and to the PS3 one. --- Client/src/camera/OCVCamera.cpp | 12 +++++++++++- Client/src/camera/OCVCamera.h | 1 + Client/src/camera/Ps3Camera.cpp | 2 ++ Client/src/presenter/presenter.cpp | 1 + 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Client/src/camera/OCVCamera.cpp b/Client/src/camera/OCVCamera.cpp index f629bf8..a410372 100644 --- a/Client/src/camera/OCVCamera.cpp +++ b/Client/src/camera/OCVCamera.cpp @@ -18,6 +18,7 @@ OCVCamera::OCVCamera(int width, int height, int fps, int index) : is_valid = true; w_scale = (float)width/(float)cam_native_width; + exposure, gain = -1; } OCVCamera::~OCVCamera() @@ -68,7 +69,16 @@ void OCVCamera::get_frame(uint8_t* buffer) void OCVCamera::set_settings(CameraSettings& settings) { - //this->width = settings + this->width = settings.width; + this->fps = settings.fps; + this->height = settings.height; + w_scale = (float)width / (float)cam_native_width; + + // Opencv needs [0,1] ranges + exposure = settings.exposure < 0 ? -1.0F : (float)settings.exposure/255; + gain = settings.gain < 0 ? -1.0F : (float)settings.gain / 64; + cap.set(cv::CAP_PROP_EXPOSURE, exposure); + cap.set(cv::CAP_PROP_GAIN, gain); } CameraSettings OCVCamera::get_settings() diff --git a/Client/src/camera/OCVCamera.h b/Client/src/camera/OCVCamera.h index a1adbf1..2d51b2f 100644 --- a/Client/src/camera/OCVCamera.h +++ b/Client/src/camera/OCVCamera.h @@ -8,6 +8,7 @@ class OCVCamera : public Camera cv::VideoCapture cap; cv::Size size; float w_scale; + float exposure, gain; int cam_native_width; int cam_index; int CV_BACKEND; diff --git a/Client/src/camera/Ps3Camera.cpp b/Client/src/camera/Ps3Camera.cpp index 49dd9e2..ceddba6 100644 --- a/Client/src/camera/Ps3Camera.cpp +++ b/Client/src/camera/Ps3Camera.cpp @@ -53,6 +53,8 @@ void Ps3Camera::set_settings(CameraSettings& settings) setting.gain = min(settings.gain, 60); ctx.eye->setGain(setting.gain); } + this->fps = settings.fps; + this->ctx.eye->setFrameRate((uint8_t)fps); } CameraSettings Ps3Camera::get_settings() diff --git a/Client/src/presenter/presenter.cpp b/Client/src/presenter/presenter.cpp index 08e17b5..23cd6cc 100644 --- a/Client/src/presenter/presenter.cpp +++ b/Client/src/presenter/presenter.cpp @@ -96,6 +96,7 @@ void Presenter::init_tracker(int type) #ifdef _DEBUG std::cout << "Resetting old tracker" << std::endl; #endif + this->t.reset(); this->t.release(); this->t = tracker_factory-> buildTracker(all_cameras[state.selected_camera]->width, From 47de828dd153d5cdd5d68370a64d1b95d0208e6f Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Fri, 28 Aug 2020 22:39:28 +0200 Subject: [PATCH 11/19] Added camera option to Config GUI to use default camera parameters. --- Client/src/view/ConfigWindow.cpp | 21 +++- Client/src/view/ConfigWindow.h | 2 +- Client/src/view/ConfigWindow.ui | 185 +++++++++++++++++-------------- 3 files changed, 119 insertions(+), 89 deletions(-) diff --git a/Client/src/view/ConfigWindow.cpp b/Client/src/view/ConfigWindow.cpp index f9de1d1..5b07be5 100644 --- a/Client/src/view/ConfigWindow.cpp +++ b/Client/src/view/ConfigWindow.cpp @@ -9,6 +9,7 @@ ConfigWindow::ConfigWindow(IRootView *prev_window, QWidget *parent) // References to UI objects gp_box_camera_prefs = findChild("gbCamera"); + gp_box_image_prefs = gp_box_camera_prefs->findChild("gbImageParams"); btn_apply = findChild("applyBtn"); @@ -16,8 +17,8 @@ ConfigWindow::ConfigWindow(IRootView *prev_window, QWidget *parent) width_selector = gp_box_camera_prefs->findChild("imgWidthSelector"); height_selector = gp_box_camera_prefs->findChild("imgHeightSelector"); fps_selector = gp_box_camera_prefs->findChild("fpsSelector"); - gain_slider = gp_box_camera_prefs->findChild("sliderGain"); - exposure_slider = gp_box_camera_prefs->findChild("sliderExposure"); + gain_slider = gp_box_image_prefs->findChild("sliderGain"); + exposure_slider = gp_box_image_prefs->findChild("sliderExposure"); connect(btn_apply, SIGNAL(released()), this, SLOT(onApplyClick())); } @@ -45,8 +46,8 @@ void ConfigWindow::set_tracking_mode(bool is_tracking) ConfigData ConfigWindow::get_inputs() { ConfigData conf = ConfigData(); - conf.cam_gain = gain_slider->value(); - conf.cam_exposure = exposure_slider->value(); + conf.cam_gain = gp_box_image_prefs->isChecked() ? gain_slider->value() : -1; + conf.cam_exposure = gp_box_image_prefs->isChecked() ? exposure_slider->value() : -1; conf.video_fps = fps_selector->value(); conf.video_width = width_selector->value(); conf.video_height = height_selector->value(); @@ -57,8 +58,16 @@ ConfigData ConfigWindow::get_inputs() void ConfigWindow::update_view_state(ConfigData conf) { std::cout << conf.cam_gain << std::endl; - gain_slider->setValue(conf.cam_gain); - exposure_slider->setValue(conf.cam_exposure); + if (conf.cam_gain > 0 && conf.cam_exposure > 0) + { + gain_slider->setValue(conf.cam_gain); + exposure_slider->setValue(conf.cam_exposure); + gp_box_image_prefs->setChecked(true); + } + else + { + gp_box_image_prefs->setChecked(false); + } fps_selector->setValue(conf.video_fps); width_selector->setValue(conf.video_width); height_selector->setValue(conf.video_height); diff --git a/Client/src/view/ConfigWindow.h b/Client/src/view/ConfigWindow.h index 21d046b..aebace0 100644 --- a/Client/src/view/ConfigWindow.h +++ b/Client/src/view/ConfigWindow.h @@ -38,7 +38,7 @@ class ConfigWindow : public QWidget, IView QPushButton *btn_apply; QComboBox *input_camera; - QGroupBox *gp_box_camera_prefs; + QGroupBox *gp_box_camera_prefs, *gp_box_image_prefs; QSpinBox *width_selector, *height_selector, *fps_selector; QSlider *gain_slider, *exposure_slider; diff --git a/Client/src/view/ConfigWindow.ui b/Client/src/view/ConfigWindow.ui index ba78922..e19a5bc 100644 --- a/Client/src/view/ConfigWindow.ui +++ b/Client/src/view/ConfigWindow.ui @@ -9,8 +9,8 @@ 0 0 - 237 - 336 + 221 + 373 @@ -22,94 +22,18 @@ 10 20 191 - 231 + 291 Camera - - - - 20 - 160 - 131 - 20 - - - - 1 - - - 64 - - - Qt::Horizontal - - - false - - - false - - - QSlider::TicksAbove - - - - - - 20 - 140 - 47 - 13 - - - - Gain - - - - - - 20 - 180 - 47 - 13 - - - - Exposure - - - - - - 20 - 200 - 131 - 20 - - - - 254 - - - 144 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - + 20 20 - 131 + 151 111 @@ -186,12 +110,109 @@ + + + + 20 + 150 + 151 + 121 + + + + Custom brightness + + + true + + + false + + + + + 10 + 40 + 131 + 20 + + + + 1 + + + 64 + + + Qt::Horizontal + + + false + + + false + + + QSlider::TicksAbove + + + + + + 10 + 68 + 47 + 13 + + + + Exposure + + + + + + 10 + 20 + 47 + 13 + + + + Gain + + + + + + 10 + 88 + 131 + 20 + + + + 254 + + + 144 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + + gbImageParams + layoutWidget 20 - 280 + 330 171 31 From 15548490d518e2a3429e4642d81e11108ca94b9d Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Fri, 28 Aug 2020 23:54:25 +0200 Subject: [PATCH 12/19] Moved all config stuff to the Config Window and fixed the issue related to not storing properly IP and port (Github issue #30). --- Client/src/model/UDPSender.cpp | 8 +- Client/src/presenter/presenter.cpp | 11 +- Client/src/view/ConfigWindow.cpp | 40 +++++ Client/src/view/ConfigWindow.h | 19 +- Client/src/view/ConfigWindow.ui | 201 +++++++++++++++++++++- Client/src/view/MainWindow.ui | 268 ++++------------------------- Client/src/view/Resource.qrc | 5 + Client/src/view/WindowMain.cpp | 56 +----- Client/src/view/WindowMain.h | 4 +- Client/src/view/qml.qrc | 7 +- 10 files changed, 301 insertions(+), 318 deletions(-) create mode 100644 Client/src/view/Resource.qrc diff --git a/Client/src/model/UDPSender.cpp b/Client/src/model/UDPSender.cpp index c47e4fa..6798495 100644 --- a/Client/src/model/UDPSender.cpp +++ b/Client/src/model/UDPSender.cpp @@ -1,12 +1,6 @@ -#include "UDPSender.h" - - - #include -//#pragma comment (lib, "Ws2_32.lib") -//#pragma comment (lib, "Mswsock.lib") -//#pragma comment (lib, "AdvApi32.lib") +#include "UDPSender.h" UDPSender::UDPSender(const char* dest_ip, int dest_port) { diff --git a/Client/src/presenter/presenter.cpp b/Client/src/presenter/presenter.cpp index 23cd6cc..5dcf08e 100644 --- a/Client/src/presenter/presenter.cpp +++ b/Client/src/presenter/presenter.cpp @@ -65,6 +65,9 @@ Presenter::Presenter(IView& view, std::unique_ptr&& t_factory, s void Presenter::init_sender(std::string &ip, int port) { + state.ip = ip; + state.port = port; + // Updata only if needed. if (this->udp_sender) { @@ -80,8 +83,6 @@ void Presenter::init_sender(std::string &ip, int port) if (port_dest == 0) port_dest = 4242; - state.ip = ip; - state.port = port; this->udp_sender = std::make_unique(ip_str.data(), port_dest); } @@ -236,10 +237,7 @@ void Presenter::send_data(double* buffer_data) void Presenter::toggle_tracking() { run = !run; - - //ConfigData curr_config = this->conf_mgr->getConfig(); view->set_tracking_mode(run); - if (run) run_loop(); } @@ -257,8 +255,7 @@ void Presenter::save_prefs(const ConfigData& data) // program state. update_stabilizer(data); - // Reset UDPSender - // this will update the state also + // Reset UDPSender this will also update the state member. std::string ip_str = data.ip; int port = data.port; init_sender(ip_str, port); diff --git a/Client/src/view/ConfigWindow.cpp b/Client/src/view/ConfigWindow.cpp index 5b07be5..f5ea59a 100644 --- a/Client/src/view/ConfigWindow.cpp +++ b/Client/src/view/ConfigWindow.cpp @@ -9,6 +9,8 @@ ConfigWindow::ConfigWindow(IRootView *prev_window, QWidget *parent) // References to UI objects gp_box_camera_prefs = findChild("gbCamera"); + gp_box_address = findChild("sendGroupbox"); + gp_box_priors = findChild("paramsGroupBox"); gp_box_image_prefs = gp_box_camera_prefs->findChild("gbImageParams"); btn_apply = findChild("applyBtn"); @@ -20,6 +22,17 @@ ConfigWindow::ConfigWindow(IRootView *prev_window, QWidget *parent) gain_slider = gp_box_image_prefs->findChild("sliderGain"); exposure_slider = gp_box_image_prefs->findChild("sliderExposure"); + + ip_field = gp_box_address->findChild("ipField"); + port_field = gp_box_address->findChild("portField"); + + + check_stabilization_landmarks = gp_box_priors->findChild("landmarkStabChck"); + cb_modelType = gp_box_priors->findChild("modeltypeSelect"); + distance_param = gp_box_priors->findChild("distanceField"); + + + connect(btn_apply, SIGNAL(released()), this, SLOT(onApplyClick())); } @@ -52,6 +65,12 @@ ConfigData ConfigWindow::get_inputs() conf.video_width = width_selector->value(); conf.video_height = height_selector->value(); conf.selected_camera = input_camera->currentIndex(); + conf.prior_distance = distance_param->text().toDouble(); + conf.ip = ip_field->text().toStdString(); + conf.port = port_field->text().toInt(); + conf.use_landmark_stab = check_stabilization_landmarks->isChecked(); + conf.selected_model = cb_modelType->currentIndex(); + return conf; } @@ -75,6 +94,27 @@ void ConfigWindow::update_view_state(ConfigData conf) for (int i = 0; i < conf.num_cameras_detected; i++) input_camera->addItem(QString("Camera %1").arg(i), i); input_camera->setCurrentIndex(conf.selected_camera); + + cb_modelType->clear(); + for (std::string s : conf.model_names) + cb_modelType->addItem(QString(s.data())); + + check_stabilization_landmarks->setChecked(conf.use_landmark_stab); + distance_param->setText(QString::number(conf.prior_distance)); + + if (conf.ip != "" || conf.port > 0) + { + gp_box_address->setChecked(true); + ip_field->setText(QString::fromStdString(conf.ip)); + port_field->setText(QString("%1").arg(conf.port)); + } + else + { + gp_box_address->setChecked(false); + ip_field->setText(""); + port_field->setText(""); + } + } void ConfigWindow::set_enabled(bool enabled) diff --git a/Client/src/view/ConfigWindow.h b/Client/src/view/ConfigWindow.h index aebace0..3a9912a 100644 --- a/Client/src/view/ConfigWindow.h +++ b/Client/src/view/ConfigWindow.h @@ -1,14 +1,12 @@ #pragma once -#include "ui_ConfigWindow.h" - #include #include -/*#include -#include -#include */ - +#include +#include +#include +#include "ui_ConfigWindow.h" #include "i_view.h" @@ -36,13 +34,18 @@ class ConfigWindow : public QWidget, IView IRootView *parentView; QPushButton *btn_apply; - QComboBox *input_camera; + QComboBox *input_camera, *cb_modelType; + + QCheckBox* check_stabilization_landmarks; + QLineEdit* distance_param, * ip_field, * port_field; - QGroupBox *gp_box_camera_prefs, *gp_box_image_prefs; + QGroupBox *gp_box_camera_prefs, *gp_box_image_prefs, *gp_box_address, *gp_box_priors;; QSpinBox *width_selector, *height_selector, *fps_selector; QSlider *gain_slider, *exposure_slider; + + private slots: void onApplyClick(); }; diff --git a/Client/src/view/ConfigWindow.ui b/Client/src/view/ConfigWindow.ui index e19a5bc..ad5d02d 100644 --- a/Client/src/view/ConfigWindow.ui +++ b/Client/src/view/ConfigWindow.ui @@ -9,13 +9,29 @@ 0 0 - 221 - 373 + 419 + 368 + + + 419 + 368 + + ConfigWindow + + + :/logo_256px.ico + :/logo_256px.ico + :/logo_256px.ico + :/logo_256px.ico + :/logo_256px.ico + :/newPrefix/logo_256px.ico + :/newPrefix/logo_256px.ico:/logo_256px.ico + @@ -212,8 +228,8 @@ 20 - 330 - 171 + 320 + 381 31 @@ -221,8 +237,183 @@ Apply + + + true + + + + 210 + 30 + 191 + 91 + + + + Use remote OpenTrack client + + + true + + + false + + + + + 90 + 30 + 91 + 21 + + + + false + + + <html><head/><body><p>IP address where Opentrack is running. Leave empty for using local PC IP address.</p></body></html> + + + asadf + + + Qt::LeftToRight + + + 192.168.1.10 + + + + + + 20 + 30 + 21 + 16 + + + + IP + + + + + + 20 + 60 + 21 + 16 + + + + Port + + + + + + 140 + 60 + 41 + 21 + + + + Qt::LeftToRight + + + 4242 + + + + + + + 210 + 130 + 191 + 151 + + + + Parameters + + + + + 10 + 26 + 61 + 18 + + + + Distance (m) + + + + + + 90 + 27 + 61 + 20 + + + + + + + + + + 10 + 62 + 121 + 16 + + + + Model type + + + + + + 27 + 85 + 121 + 22 + + + + + + + 13 + 118 + 131 + 31 + + + + <html><head/><body><p><span style=" font-weight:600;">Experimental</span></p><p>Apply a filter to reduce noise on the recognized facial landmarks. Can reduce noise and thus, make you able to reduce the amount of Acella fitlering in Opentrack, gaining responsiveness.</p></body></html> + + + -1 + + + Landmark stabilization + + + true + + + - + + + diff --git a/Client/src/view/MainWindow.ui b/Client/src/view/MainWindow.ui index fd390df..54882a3 100644 --- a/Client/src/view/MainWindow.ui +++ b/Client/src/view/MainWindow.ui @@ -7,7 +7,7 @@ 0 0 420 - 590 + 459 @@ -197,249 +197,53 @@ - + - + 0 - 1 + 0 - - - 300 - 190 - + + You can disable the video preview to further reduce the CPU usage of AITrack. - - - 399 - 190 - + + -1 - - Preferences + + Disables the video preview. - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + Qt::LeftToRight + + + false + + + margin-left:150%; + + + Enable preview + + + true - - - true - - - - 184 - 18 - 191 - 91 - - - - Use remote OpenTrack client - - - true - - - false - - - - - 90 - 30 - 91 - 21 - - - - false - - - <html><head/><body><p>IP address where Opentrack is running. Leave empty for using local PC IP address.</p></body></html> - - - asadf - - - Qt::LeftToRight - - - 192.168.1.10 - - - - - - 20 - 30 - 21 - 16 - - - - IP - - - - - - 20 - 60 - 21 - 16 - - - - Port - - - - - - 140 - 60 - 41 - 21 - - - - Qt::LeftToRight - - - 4242 - - - - - - - 10 - 20 - 161 - 151 - - - - Parameters - - - - - 10 - 26 - 61 - 18 - - - - Distance (m) - - - - - - 90 - 27 - 51 - 20 - - - - - - - - - - 10 - 62 - 121 - 16 - - - - Model type - - - - - - 19 - 85 - 121 - 22 - - - - - - - 10 - 118 - 131 - 31 - - - - <html><head/><body><p><span style=" font-weight:600;">Experimental</span></p><p>Apply a filter to reduce noise on the recognized facial landmarks. Can reduce noise and thus, make you able to reduce the amount of Acella fitlering in Opentrack, gaining responsiveness.</p></body></html> - - - -1 - - - Landmark stabilization - - - true - - - - - - - 184 - 144 - 191 - 31 - - - - - 0 - 0 - - - - Apply changes - - - - - - 234 - 115 - 91 - 20 - - - - You can disable the video preview to further reduce the CPU usage of AITrack. - - - -1 - - - Enable preview - - - true - - + + + 0 + 0 + + + + + 0 + 30 + + 🔧 Configuration⚙️ diff --git a/Client/src/view/Resource.qrc b/Client/src/view/Resource.qrc new file mode 100644 index 0000000..eb5986e --- /dev/null +++ b/Client/src/view/Resource.qrc @@ -0,0 +1,5 @@ + + + logo_256px.ico + + diff --git a/Client/src/view/WindowMain.cpp b/Client/src/view/WindowMain.cpp index 57d24c2..aa4d541 100644 --- a/Client/src/view/WindowMain.cpp +++ b/Client/src/view/WindowMain.cpp @@ -20,19 +20,11 @@ WindowMain::WindowMain(QWidget *parent) tracking_frame = findChild("cameraView"); - gp_box_prefs = findChild("prefsGroupbox"); - gp_box_address = gp_box_prefs->findChild("sendGroupbox"); - gp_box_priors = gp_box_prefs->findChild("paramsGroupBox"); - - btn_save = gp_box_prefs->findChild("saveBtn"); btn_config = findChild("btnConfig"); - cb_modelType = gp_box_priors->findChild("modeltypeSelect"); check_video_preview = findChild("chkVideoPreview"); - check_stabilization_landmarks = findChild("landmarkStabChck"); connect(btn_track, SIGNAL(released()), this, SLOT(onTrackClick())); - connect(btn_save, SIGNAL(released()), this, SLOT(onSaveClick())); connect(btn_config, SIGNAL(released()), this, SLOT(onConfigClick())); connect(check_video_preview, SIGNAL(released()), this, SLOT(onSaveClick())); @@ -48,7 +40,6 @@ void WindowMain::closeEvent(QCloseEvent* event) } - void WindowMain::paint_video_frame(cv::Mat& img) { if (check_video_preview->isChecked()) @@ -81,26 +72,12 @@ void WindowMain::set_tracking_mode(bool is_tracking) { // Change button name to "stop" btn_track->setText("Stop tracking"); - - // Disable groupbox fields - gp_box_address->setEnabled(false); - gp_box_priors->setEnabled(false); - - //Disable save button - btn_save->setEnabled(false); } else { // Change button name to "start" btn_track->setText("Start tracking"); - btn_save->setEnabled(true); - - // Enable groupbox Fields - gp_box_address->setEnabled(true); - gp_box_priors->setEnabled(true); - //check_video_preview->setCheckable(false); - // Remove background from label tracking_frame->setPixmap(QPixmap()); tracking_frame->setText("No video input"); @@ -130,32 +107,15 @@ void WindowMain::update_view_state(ConfigData conf) ConfigData WindowMain::get_inputs() { - ConfigData inputs = ConfigData(); - inputs.ip = gp_box_address->findChild("ipField")->text().toStdString(); - inputs.port= gp_box_address->findChild("portField")->text().toInt(); - inputs.prior_distance = gp_box_priors->findChild("distanceField")->text().toDouble(); + // Obtain inputs of children windows + ConfigData inputs = conf_win->get_inputs(); inputs.show_video_feed = check_video_preview->isChecked(); - inputs.selected_model = cb_modelType->currentIndex(); - inputs.use_landmark_stab = check_stabilization_landmarks->isChecked(); return inputs; } void WindowMain::set_inputs(const ConfigData data) { - if(data.ip != "" || data.port > 0) - gp_box_address->setChecked(true); - - gp_box_address->findChild("ipField")->setText(data.ip.data()); - gp_box_address->findChild("portField")->setText(data.port==0 ? "" : QString::number(data.port)); - gp_box_priors->findChild("distanceField")->setText(QString::number(data.prior_distance)); check_video_preview->setChecked(data.show_video_feed); - - cb_modelType->clear(); - for (std::string s:data.model_names) - cb_modelType->addItem(QString(s.data())); - cb_modelType->setCurrentIndex(data.selected_model); - check_stabilization_landmarks->setChecked(data.use_landmark_stab); - this->conf_win->update_view_state(data); } @@ -189,20 +149,10 @@ void WindowMain::onTrackClick() void WindowMain::onSaveClick() { - // Obtain inputs of children windows - ConfigData conf_child = conf_win->get_inputs(); - // Merge with config from this window ConfigData config = get_inputs(); - - conf_child.ip = config.ip; - conf_child.port = config.port; - conf_child.prior_distance = config.prior_distance; - conf_child.show_video_feed = config.show_video_feed; - conf_child.selected_model = config.selected_model; - conf_child.use_landmark_stab = config.use_landmark_stab; - presenter->save_prefs(conf_child); + presenter->save_prefs(config); std::cout << "Saved changes" << std::endl; } diff --git a/Client/src/view/WindowMain.h b/Client/src/view/WindowMain.h index 5c614b8..d05b71a 100644 --- a/Client/src/view/WindowMain.h +++ b/Client/src/view/WindowMain.h @@ -45,9 +45,9 @@ class WindowMain : public QMainWindow, IView, IRootView Ui::MainWindow ui; QPushButton *btn_track, *btn_save, *btn_config; QLabel *tracking_frame, *tracking_info; - QGroupBox *gp_box_prefs, *gp_box_address, *gp_box_priors; + //QGroupBox *gp_box_prefs, *gp_box_address, *gp_box_priors; QCheckBox *check_video_preview, *check_stabilization_landmarks; - QComboBox* cb_modelType; + //QComboBox* cb_modelType; ConfigWindow *conf_win; /** diff --git a/Client/src/view/qml.qrc b/Client/src/view/qml.qrc index e9989e1..ba26709 100644 --- a/Client/src/view/qml.qrc +++ b/Client/src/view/qml.qrc @@ -1,6 +1,5 @@ - - MainWindow.ui - ConfigWindow.ui - + + logo_256px.ico + From b1d03a1045d0aa5c5f698f711fa549b64cb0b196 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Sat, 29 Aug 2020 00:02:14 +0200 Subject: [PATCH 13/19] Disable config window on tracking. --- Client/src/view/ConfigWindow.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Client/src/view/ConfigWindow.cpp b/Client/src/view/ConfigWindow.cpp index f5ea59a..b086b4a 100644 --- a/Client/src/view/ConfigWindow.cpp +++ b/Client/src/view/ConfigWindow.cpp @@ -119,8 +119,7 @@ void ConfigWindow::update_view_state(ConfigData conf) void ConfigWindow::set_enabled(bool enabled) { - gp_box_camera_prefs->setEnabled(enabled); - btn_apply->setEnabled(enabled); + this->setEnabled(enabled); } void ConfigWindow::show_message(const char* msg, MSG_SEVERITY severity){} \ No newline at end of file From 1cca0b3967922b9addcd8c04a1497224d2a776d1 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Sat, 29 Aug 2020 00:09:30 +0200 Subject: [PATCH 14/19] Fixed landmark stabilizer (EAFilter) bug. last_value was not being initializated to 0, so the first readings could be too deviated. This is related to the "jump like crazy" bug, because only one point far from its correct place could completely mess up the solvePnP calculation. --- AITracker/src/filters.cpp | 4 ++++ Client/src/presenter/presenter.cpp | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/AITracker/src/filters.cpp b/AITracker/src/filters.cpp index 88ff42f..bd6bd5b 100644 --- a/AITracker/src/filters.cpp +++ b/AITracker/src/filters.cpp @@ -1,5 +1,7 @@ #include "filters.h" +#include + MAFilter::MAFilter(int steps, int array_size) { this->n_steps = steps; @@ -41,6 +43,8 @@ EAFilter::EAFilter(int array_size) { this->array_size = array_size; this->last_value = new float[array_size]; + //If the last value is not 0, the first readings could bounce + std::memset(last_value, 0, array_size * sizeof(float)); } EAFilter::~EAFilter() diff --git a/Client/src/presenter/presenter.cpp b/Client/src/presenter/presenter.cpp index 5dcf08e..8bd29dc 100644 --- a/Client/src/presenter/presenter.cpp +++ b/Client/src/presenter/presenter.cpp @@ -25,10 +25,6 @@ Presenter::Presenter(IView& view, std::unique_ptr&& t_factory, s // Setup a filter to stabilize the recognized facial landmarks if needed. update_stabilizer(state); - - /* - ;*/ - CameraFactory camfactory; CameraSettings camera_settings = build_camera_params(); all_cameras = camfactory.getCameras(camera_settings); From ea7e40366831bab77dd48e5b38bd27d04f607d7f Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Sat, 29 Aug 2020 00:28:36 +0200 Subject: [PATCH 15/19] Update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index db6607e..2c476a7 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Don't worry. AITrack supports low resolutions pretty well. Anything achieving at **IMPORTANT:** In case you want to know more, please, head to the `Doc/` directory to find guides about usage. If you can't find there what you're looking for, feel free to post your question on the [issues page](https://github.com/AIRLegend/aitracker/issues). -**Thanks to Sims Smith**, who made a [video tutorial on how to setting up AITrack (v0.4)](https://img.youtube.com/vi/LPlahUVPx4o/hqdefault.jpg). You can check it out. +**Thanks to Sims Smith**, who made a [video tutorial on how to setting up AITrack (v0.4)](https://youtu.be/LPlahUVPx4o) and **Stream Flight**, with a [tutorial for v0.5](https://www.youtube.com/watch?v=CMIwUg8NAlg). You can check them out. **ALSO IMPORTANT AND NOT COVERED IN THE VIDEO TUTORIAL** From 57fedc2c44c8e5e5f337f6fc239cef0a4334c8f1 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Sat, 29 Aug 2020 18:39:09 +0200 Subject: [PATCH 16/19] Delete old stuff --- Client/src/model/IPResolver.cpp | 23 ----------------------- Client/src/model/IPResolver.h | 8 -------- Client/src/view/qml.qrc | 5 ----- 3 files changed, 36 deletions(-) delete mode 100644 Client/src/model/IPResolver.cpp delete mode 100644 Client/src/model/IPResolver.h delete mode 100644 Client/src/view/qml.qrc diff --git a/Client/src/model/IPResolver.cpp b/Client/src/model/IPResolver.cpp deleted file mode 100644 index a7908da..0000000 --- a/Client/src/model/IPResolver.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "IPResolver.h" - -#include -#include -#include -//#include - -std::string network::get_local_ip() -{ - /*const QHostAddress& localhost = QHostAddress(QHostAddress::LocalHost); - for (const QHostAddress& address : QNetworkInterface::allAddresses()) { - - if (address.protocol() == QAbstractSocket::IPv4Protocol && address != localhost) - { -#ifdef _DEBUG - qDebug() << address.toString(); -#endif // _DEBUG - return address.toString().toStdString(); - } - }*/ - - return "127.0.0.1"; -} \ No newline at end of file diff --git a/Client/src/model/IPResolver.h b/Client/src/model/IPResolver.h deleted file mode 100644 index d7eac6b..0000000 --- a/Client/src/model/IPResolver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include - -namespace network -{ - std::string get_local_ip(); -} diff --git a/Client/src/view/qml.qrc b/Client/src/view/qml.qrc deleted file mode 100644 index ba26709..0000000 --- a/Client/src/view/qml.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - logo_256px.ico - - From ac86da0bd24fa0066c399d1f02c4ec111819f5a8 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Sat, 29 Aug 2020 18:41:41 +0200 Subject: [PATCH 17/19] Model dropdown was not being correctly set to the current selected model. --- Client/src/view/ConfigWindow.cpp | 1 + Client/src/view/ConfigWindow.ui | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Client/src/view/ConfigWindow.cpp b/Client/src/view/ConfigWindow.cpp index b086b4a..1bc8711 100644 --- a/Client/src/view/ConfigWindow.cpp +++ b/Client/src/view/ConfigWindow.cpp @@ -98,6 +98,7 @@ void ConfigWindow::update_view_state(ConfigData conf) cb_modelType->clear(); for (std::string s : conf.model_names) cb_modelType->addItem(QString(s.data())); + cb_modelType->setCurrentIndex(conf.selected_model); check_stabilization_landmarks->setChecked(conf.use_landmark_stab); distance_param->setText(QString::number(conf.prior_distance)); diff --git a/Client/src/view/ConfigWindow.ui b/Client/src/view/ConfigWindow.ui index ad5d02d..2a2dcda 100644 --- a/Client/src/view/ConfigWindow.ui +++ b/Client/src/view/ConfigWindow.ui @@ -13,6 +13,12 @@ 368 + + + 419 + 368 + + 419 @@ -117,7 +123,7 @@ - Input ID + Camera From a06ed3eba631be86331f277ecd27f9a285aa13e8 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Sat, 29 Aug 2020 18:45:08 +0200 Subject: [PATCH 18/19] Deleted references to IP^Resolver and added check on OpenCV camera to also return false if it can read a valid frame. --- Client/Client.vcxproj | 4 +--- Client/Client.vcxproj.filters | 8 +++++--- Client/src/camera/OCVCamera.cpp | 5 +++++ Client/src/presenter/presenter.cpp | 3 +-- Client/src/view/MainWindow.ui | 8 +++++++- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Client/Client.vcxproj b/Client/Client.vcxproj index 0be4f4a..c665081 100644 --- a/Client/Client.vcxproj +++ b/Client/Client.vcxproj @@ -178,7 +178,6 @@ - @@ -188,7 +187,7 @@ - + @@ -202,7 +201,6 @@ - diff --git a/Client/Client.vcxproj.filters b/Client/Client.vcxproj.filters index 3d5e4f6..4cf05a3 100644 --- a/Client/Client.vcxproj.filters +++ b/Client/Client.vcxproj.filters @@ -1,7 +1,6 @@  - @@ -34,7 +33,6 @@ - @@ -78,7 +76,6 @@ - Resource Files @@ -120,4 +117,9 @@ Form Files + + + Resource Files + + \ No newline at end of file diff --git a/Client/src/camera/OCVCamera.cpp b/Client/src/camera/OCVCamera.cpp index a410372..ad22f6e 100644 --- a/Client/src/camera/OCVCamera.cpp +++ b/Client/src/camera/OCVCamera.cpp @@ -34,6 +34,11 @@ bool OCVCamera::is_camera_available() available = cap.isOpened(); if (available) { + cv::Mat frame; + cap.read(frame); + if (frame.empty()) + return false; + cam_native_width = cap.get(cv::CAP_PROP_FRAME_WIDTH); cap.release(); } diff --git a/Client/src/presenter/presenter.cpp b/Client/src/presenter/presenter.cpp index 8bd29dc..950307a 100644 --- a/Client/src/presenter/presenter.cpp +++ b/Client/src/presenter/presenter.cpp @@ -4,7 +4,6 @@ #include "presenter.h" #include "opencv.hpp" -#include "../model/IPResolver.h" #include "../camera/CameraFactory.h" @@ -74,7 +73,7 @@ void Presenter::init_sender(std::string &ip, int port) std::string ip_str = ip; int port_dest = port; if (QString(ip_str.data()).simplified().replace(" ", "").size() < 2) - ip_str = network::get_local_ip(); + ip_str = "127.0.0.1"; if (port_dest == 0) port_dest = 4242; diff --git a/Client/src/view/MainWindow.ui b/Client/src/view/MainWindow.ui index 54882a3..06c2e2f 100644 --- a/Client/src/view/MainWindow.ui +++ b/Client/src/view/MainWindow.ui @@ -184,6 +184,7 @@ + 10 75 true @@ -244,8 +245,13 @@ 30 + + + 10 + + - 🔧 Configuration⚙️ + Configuration ⚙️ From 11c235bafed4b6a1942fdcfb7b0caa3f5efa6d8c Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Sat, 29 Aug 2020 18:49:32 +0200 Subject: [PATCH 19/19] Added reference to wiki in the README --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2c476a7..8898997 100644 --- a/README.md +++ b/README.md @@ -39,11 +39,11 @@ Don't worry. AITrack supports low resolutions pretty well. Anything achieving at --- **IMPORTANT:** -In case you want to know more, please, head to the `Doc/` directory to find guides about usage. If you can't find there what you're looking for, feel free to post your question on the [issues page](https://github.com/AIRLegend/aitracker/issues). +In case you want to know more, please, head to the [project's wiki](https://github.com/AIRLegend/aitrack/wiki) to find guides about usage. If you can't find there what you're looking for, feel free to post your question on the [issues page](https://github.com/AIRLegend/aitracker/issues). **Thanks to Sims Smith**, who made a [video tutorial on how to setting up AITrack (v0.4)](https://youtu.be/LPlahUVPx4o) and **Stream Flight**, with a [tutorial for v0.5](https://www.youtube.com/watch?v=CMIwUg8NAlg). You can check them out. -**ALSO IMPORTANT AND NOT COVERED IN THE VIDEO TUTORIAL** +**ALSO IMPORTANT AND NOT COVERED IN THE VIDEO TUTORIALS** >Because of v0.4 is an older version, several punctualizations have to be made: >1) You don't need to configure "Use remote client" anymore if you're running Opentrack in your local machine. @@ -58,9 +58,9 @@ In case you want to know more, please, head to the `Doc/` directory to find guid ## Bugs and Contributing -If you encounter any bug/problem or you have some idea, post it on the [issues page](https://github.com/AIRLegend/aitracker/issues) to find help or further discussion. If you decide to fix something or implement a request, feel free to fork this repo, develop your new feature in a separate branch and then, make a PR to review it, here is the [guide to developers](Doc/DEVELOP.md). +If you encounter any bug/problem or you have some idea, post it on the [issues page](https://github.com/AIRLegend/aitracker/issues) to find help or further discussion. If you decide to fix something or implement a request, feel free to fork this repo, develop your new feature in a separate branch and then, make a PR to review it, here is the [guide to developers](Doc/DEVELOP.md) (also available in the wiki). -Also, there is a Discord server you can join to be aware of the news of the project, report problems or request features! +Besides, there is a Discord server you can join to be aware of the news of the project, report problems or request features! Join the server!