From d4074f68512ca3e83bffee06857dc685dcbaffca Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Tue, 25 Aug 2020 09:15:37 +0200 Subject: [PATCH 1/4] Resize OCVCamera image maintaining aspect ratio instead of forcing the resolution change. --- Client/src/camera/OCVCamera.cpp | 14 ++++++++++---- Client/src/camera/OCVCamera.h | 2 ++ Client/src/camera/Ps3Camera.cpp | 1 - 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Client/src/camera/OCVCamera.cpp b/Client/src/camera/OCVCamera.cpp index f10cc4c..3c8b739 100644 --- a/Client/src/camera/OCVCamera.cpp +++ b/Client/src/camera/OCVCamera.cpp @@ -3,7 +3,7 @@ OCVCamera::OCVCamera(int width, int height, int fps) : Camera(width, height, fps), - size(width, height), + size(0, 0), cap() { CV_BACKEND = cv::CAP_DSHOW; @@ -15,7 +15,8 @@ OCVCamera::OCVCamera(int width, int height, int fps) : throw std::runtime_error("No compatible camera found."); } is_valid = true; - cap.set(cv::CAP_PROP_BUFFERSIZE, 1); + + w_scale = (float)width/(float)cam_native_width; } OCVCamera::~OCVCamera() @@ -30,8 +31,10 @@ bool OCVCamera::is_camera_available() cap.open(0, CV_BACKEND); available = cap.isOpened(); if (available) + { + cam_native_width = cap.get(cv::CAP_PROP_FRAME_WIDTH); cap.release(); - + } return available; } @@ -53,7 +56,10 @@ void OCVCamera::get_frame(uint8_t* buffer) { cv::Mat frame; cap.read(frame); - cv::resize(frame, frame, size); + //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++) buffer[i] = frame.data[i]; diff --git a/Client/src/camera/OCVCamera.h b/Client/src/camera/OCVCamera.h index 49e54e0..d6b4bb0 100644 --- a/Client/src/camera/OCVCamera.h +++ b/Client/src/camera/OCVCamera.h @@ -7,6 +7,8 @@ class OCVCamera : public Camera private: cv::VideoCapture cap; cv::Size size; + float w_scale; + int cam_native_width; int CV_BACKEND; bool is_camera_available(); diff --git a/Client/src/camera/Ps3Camera.cpp b/Client/src/camera/Ps3Camera.cpp index b4864c1..82a7fba 100644 --- a/Client/src/camera/Ps3Camera.cpp +++ b/Client/src/camera/Ps3Camera.cpp @@ -9,7 +9,6 @@ Ps3Camera::Ps3Camera(int width, int height, int fps): { if (!this->ctx.hasDevices()) { - std::cout << "SOME ERROR BUILDING" << std::endl; throw std::runtime_error("No PS3 Camera found."); } ctx.eye->setFlip(true); From f177ca69e38637e5e3fd298f6f180e9decfbe6b9 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Tue, 25 Aug 2020 15:48:10 +0200 Subject: [PATCH 2/4] Solved crash on startup bug For some reason, libusb_get_device_list produced a SEGFAULT. This was experienced by some people while constructing a PS3 camera and query for connected devices. Forcing libusb initialization on each query solves the error. --- Client/src/presenter/presenter.cpp | 8 +------- PS3Driver/src/ps3eye.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Client/src/presenter/presenter.cpp b/Client/src/presenter/presenter.cpp index f8b44ae..ea90157 100644 --- a/Client/src/presenter/presenter.cpp +++ b/Client/src/presenter/presenter.cpp @@ -17,14 +17,12 @@ Presenter::Presenter(IView& view, TrackerFactory* t_factory, ConfigMgr* conf_mgr 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); - //this->filter = new MAFilter(3, 66*2); - //this->filter = new EAFilter(66 * 2); - //this->filter = nullptr; // Setup a filter to stabilize the recognized facial landmarks if needed. update_stabilizer(state); @@ -45,13 +43,9 @@ Presenter::Presenter(IView& view, TrackerFactory* t_factory, ConfigMgr* conf_mgr int port = state.port; init_sender(ip_str, port); - // Build tracker init_tracker(state.selected_model); - // Get avilable model types - this->tracker_factory->get_model_names(state.model_names); - } // Check if there was a problem initing tracker diff --git a/PS3Driver/src/ps3eye.cpp b/PS3Driver/src/ps3eye.cpp index 98d0e01..f661c92 100644 --- a/PS3Driver/src/ps3eye.cpp +++ b/PS3Driver/src/ps3eye.cpp @@ -331,6 +331,10 @@ USBMgr::USBMgr() active_camera_count = 0; libusb_init(&usb_context); libusb_set_debug(usb_context, 1); + + libusb_set_option(usb_context, + LIBUSB_OPTION_LOG_LEVEL, + LIBUSB_LOG_LEVEL_INFO); } USBMgr::~USBMgr() @@ -392,9 +396,14 @@ int USBMgr::listDevices( std::vector& list ) libusb_device *dev; libusb_device **devs; libusb_device_handle *devhandle; + int i = 0; int cnt; + int res = libusb_init(&usb_context); + if (res < 0) + return 0; + cnt = (int)libusb_get_device_list(usb_context, &devs); if (cnt < 0) { @@ -986,6 +995,7 @@ static void LIBUSB_CALL transfer_completed_callback(struct libusb_transfer *xfr) bool PS3EYECam::devicesEnumerated = false; std::vector PS3EYECam::devices; + const std::vector& PS3EYECam::getDevices( bool forceRefresh ) { if( devicesEnumerated && ( ! forceRefresh ) ) From 12bfced2356e07c6adc0c623b05ec3a6247fe7e5 Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Tue, 25 Aug 2020 16:57:06 +0200 Subject: [PATCH 3/4] Update docs --- Doc/USER_GUIDE.md | 17 +++++++++++++++++ README.md | 9 +++++++++ 2 files changed, 26 insertions(+) diff --git a/Doc/USER_GUIDE.md b/Doc/USER_GUIDE.md index 59806a4..da70da8 100644 --- a/Doc/USER_GUIDE.md +++ b/Doc/USER_GUIDE.md @@ -1,5 +1,22 @@ # User guide: Setup, common problems and tips +## Video version + +Thanks to Sims Smith, for making a tutorial on how to setup this software to work with XPlane and Flight Simulator 2020. Although it's made for AITrack v0.4, the core process is almost the same. + +Although this tutorial covers pretty much everything, it's worth pointing out that: + + +
+ +[](https://youtu.be/LPlahUVPx4o) + +
+ +1) You don't need to configure "Use remote client" anymore if you're running Opentrack in your local machine. +2) You should take you time for [tweaking your curves in Opentrack](https://www.youtube.com/watch?v=u0TBI7SoGkc) to your preferences. +3) Experiment with Opentrack's built in filters. Acella it's the recommended one at the moment. Configure it's smoothing parameter to reduce camera shaking. + ## Configuring opentrack and AiTrack AiTrack sends data over UDP to opentrack, which in turn, sends it to your game, so both of them need to be running. diff --git a/README.md b/README.md index 8d79c00..db6607e 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,15 @@ 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. + +**ALSO IMPORTANT AND NOT COVERED IN THE VIDEO TUTORIAL** + +>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. +>2) You should take you time for [tweaking your curves in Opentrack](https://www.youtube.com/watch?v=u0TBI7SoGkc) to your preferences. +>3) Experiment with Opentrack's built in filters. Acella it's the recommended one at the moment. Configure it's smoothing parameter to reduce camera shaking. + --- ## Showoff videos From b67d24c687209de570ffff2271d0c3070da8b4ce Mon Sep 17 00:00:00 2001 From: AIRLegend Date: Tue, 25 Aug 2020 17:26:03 +0200 Subject: [PATCH 4/4] Add preferences for camera settings (gain and exposure). Right now, only it's implemented the behaviour for the PS3 camera. Will be needed to also implement it for OCVCamera. --- Client/Client.vcxproj | 2 ++ Client/Client.vcxproj.filters | 6 ++++++ Client/src/camera/Camera.h | 3 +++ Client/src/camera/CameraFactory.cpp | 7 ++++++- Client/src/camera/CameraFactory.h | 2 +- Client/src/camera/CameraSettings.cpp | 17 ++++++++++++++++ Client/src/camera/CameraSettings.h | 12 +++++++++++ Client/src/camera/NullCamera.h | 2 ++ Client/src/camera/OCVCamera.cpp | 10 ++++++++++ Client/src/camera/OCVCamera.h | 2 ++ Client/src/camera/Ps3Camera.cpp | 30 +++++++++++++++++++++++++--- Client/src/camera/Ps3Camera.h | 3 +++ Client/src/model/Config.cpp | 6 ++++++ Client/src/model/Config.h | 3 +++ Client/src/presenter/presenter.cpp | 2 +- 15 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 Client/src/camera/CameraSettings.cpp create mode 100644 Client/src/camera/CameraSettings.h diff --git a/Client/Client.vcxproj b/Client/Client.vcxproj index b0d711d..c3e157d 100644 --- a/Client/Client.vcxproj +++ b/Client/Client.vcxproj @@ -173,6 +173,7 @@ + @@ -195,6 +196,7 @@ + diff --git a/Client/Client.vcxproj.filters b/Client/Client.vcxproj.filters index 05e64fd..a320f84 100644 --- a/Client/Client.vcxproj.filters +++ b/Client/Client.vcxproj.filters @@ -25,6 +25,9 @@ Source Files + + Source Files + @@ -61,6 +64,9 @@ Header Files + + Header Files + diff --git a/Client/src/camera/Camera.h b/Client/src/camera/Camera.h index 83aa29c..96bb3d0 100644 --- a/Client/src/camera/Camera.h +++ b/Client/src/camera/Camera.h @@ -1,6 +1,7 @@ #pragma once #include +#include "CameraSettings.h" class Camera { @@ -11,6 +12,8 @@ class Camera virtual void start_camera() = 0; virtual void stop_camera() = 0; virtual void get_frame(uint8_t* buffer) = 0; + virtual void set_settings(CameraSettings& settings) = 0; + virtual CameraSettings get_settings() = 0; Camera(int width, int height, int fps) { this->width = width; diff --git a/Client/src/camera/CameraFactory.cpp b/Client/src/camera/CameraFactory.cpp index be3b52b..cad3cf4 100644 --- a/Client/src/camera/CameraFactory.cpp +++ b/Client/src/camera/CameraFactory.cpp @@ -4,7 +4,7 @@ #include "OCVCamera.h" #include "NullCamera.h" -Camera* CameraFactory::buildCamera(int width, int height) +Camera* CameraFactory::buildCamera(int width, int height, int exposure, int gain) { Camera *camera = NULL; bool error = false; @@ -35,5 +35,10 @@ Camera* CameraFactory::buildCamera(int width, int height) camera = new NullCamera; } + CameraSettings cam_settings; + cam_settings.exposure = exposure; + cam_settings.gain = gain; + camera->set_settings(cam_settings); + return camera; } \ No newline at end of file diff --git a/Client/src/camera/CameraFactory.h b/Client/src/camera/CameraFactory.h index d177eff..3dd0dbe 100644 --- a/Client/src/camera/CameraFactory.h +++ b/Client/src/camera/CameraFactory.h @@ -5,6 +5,6 @@ class CameraFactory { public: - Camera* buildCamera(int width, int height); + Camera* buildCamera(int width, int height, int exposure=-1, int gain=-1); }; diff --git a/Client/src/camera/CameraSettings.cpp b/Client/src/camera/CameraSettings.cpp new file mode 100644 index 0000000..ffc5a20 --- /dev/null +++ b/Client/src/camera/CameraSettings.cpp @@ -0,0 +1,17 @@ +#include "CameraSettings.h" + + +CameraSettings::CameraSettings() +{ + exposure = -1; + gain = -1; +} + +CameraSettings::CameraSettings(CameraSettings& settings) +{ + exposure = settings.exposure; + gain = settings.gain; +} + +CameraSettings::~CameraSettings() +{} \ No newline at end of file diff --git a/Client/src/camera/CameraSettings.h b/Client/src/camera/CameraSettings.h new file mode 100644 index 0000000..3f79f21 --- /dev/null +++ b/Client/src/camera/CameraSettings.h @@ -0,0 +1,12 @@ +#pragma once + +struct CameraSettings +{ + int exposure; + int gain; + + CameraSettings(); + CameraSettings(CameraSettings& settings); + ~CameraSettings(); +}; + diff --git a/Client/src/camera/NullCamera.h b/Client/src/camera/NullCamera.h index 6131d98..9bafa35 100644 --- a/Client/src/camera/NullCamera.h +++ b/Client/src/camera/NullCamera.h @@ -9,4 +9,6 @@ class NullCamera : public Camera void start_camera() {}; void stop_camera() {}; void get_frame(uint8_t* buffer) {}; + void set_settings(CameraSettings& settings) {}; + CameraSettings get_settings() { return CameraSettings(); }; }; diff --git a/Client/src/camera/OCVCamera.cpp b/Client/src/camera/OCVCamera.cpp index 3c8b739..e0a76db 100644 --- a/Client/src/camera/OCVCamera.cpp +++ b/Client/src/camera/OCVCamera.cpp @@ -65,3 +65,13 @@ void OCVCamera::get_frame(uint8_t* buffer) buffer[i] = frame.data[i]; } + +void OCVCamera::set_settings(CameraSettings& settings) +{ + //TODO +} + +CameraSettings OCVCamera::get_settings() +{ + return CameraSettings(); +} diff --git a/Client/src/camera/OCVCamera.h b/Client/src/camera/OCVCamera.h index d6b4bb0..c374d09 100644 --- a/Client/src/camera/OCVCamera.h +++ b/Client/src/camera/OCVCamera.h @@ -19,5 +19,7 @@ class OCVCamera : public Camera void start_camera(); void stop_camera(); void get_frame(uint8_t* buffer); + void set_settings(CameraSettings& settings); + CameraSettings get_settings(); }; diff --git a/Client/src/camera/Ps3Camera.cpp b/Client/src/camera/Ps3Camera.cpp index 82a7fba..49dd9e2 100644 --- a/Client/src/camera/Ps3Camera.cpp +++ b/Client/src/camera/Ps3Camera.cpp @@ -3,9 +3,10 @@ #include -Ps3Camera::Ps3Camera(int width, int height, int fps): +Ps3Camera::Ps3Camera(int width, int height, int fps) : Camera(width, height, fps), - ctx(width, height, fps) + ctx(width, height, fps), + setting() { if (!this->ctx.hasDevices()) { @@ -13,6 +14,9 @@ Ps3Camera::Ps3Camera(int width, int height, int fps): } ctx.eye->setFlip(true); this->is_valid = true; + + setting.exposure = 140; + setting.gain = 1; } Ps3Camera::~Ps3Camera() @@ -34,4 +38,24 @@ void Ps3Camera::stop_camera() void Ps3Camera::get_frame(uint8_t *buffer) { this->ctx.eye->getFrame(buffer); -} \ No newline at end of file +} + +void Ps3Camera::set_settings(CameraSettings& settings) +{ + if (settings.exposure >= 0) + { + setting.exposure = min(settings.exposure, 254); + ctx.eye->setExposure(setting.exposure); + } + + if (settings.gain >= 0) + { + setting.gain = min(settings.gain, 60); + ctx.eye->setGain(setting.gain); + } +} + +CameraSettings Ps3Camera::get_settings() +{ + return CameraSettings(setting); +} diff --git a/Client/src/camera/Ps3Camera.h b/Client/src/camera/Ps3Camera.h index ee73247..501d33d 100644 --- a/Client/src/camera/Ps3Camera.h +++ b/Client/src/camera/Ps3Camera.h @@ -37,6 +37,7 @@ class Ps3Camera : public Camera private: ps3eye_context ctx; + CameraSettings setting; public: Ps3Camera(int width = 640, int height = 480, int fps = 30); @@ -44,5 +45,7 @@ class Ps3Camera : public Camera void start_camera(); void stop_camera(); void get_frame(uint8_t* buffer); + void set_settings(CameraSettings& settings); + CameraSettings get_settings(); }; diff --git a/Client/src/model/Config.cpp b/Client/src/model/Config.cpp index 1308e61..94dbe2f 100644 --- a/Client/src/model/Config.cpp +++ b/Client/src/model/Config.cpp @@ -19,6 +19,8 @@ ConfigData ConfigData::getGenericConfig() conf.video_fps = 30; conf.use_landmark_stab = true; conf.x, conf.y, conf.z, conf.pitch, conf.yaw, conf.roll = 0; + conf.cam_exposure = -1; + conf.cam_gain = -1; return conf; } @@ -48,6 +50,8 @@ void ConfigMgr::updateConfig(const ConfigData& data) conf.setValue("video_height", data.video_height); conf.setValue("stabilize_landmarks", data.use_landmark_stab); conf.setValue("fps", data.video_fps); + conf.setValue("cam_exposure", data.cam_exposure); + conf.setValue("cam_gain", data.cam_gain); } ConfigData ConfigMgr::getConfig() @@ -64,6 +68,8 @@ ConfigData ConfigMgr::getConfig() 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(); + c.cam_exposure= conf.value("cam_exposure", -1).toInt(); + c.cam_gain = conf.value("cam_gain", -1).toInt(); return c; } diff --git a/Client/src/model/Config.h b/Client/src/model/Config.h index e43f76d..d92cd79 100644 --- a/Client/src/model/Config.h +++ b/Client/src/model/Config.h @@ -21,6 +21,9 @@ struct ConfigData float x, y, z, yaw, pitch, roll; + int cam_exposure; + int cam_gain; + std::vector model_names; int selected_model; diff --git a/Client/src/presenter/presenter.cpp b/Client/src/presenter/presenter.cpp index ea90157..1ea8877 100644 --- a/Client/src/presenter/presenter.cpp +++ b/Client/src/presenter/presenter.cpp @@ -28,7 +28,7 @@ Presenter::Presenter(IView& view, TrackerFactory* t_factory, ConfigMgr* conf_mgr CameraFactory camfactory; - camera = camfactory.buildCamera(state.video_width, state.video_height); + camera = camfactory.buildCamera(state.video_width, state.video_height, state.cam_exposure, state.cam_gain); if (!camera->is_valid) {