diff --git a/.gitignore b/.gitignore
index b1a9a70..63cf4ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -350,7 +350,9 @@ Client/models
prefs.ini
log.txt
+
# CMake
CMakeCache.txt
CMakeFiles/
-
+/cmake-build-debug/
+cmake_install.cmake
diff --git a/AITracker/AITracker.vcxproj b/AITracker/AITracker.vcxproj
index c2efa05..509e3c8 100644
--- a/AITracker/AITracker.vcxproj
+++ b/AITracker/AITracker.vcxproj
@@ -189,7 +189,7 @@
true
$(SolutionDir)Dependencies\OpenCV\include\;$(SolutionDir)Dependencies\onnxruntime\include\;%(AdditionalIncludeDirectories)
MultiThreadedDLL
- Disabled
+ MaxSpeed
Console
diff --git a/AITracker/src/PositionSolver.cpp b/AITracker/src/PositionSolver.cpp
index 0b73bb1..e6361ef 100644
--- a/AITracker/src/PositionSolver.cpp
+++ b/AITracker/src/PositionSolver.cpp
@@ -1,5 +1,6 @@
#include "PositionSolver.h"
+#define USE_FOV // Use FOV correction for the camera matrix.
PositionSolver::PositionSolver(
int width,
@@ -20,7 +21,7 @@ PositionSolver::PositionSolver(
{
this->prior_pitch = -1.57;
this->prior_yaw = -1.57;
- this->prior_distance = prior_distance * -2.;
+ this->prior_distance = prior_distance * -2.0;
this->rv[0] = this->prior_pitch;
this->rv[1] = this->prior_yaw;
@@ -28,8 +29,8 @@ PositionSolver::PositionSolver(
this->tv[2] = this->prior_distance;
head3dScale = (cv::Mat_(3, 3) <<
- x_scale, 0.0, 0,
- 0.0, y_scale, 0,
+ y_scale, 0.0, 0, // pitch is rv[0], pitch involves y-axis
+ 0.0, x_scale, 0, // yaw is rv[1], yaw involves x-axis
0.0, 0.0, z_scale
);
@@ -63,9 +64,9 @@ PositionSolver::PositionSolver(
{
contour_indices = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,27,28,29,30,31,32,33,34,35,36,39,42,45 };
- landmark_points_buffer = cv::Mat(contour_indices.size(), 1, CV_32FC2);
+ landmark_points_buffer = cv::Mat((int)contour_indices.size(), 1, CV_32FC2);
- mat3dcontour = (cv::Mat_(contour_indices.size(), 3) <<
+ mat3dcontour = (cv::Mat_((int)contour_indices.size(), 3) <<
0.45517698, -0.30089578, 0.76442945,
0.44899884, -0.16699584, 0.76514298,
0.43743154, -0.02265548, 0.73926717,
@@ -102,15 +103,44 @@ PositionSolver::PositionSolver(
// https://github.com/opentrack/opentrack/blob/3cc3ef246ad71c463c8952bcc96984b25d85b516/tracker-aruco/ftnoir_tracker_aruco.cpp#L193
// Taking into account the camera FOV instead of assuming raw image dims is more clever and
// will make the solver more camera-agnostic.
- float diag_fov = fov * TO_RAD;
+ float diag_fov = (float)(fov * TO_RAD);
// Get expressed in sensor-size units
+ #ifdef USE_FOV
+ // field of view is a rectangular viewport with corners on a circular lens
+ // the diagonal of the rectangle can be expressed as the angular field of view or pixels
+ // the width of the rectangle can be expressed as either the field of view width or width in pixels
+ // the height of the rectangle can be expressed as either the field of view height or height in pixes
+ double width_squared = (double)width * width;
+ double height_squared = (double)height * height;
+ double diagonal_squared = width_squared + height_squared;
+ double diagonal = sqrt(diagonal_squared); // hypotenuse of triangle
+
+ // set default focalLength for width and heigh if field of view is not set
+ double focalLength_width = width;
+ double focalLength_height = height;
+ if (fov != 0.0)
+ {
+ double fov_w = (double)diag_fov * width / diagonal;
+ double fov_h = (double)diag_fov * height / diagonal;
+
+ focalLength_width = 0.5 * width / tan(0.5 * fov_w);
+ focalLength_height = 0.5 * height / tan(0.5 * fov_h);
+ }
+
+ camera_matrix = (cv::Mat_(3, 3) <<
+ focalLength_height, 0, height / 2,
+ 0, focalLength_width, width / 2,
+ 0, 0, 1
+ );
+
+ #else
double fov_w = 2. * atan(tan(diag_fov / 2.) / sqrt(1. + height / (double)width * height / (double)width));
double fov_h = 2. * atan(tan(diag_fov / 2.) / sqrt(1. + width / (double)height * width / (double)height));
- float i_height = .5 * height / (tan(.5*fov_w));
- float i_width = .5* width / (tan(.5*fov_h));
+ float i_height = (float)(0.5f * height / (tan(0.5 * fov_w)));
+ float i_width = (float)(0.5f * width / (tan(0.5 * fov_h)));
/*camera_matrix = (cv::Mat_(3, 3) <<
height, 0, height / 2,
@@ -122,7 +152,10 @@ PositionSolver::PositionSolver(
i_width, 0, height / 2,
0, i_height, width / 2,
0, 0, 1
- );
+ );
+
+
+ #endif
camera_distortion = (cv::Mat_(4, 1) << 0, 0, 0, 0);
@@ -131,6 +164,7 @@ PositionSolver::PositionSolver(
if(complex) std::cout << "Using complex solver" << std::endl;
}
+
void PositionSolver::solve_rotation(FaceData* face_data)
{
int contour_idx = 0;
@@ -139,8 +173,7 @@ void PositionSolver::solve_rotation(FaceData* face_data)
for (int i = 0; i < contour_indices.size(); i++)
{
contour_idx = contour_indices[i];
- landmark_points_buffer.at(i, j) = (int)face_data->landmark_coords[2 * contour_idx + j];
-
+ landmark_points_buffer.at(i, j) = (float)(int)face_data->landmark_coords[2 * contour_idx + j]; // fix complation warnings.
}
}
@@ -164,15 +197,18 @@ void PositionSolver::solve_rotation(FaceData* face_data)
for (int i = 0; i < 3; i++)
{
face_data->rotation[i] = rvec.at(i, 0);
- face_data->translation[i] = tvec.at(i, 0) * 10;
+ face_data->translation[i] = tvec.at(i, 0) * 10; // scale solvePnP coordinates to opentrack units in centimeters
}
- // We dont want the Z axis oversaturated.
+ // We dont want the Z axis oversaturated since opentrack has +/-600 centimeter range
face_data->translation[2] /= 100;
- std::cout << face_data->to_string() << std::endl;
+#ifdef _DEBUG
+ std::cout << face_data->to_string() << std::endl; // disable copy constructor and output to std::cout
+#endif
correct_rotation(*face_data);
+ clip_rotations(*face_data);
}
@@ -218,14 +254,38 @@ void PositionSolver::get_euler(cv::Mat& rvec, cv::Mat& tvec)
void PositionSolver::correct_rotation(FaceData& face_data)
{
- float distance = -(face_data.translation[2]);
- float lateral_offset = face_data.translation[1];
- float verical_offset = face_data.translation[0];
+ float distance = (float) -(face_data.translation[2]);
+ float lateral_offset = (float)face_data.translation[1];
+ float verical_offset = (float)face_data.translation[0];
- float correction_yaw = std::atan(std::tan(lateral_offset / distance)) * TO_DEG;
- float correction_pitch = std::atan(std::tan(verical_offset / distance)) * TO_DEG;
+ float correction_yaw = (float)(std::atan(lateral_offset / distance) * TO_DEG); // (lateral_offset / distance) is already tangent, so only need atan to obtain radians
+ float correction_pitch = (float)(std::atan(verical_offset / distance) * TO_DEG); // (verical_offset / distance) is already tangent, so only need atan to obtain radians
face_data.rotation[1] += correction_yaw;
face_data.rotation[0] += correction_pitch;
+
+ // Note: We could saturate pitch here, but its better to let the user do it via Opentrack.
+ // The coefficient could be problematic for some users.
+ //face_data.rotation[0] = face_data.rotation[0] * 1.5;
+}
+
+
+void PositionSolver::clip_rotations(FaceData& face_data)
+{
+ // Limit yaw between -90.0 and +90.0 degrees
+ if (face_data.rotation[1] >= 90.0)
+ face_data.rotation[1] = 90.0;
+ else if (face_data.rotation[1] <= -90.0)
+ face_data.rotation[1] = -90.0;
+ // Limit pitch between -90.0 and +90.0
+ if (face_data.rotation[0] >= 90.0)
+ face_data.rotation[0] = 90.0;
+ else if (face_data.rotation[0] <= -90.0)
+ face_data.rotation[0] = -90.0;
+ // Limit roll between -90.0 and +90.0
+ if (face_data.rotation[2] >= 90.0)
+ face_data.rotation[2] = 90.0;
+ else if (face_data.rotation[2] <= -90.0)
+ face_data.rotation[2] = -90.0;
}
diff --git a/AITracker/src/PositionSolver.h b/AITracker/src/PositionSolver.h
index 1f3bd2b..cd9e78e 100644
--- a/AITracker/src/PositionSolver.h
+++ b/AITracker/src/PositionSolver.h
@@ -1,7 +1,7 @@
#pragma once
#include "opencv2/core/matx.hpp"
-#include "opencv.hpp"
+#include "opencv2/opencv.hpp"
#include "data.h"
/**
@@ -68,5 +68,12 @@ class PositionSolver
* This method corrects them.
*/
void correct_rotation(FaceData& face_data);
+
+
+ /**
+ * Ensures all rotations are in -90/90 range.
+ * (No human head can rotate more supposing camera view is frontal).
+ */
+ void clip_rotations(FaceData& face_data);
};
diff --git a/AITracker/src/data.cpp b/AITracker/src/data.cpp
index b92f58d..95b3c47 100644
--- a/AITracker/src/data.cpp
+++ b/AITracker/src/data.cpp
@@ -9,7 +9,6 @@ FaceData::FaceData():
face_detected = false;
}
-
std::string FaceData::to_string()
{
std::string datastring =
@@ -21,7 +20,7 @@ std::string FaceData::to_string()
std::string(" X: ") +
std::to_string(this->translation[0]) + ", Y: " +
std::to_string(this->translation[1]) + ", Z: " +
- std::to_string(this->translation[2]) ;
+ std::to_string(this->translation[2]);
return datastring;
}
diff --git a/AITracker/src/filters.cpp b/AITracker/src/filters.cpp
index bd6bd5b..33df811 100644
--- a/AITracker/src/filters.cpp
+++ b/AITracker/src/filters.cpp
@@ -1,37 +1,57 @@
#include "filters.h"
-
#include
+#include
+
MAFilter::MAFilter(int steps, int array_size)
{
this->n_steps = steps;
this->array_size = array_size;
- this->idx = 0;
+ this->idx = 0; // this->idx < this->n_steps
- this->circular_buffer = new float[steps * array_size];
+ this->circular_buffer = (float *)new float[steps * array_size]; // float[steps][array_size]
+ this->sum = (float *)new float[array_size]; // use this array to cache the sum
+ for (int i = 0; i < array_size; i++)
+ this->sum[i] = nanf("");
}
MAFilter::~MAFilter()
{
delete[] this->circular_buffer;
+ delete[] this->sum;
}
void MAFilter::filter(float* in_array, float* out_array)
{
int offset = this->idx * this->array_size;
+ // equivalent to:
+ // typedef float (*CIRCULAR_BUFFER_IDX)[this->array_size];
+ // typedef float (*CIRCULAR_BUFFER)[this->n_steps][this->array_size];
+ float *circular_buffer_idx = &this->circular_buffer[offset]; // CIRCULAR_BUFFER_IDX circular_buffer_idx = &((CIRCULAR_BUFFER)this->circular_buffer)[this->idx][0];
+
for (int i = 0; i < this->array_size; i++)
{
- // Insert current position
- this->circular_buffer[offset + i] = in_array[i];
- out_array[i] = 0;
-
- // get mean of all steps for this position
- for (int j = 0; j < this->n_steps; j++)
+ if (isnan(this->sum[i]))
{
- out_array[i] += this->circular_buffer[j * this->array_size + i];
+ // initialize sum
+ this->sum[i] = in_array[i] * this->n_steps;
+ // calculate average
+ out_array[i] = this->sum[i] / this->n_steps;
+ // initialize empty circular_buffer with new value
+ for (int j = 0; j < this->n_steps; j++)
+ {
+ this->circular_buffer[j * this->array_size + i] = in_array[i];
+ }
+ }
+ else
+ {
+ // Recalculate sum by subtracting old value and adding new value
+ this->sum[i] = this->sum[i] - circular_buffer_idx[i] + in_array[i];
+ // calculate average
+ out_array[i] = this->sum[i] / this->n_steps;
+ // Insert current position
+ circular_buffer_idx[i] = in_array[i];
}
-
- out_array[i] /= this->n_steps;
}
this->idx = (this->idx + 1) % this->n_steps;
@@ -56,7 +76,7 @@ void EAFilter::filter(float* in_array, float* out_array)
{
for (int i = 0; i < array_size; i++)
{
- out_array[i] = 0.6 * in_array[i] + 0.4 * this->last_value[i];
+ out_array[i] = (0.6f * in_array[i] + 0.4f * this->last_value[i]);
this->last_value[i] = in_array[i];
}
diff --git a/AITracker/src/filters.h b/AITracker/src/filters.h
index a9745b2..4b23545 100644
--- a/AITracker/src/filters.h
+++ b/AITracker/src/filters.h
@@ -16,8 +16,7 @@ class MAFilter : public IFilter
int n_steps;
float *circular_buffer;
-
-
+ float *sum;
public:
MAFilter(int steps, int array_size);
@@ -34,8 +33,6 @@ class EAFilter : public IFilter
int array_size;
float* last_value;
-
-
public:
EAFilter(int array_size);
~EAFilter();
diff --git a/AITracker/src/imageprocessor.cpp b/AITracker/src/imageprocessor.cpp
index 03b5137..416d857 100644
--- a/AITracker/src/imageprocessor.cpp
+++ b/AITracker/src/imageprocessor.cpp
@@ -13,27 +13,19 @@ ImageProcessor::ImageProcessor() :
void ImageProcessor::normalize(cv::Mat& image)
{
cv::divide(image, std_scaling, image);
-
- /*float* ptr = image.ptr();
- for (int channel = 0; channel < 3; channel++){
- for (int i = 0; i < 224 * 224; i++) {
- ptr[224*224*channel + i] /= std_scaling[channel];
- }
- }*/
-
cv::subtract(image, mean_scaling, image);
}
-/*void ImageProcessor::cvt_format(float* from, float* dest, int dim_x, int dim_y)
+void ImageProcessor::cvt_format(float* from, float* dest, int dim_x, int dim_y)
{
for (int channel = 1; channel < 4; channel++)
{
- for (int row = 0; row < 224; row++)
+ for (int row = 0; row < dim_x; row++)
{
- for (int col = 0; col < 224; col++)
+ for (int col = 0; col < dim_y; col++)
{
- dest[((channel - 1) * 224 * 224) + (224 * col + row)] = from[3 * (224 * col + row)];
+ dest[((channel - 1) * dim_x * dim_y) + (dim_y * col + row)] = from[3 * (dim_y * col + row)];
}
}
}
@@ -41,43 +33,38 @@ void ImageProcessor::normalize(cv::Mat& image)
void ImageProcessor::transpose(float* from, float* dest, int dim_x, int dim_y)
{
- int stride = 224 * 224;
+ int stride = dim_x * dim_y;
for (int c = 0; c < 3; c++)
{
- for (int i = 0; i < 224 * 224; i++)
- {
- dest[i + stride*c] = from[c + i*3];
- }
- }
-}*/
-
-
-void ImageProcessor::cvt_format(float* from, float* dest, int dim_x, int dim_y)
-{
- for (int channel = 1; channel < 4; channel++)
- {
- for (int row = 0; row < dim_x; row++)
+ float * from_by_channel = &from[c];
+ float * dest_by_channel = &dest[stride * c];
+ for (int i = 0; i < stride; i++)
{
- for (int col = 0; col < dim_y; col++)
- {
- dest[((channel - 1) * dim_x * dim_y) + (dim_y * col + row)] = from[3 * (dim_y * col + row)];
- }
+ dest_by_channel[i] = from_by_channel[i*3];
}
}
}
-void ImageProcessor::transpose(float* from, float* dest, int dim_x, int dim_y)
+
+void ImageProcessor::normalize_and_transpose(cv::Mat& image, float* dest, int dim_x, int dim_y)
{
- int stride = dim_x * dim_y;
+ const int stride = dim_x * dim_y;
- for (int c = 0; c < 3; c++)
+ // combine normalize and transpose methods to reduce for loops
+ float* from = (float*)image.data;
+ for (int channel = 0; channel < 3; channel++)
{
- for (int i = 0; i < dim_x * dim_y; i++)
+ float std_scaline_for_channel = (float)std_scaling[channel];
+ float mean_scaling_for_channel = (float)mean_scaling[channel];
+
+ for (int i = 0; i < stride; i++)
{
- dest[i + stride*c] = from[c + i*3];
+ float& from_reference = from[channel + i * 3]; // use a reference to reduce indexing
+ from_reference /= std_scaline_for_channel; /* remove internal for for loop of cv::divide(image, std_scaling, image); */
+ from_reference -= mean_scaling_for_channel; /* remove internal for for loop of cv::subtract(image, mean_scaling, image); */
+
+ dest[stride * channel + i] = from_reference; /* transpose */
}
}
}
-
-
diff --git a/AITracker/src/imageprocessor.h b/AITracker/src/imageprocessor.h
index a4c0c81..65e8ec7 100644
--- a/AITracker/src/imageprocessor.h
+++ b/AITracker/src/imageprocessor.h
@@ -1,14 +1,20 @@
#pragma once
-#include "opencv.hpp"
+#include "opencv2/opencv.hpp"
class ImageProcessor
{
public:
ImageProcessor();
void normalize(cv::Mat& image);
- void cvt_format(float* from, float* dest, int dim_x = 224, int dim_y=224);
- void transpose(float* from, float* dest, int dim_x = 224, int dim_y=224);
+ void cvt_format(float* from, float* dest, int dim_x = 224, int dim_y = 224);
+ void transpose(float* from, float* dest, int dim_x = 224, int dim_y = 224);
+
+ /*
+ Alternative implementation of the normalize and transpose functions which executes the same
+ functionality in a single run. Using this processing time cuts in half.
+ */
+ void normalize_and_transpose(cv::Mat& image, float* dest, int dim_x = 224, int dim_y = 224);
private:
cv::Scalar mean_scaling, std_scaling;
diff --git a/AITracker/src/model.cpp b/AITracker/src/model.cpp
index 1371e34..b85f6d1 100644
--- a/AITracker/src/model.cpp
+++ b/AITracker/src/model.cpp
@@ -7,7 +7,6 @@
#include
-
Tracker::Tracker(std::unique_ptr&& solver, std::wstring& detection_model_path, std::wstring& landmark_model_path):
improc(),
memory_info(allocator.GetInfo()),
@@ -23,37 +22,45 @@ Tracker::Tracker(std::unique_ptr&& solver, std::wstring& detecti
session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);
session_options.SetInterOpNumThreads(1);
session_options.SetIntraOpNumThreads(1);
+ session_options.SetExecutionMode(ExecutionMode::ORT_PARALLEL);
enviro->DisableTelemetryEvents();
- session = std::make_unique(*enviro, detection_model_path.data(), session_options);
+ // Landmark detector
session_lm = std::make_unique(*enviro, landmark_model_path.data(), session_options);
+ // Face detector
+ float score_threshold = .8;
+ float nms_threshold = .3;
+ int topK = 50;
+ face_detector = cv::FaceDetectorYN::create(
+ std::string(detection_model_path.begin(), detection_model_path.end()),
+ "",
+ cv::Size(224, 224),
+ score_threshold,
+ nms_threshold,
+ topK
+ );
+
tensor_input_size = tensor_input_dims[1] * tensor_input_dims[2] * tensor_input_dims[3];
}
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);
- cv::cvtColor(img_copy, img_copy, cv::COLOR_BGR2RGB);
-
- // Normalization complexity is too high (O(mn)), better to normalize scaled images in
- // detect_face and detect_landmarks functions.
-
- detect_face(img_copy, face_data);
+ detect_face(image, face_data);
if (face_data.face_detected)
{
cv::Point p1(face_data.face_coords[0], face_data.face_coords[1]);
cv::Point p2(face_data.face_coords[2], face_data.face_coords[3]);
- cv::Mat cropped = img_copy(cv::Rect(p1, p2));
+ cv::Mat cropped = image(cv::Rect(p1, p2));
int height = face_data.face_coords[2] - face_data.face_coords[0];
int width = face_data.face_coords[3] - face_data.face_coords[1];
- float scale_x = (float)width / 224;
- float scale_y = (float)height / 224;
+ float scale_x = (float)width / 224.0f;
+ float scale_y = (float)height / 224.0f;
+
detect_landmarks(cropped, face_data.face_coords[0], face_data.face_coords[1], scale_x, scale_y, face_data);
if (filter != nullptr)
@@ -63,82 +70,73 @@ void Tracker::predict(cv::Mat& image, FaceData& face_data, const std::unique_ptr
}
}
-float logit(float p)
-{
- if (p >= 1.0)
- p = 0.99999;
- else if (p <= 0.0)
- p = 0.0000001;
- p = p / (1 - p);
- return log(p) / 16;
+float inline logit(float p)
+{
+ if (p >= 0.9999999f)
+ p = 0.9999999f;
+ else if (p <= 0.0000001f)
+ p = 0.0000001f;
+
+ p = p / (1.0f - p);
+ return log(p) / 16.0f;
}
void Tracker::detect_face(const cv::Mat& image, FaceData& face_data)
{
- cv::Mat resized;
+ cv::Mat resized, faces;
cv::resize(image, resized, cv::Size(224, 224), NULL, NULL, cv::INTER_LINEAR);
- 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);
-
-
- auto output_tensors = session->Run(Ort::RunOptions{ nullptr },
- detection_input_node_names.data(), &input_tensor, 1, detection_output_node_names.data(), 2);
-
- float* output_arr = output_tensors[0].GetTensorMutableData();
- float* maxpool_arr = output_tensors[1].GetTensorMutableData();
+ float width = (float)image.cols;
+ float height = (float)image.rows;
+ int im_width = resized.cols;
+ int im_height = resized.rows;
- cv::Mat out(4, tensor_detection_output_dims, CV_32F, output_arr);
- cv::Mat maxpool(4, tensor_detection_output_dims, CV_32F, maxpool_arr);
+ this->face_detector->detect(resized, faces);
-
- cv::Mat first(56, 56, CV_32F, out.ptr(0,0));
- cv::Mat second(56, 56, CV_32F, out.ptr(0,1));
-
- cv::Point p(-1, -1);
- cv::minMaxLoc(first, NULL, NULL, NULL, &p);
-
-
- float c = first.at(p);
- float r = second.at(p) * 2 * 56;
- int x = p.x * 4;
- int y = p.y * 4;
-
-
- face_data.face_detected = c > .7 ? true : false;
-
- if (face_data.face_detected)
+
+
+ // Get data
+ face_data.face_detected = false;
+ if (faces.rows > 0)
{
- float face[] = { x - r, y - r, 2 * r, 2 * r };
- float width = image.cols;
- float height = image.rows;
-
- face[0] *= width / 224;
- face[2] *= width / 224;
- face[1] *= height / 224;
- face[3] *= height / 224;
+ face_data.face_detected = true;
+ float x0 = faces.at(0, 0);
+ float y0 = faces.at(0, 1);
+ float face_w = faces.at(0, 2);
+ float face_h = faces.at(0, 3);
+
+
+ float w_ratio = (width / im_width);
+ float h_ratio = (height / im_height);
+
+ float x_offset = 0;//face_w * 0.01;
+ float y_offset = 0;// face_h * 0.01;
+
+ float face[] = {
+ ((x0 - x_offset) * (w_ratio) ),
+ ((y0 - y_offset) * (h_ratio) ),
+ ((face_w) * (w_ratio) ),
+ ((face_h) * (h_ratio) )
+ };
proc_face_detect(face, width, height);
- face_data.face_coords[0] = face[0];
- face_data.face_coords[1] = face[1];
- face_data.face_coords[2] = face[2];
- face_data.face_coords[3] = face[3];
+ face_data.face_coords[0] = (int)face[0];
+ face_data.face_coords[1] = (int)face[1];
+ face_data.face_coords[2] = (int)face[2];
+ face_data.face_coords[3] = (int)face[3];
+
}
-
}
-
-
void Tracker::detect_landmarks(const cv::Mat& image, int x0, int y0, float scale_x, float scale_y, FaceData& face_data)
{
cv::Mat resized;
cv::resize(image, resized, cv::Size(224, 224), NULL, NULL, cv::INTER_LINEAR);
- improc.normalize(resized);
- improc.transpose((float*)resized.data, buffer_data);
+ resized.convertTo(resized, CV_32F);
+ cv::cvtColor(resized, resized, cv::COLOR_BGR2RGB);
+ improc.normalize_and_transpose(resized, buffer_data); // combine methods
Ort::Value input_tensor = Ort::Value::CreateTensor(memory_info, buffer_data, tensor_input_size, tensor_input_dims, 4);
@@ -159,15 +157,15 @@ void Tracker::proc_face_detect(float* face, float width, float height)
float w = face[2];
float h = face[3];
- int crop_x1 = (int)(x - w * 0.09f);
- int crop_y1 = (int)(y - h * 0.450f);
- int crop_x2 = (int)(x + w + w * 0.09f);
- int crop_y2 = (int)(y + h + h * 0.450f);
+ int crop_x1 = (int)(x);
+ int crop_y1 = (int)(y);
+ int crop_x2 = (int)(x + w);
+ int crop_y2 = (int)(y + h + h * 0.1f); // force a little taller BB so the chin tends to be covered
- face[0] = std::max(0, crop_x1);
- face[1] = std::max(0, crop_y1);
- face[2] = std::min((int)width, crop_x2);
- face[3] = std::min((int)height, crop_y2);
+ face[0] = (float)std::max(0, crop_x1);
+ face[1] = (float)std::max(0, crop_y1);
+ face[2] = (float)std::min((int)width, crop_x2);
+ face[3] = (float)std::min((int)height, crop_y2);
}
@@ -179,12 +177,14 @@ void Tracker::proc_heatmaps(float* heatmaps, int x0, int y0, float scale_x, floa
int offset = heatmap_size * landmark;
int argmax = -100;
float maxval = -100;
+
+ float* landmark_heatmap = &heatmaps[offset]; // reduce indexing
for (int i = 0; i < heatmap_size; i++)
{
- if (heatmaps[offset + i] > maxval)
+ if (landmark_heatmap[i] > maxval)
{
argmax = i;
- maxval = heatmaps[offset + i];
+ maxval = landmark_heatmap[i];
}
}
@@ -192,15 +192,15 @@ void Tracker::proc_heatmaps(float* heatmaps, int x0, int y0, float scale_x, floa
int y = argmax % 28;
- float conf = heatmaps[offset + argmax];
+ // float conf = heatmaps[offset + argmax]; unreferenced local variable
float res = 223;
- int off_x = floor(res * (logit(heatmaps[66 * heatmap_size + offset + argmax])) + 0.1);
- int off_y = floor(res * (logit(heatmaps[2 * 66 * heatmap_size + offset + argmax])) + 0.1);
+ int off_x = (int)floor(res * (logit(heatmaps[66 * heatmap_size + offset + argmax])) + 0.1f);
+ int off_y = (int)floor(res * (logit(heatmaps[2 * 66 * heatmap_size + offset + argmax])) + 0.1f);
- float lm_x = (float)y0 + (float)(scale_x * (res * (float(x) / 27.) + off_x));
- float lm_y = (float)x0 + (float)(scale_y * (res * (float(y) / 27.) + off_y));
+ float lm_x = (float)y0 + (float)(scale_x * (res * (float(x) / 27.0f) + off_x));
+ float lm_y = (float)x0 + (float)(scale_y * (res * (float(y) / 27.0f) + off_y));
face_data.landmark_coords[2 * landmark] = lm_x;
face_data.landmark_coords[2 * landmark + 1] = lm_y;
diff --git a/AITracker/src/model.h b/AITracker/src/model.h
index 320d200..a7a2804 100644
--- a/AITracker/src/model.h
+++ b/AITracker/src/model.h
@@ -1,12 +1,15 @@
#pragma once
-#include "opencv.hpp"
+#include "opencv2/opencv.hpp"
+
#include
#include "data.h"
#include "imageprocessor.h"
#include "PositionSolver.h"
#include "filters.h"
+
+
class Tracker
{
@@ -32,6 +35,7 @@ class Tracker
std::vector landmarks_input_node_names;
std::vector landmarks_output_node_names;
+ cv::Ptr face_detector;
size_t tensor_input_size;
int64_t tensor_input_dims[4] = { 1,3,224,224 };
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3f8ba81..d1eae81 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,8 +14,8 @@ SET(ONNXRUNTIME_EXTRACT_PATH "Dependencies/")
#SET(PS3Driver_URL "")
#SET(PS3Driver_PATH "")
-SET(OPENCV_URL "https://github.com/opencv/opencv/releases/download/4.3.0/opencv-4.3.0-vc14_vc15.exe")
-SET(OPENCV_PATH "${DEPS_DIR}opencv-4.3.0-vc14_vc15.exe")
+SET(OPENCV_URL "https://github.com/opencv/opencv/releases/download/4.6.0/opencv-4.6.0-vc14_vc15.exe")
+SET(OPENCV_PATH "${DEPS_DIR}opencv-4.6.0-vc14_vc15.exe")
SET(LIBUSB_URL "https://github.com/libusb/libusb/releases/download/v1.0.23/libusb-1.0.23.7z")
SET(LIBUSB_NAME "libusb-1.0.23")
diff --git a/Camera.sln b/Camera.sln
index ca44b7a..f146dfd 100644
--- a/Camera.sln
+++ b/Camera.sln
@@ -44,7 +44,7 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {8A67DE57-0604-4880-B0CC-9B96E5E3EFCD}
Qt5Version = $(DefaultQtVersion)
+ SolutionGuid = {8A67DE57-0604-4880-B0CC-9B96E5E3EFCD}
EndGlobalSection
EndGlobal
diff --git a/Client/Client.vcxproj b/Client/Client.vcxproj
index 5bb37b0..8fcd8d8 100644
--- a/Client/Client.vcxproj
+++ b/Client/Client.vcxproj
@@ -78,7 +78,7 @@
$(Qt_LIBPATH_);$(SolutionDir)Dependencies\libusb\MS64\static;$(SolutionDir)Dependencies\OpenCV\lib;$(SolutionDir)Dependencies\spdlog\lib\;$(SolutionDir)Dependencies\onnxruntime\lib\;%(AdditionalLibraryDirectories)
- $(Qt_LIBS_);opencv_world430.lib;onnxruntime.lib;Ws2_32.lib;libusb-1.0.lib;legacy_stdio_definitions.lib;%(AdditionalDependencies)
+ $(Qt_LIBS_);opencv_world460.lib;onnxruntime.lib;Ws2_32.lib;libusb-1.0.lib;legacy_stdio_definitions.lib;%(AdditionalDependencies)
true
true
@@ -104,7 +104,7 @@
$(Qt_LIBPATH_);$(SolutionDir)Dependencies\libusb\MS64\static;$(SolutionDir)Dependencies\OpenCV\lib;$(SolutionDir)Dependencies\onnxruntime\lib\;%(AdditionalLibraryDirectories)
- $(Qt_LIBS_);opencv_world430d.lib;onnxruntime.lib;Ws2_32.lib;legacy_stdio_definitions.lib;libusb-1.0.lib;%(AdditionalDependencies)
+ $(Qt_LIBS_);opencv_world460d.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\;$(ProjectDir)Vendor\spdlog\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)
@@ -155,12 +155,12 @@
true
true
None
- Disabled
+ MaxSpeed
MultiThreadedDLL
Console
- true
+ false
diff --git a/Client/src/Main.cpp b/Client/src/Main.cpp
index 25dfda6..3d9111f 100644
--- a/Client/src/Main.cpp
+++ b/Client/src/Main.cpp
@@ -21,10 +21,6 @@
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);
-
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
@@ -45,16 +41,26 @@ int main(int argc, char *argv[])
logger->info(" ---------- AITRACK LOG ----------");
+ auto conf_mgr = std::make_unique("./prefs.ini");
+ logger->info("Created/Found prefs.ini");
+
+ auto state = conf_mgr->getConfig();
+ if (state.onnx_set_env_threads) {
+ std::wstring ws = std::to_wstring(state.onnx_env_threads);
+ SetEnvironmentVariable(LPWSTR(L"OMP_NUM_THREADS"), ws.c_str());
+ }
+ if (state.onnx_set_num_threads) {
+ omp_set_num_threads(state.onnx_num_threads);
+ }
+ if (state.onnx_set_dynamic) {
+ omp_set_dynamic(state.onnx_dynamic);
+ }
QApplication app(argc, argv);
WindowMain w;
w.show();
-
- auto conf_mgr = std::make_unique("./prefs.ini");
- logger->info("Created/Found prefs.ini");
-
auto t_factory = std::make_unique("./models/");
Presenter p((IView&)w, std::move(t_factory), std::move(conf_mgr));
diff --git a/Client/src/camera/OCVCamera.h b/Client/src/camera/OCVCamera.h
index 2d1e0bd..81492b5 100644
--- a/Client/src/camera/OCVCamera.h
+++ b/Client/src/camera/OCVCamera.h
@@ -1,6 +1,6 @@
#pragma once
#include "Camera.h"
-#include "opencv.hpp"
+#include "opencv2/opencv.hpp"
class OCVCamera : public Camera
{
diff --git a/Client/src/model/Config.cpp b/Client/src/model/Config.cpp
index e4c652c..dd72360 100644
--- a/Client/src/model/Config.cpp
+++ b/Client/src/model/Config.cpp
@@ -17,16 +17,23 @@ ConfigData ConfigData::getGenericConfig()
conf.num_cameras_detected = 0;
conf.video_width = -1;
conf.video_height = -1;
- conf.video_fps = -1;
+ conf.video_fps = 30;
conf.use_landmark_stab = true;
conf.autocheck_updates = true;
conf.tracking_shortcut_enabled = false;
conf.x, conf.y, conf.z, conf.pitch, conf.yaw, conf.roll = 0;
conf.cam_exposure = -1;
conf.cam_gain = -1;
+ conf.onnx_set_env_threads = true;
+ conf.onnx_env_threads = 1;
+ conf.onnx_set_num_threads = true;
+ conf.onnx_num_threads = 1;
+ conf.onnx_set_dynamic = true;
+ conf.onnx_dynamic = 0;
conf.head_scale_x = 1.0;
conf.head_scale_y = 1.0;
conf.head_scale_z = 1.0;
+
return conf;
}
@@ -59,10 +66,19 @@ void ConfigMgr::updateConfig(const ConfigData& data)
conf.setValue("cam_gain", data.cam_gain);
conf.setValue("selected_camera", data.selected_camera);
conf.setValue("autocheck_updates", data.autocheck_updates);
+
+ conf.setValue("onnx_set_env_threads", data.onnx_set_env_threads);
+ conf.setValue("onnx_env_threads", data.onnx_env_threads);
+ conf.setValue("onnx_set_num_threads", data.onnx_set_num_threads);
+ conf.setValue("onnx_num_threads", data.onnx_num_threads);
+ conf.setValue("onnx_set_dynamic", data.onnx_set_dynamic);
+ conf.setValue("onnx_dynamic", data.onnx_dynamic);
+
conf.setValue("head_3d_scale_x", data.head_scale_x);
conf.setValue("head_3d_scale_y", data.head_scale_y);
conf.setValue("head_3d_scale_z", data.head_scale_z);
conf.setValue("tracking_shortcut_enabled", data.tracking_shortcut_enabled);
+
}
ConfigData ConfigMgr::getConfig()
@@ -82,10 +98,17 @@ ConfigData ConfigMgr::getConfig()
c.cam_exposure= conf.value("cam_exposure", -1).toInt();
c.cam_gain = conf.value("cam_gain", -1).toInt();
c.autocheck_updates = conf.value("autocheck_updates", 1).toBool();
+ c.onnx_set_env_threads = conf.value("set_env_threads", true).toBool();
+ c.onnx_env_threads = conf.value("env_threads", 1).toInt();
+ c.onnx_set_num_threads = conf.value("set_num_threads", true).toBool();
+ c.onnx_num_threads = conf.value("num_threads", 1).toInt();
+ c.onnx_set_dynamic = conf.value("set_dynamic", true).toBool();
+ c.onnx_dynamic = conf.value("dynamic", 0).toInt();
c.head_scale_x = conf.value("head_3d_scale_x", 1.0).toDouble();
c.head_scale_y = conf.value("head_3d_scale_y", 1.0).toDouble();
c.head_scale_z = conf.value("head_3d_scale_z", 1.0).toDouble();
c.tracking_shortcut_enabled= conf.value("tracking_shortcut_enabled", false).toBool();
+
return c;
}
diff --git a/Client/src/model/Config.h b/Client/src/model/Config.h
index fc37a03..1a2f279 100644
--- a/Client/src/model/Config.h
+++ b/Client/src/model/Config.h
@@ -30,6 +30,13 @@ struct ConfigData
int cam_exposure;
int cam_gain;
+ bool onnx_set_env_threads;
+ int onnx_env_threads;
+ bool onnx_set_num_threads;
+ int onnx_num_threads;
+ bool onnx_set_dynamic;
+ int onnx_dynamic;
+
std::vector model_names;
int selected_model;
diff --git a/Client/src/model/UDPSender.cpp b/Client/src/model/UDPSender.cpp
index 6798495..15d5f29 100644
--- a/Client/src/model/UDPSender.cpp
+++ b/Client/src/model/UDPSender.cpp
@@ -4,27 +4,54 @@
UDPSender::UDPSender(const char* dest_ip, int dest_port)
{
-
this->ip = std::string(dest_ip);
this->port = dest_port;
+
//std::cout << "ip: " << this->ip << " port: " << this->port << std::endl;
- dest = sockaddr_in();
- local = sockaddr_in();
-
WSAStartup(MAKEWORD(2, 2), &data);
- local.sin_family = AF_INET;
- inet_pton(AF_INET, dest_ip, &local.sin_addr.s_addr);
- local.sin_port = htons(0);
- dest.sin_family = AF_INET;
- inet_pton(AF_INET, dest_ip, &dest.sin_addr.s_addr);
- dest.sin_port = htons(dest_port);
+ memset(&dest_IPv6, 0, sizeof(dest_IPv6));
+ memset(&local_IPv6, 0, sizeof(local_IPv6));
+
+ if (inet_pton(AF_INET6, dest_ip, &dest_IPv6.sin6_addr) == 1)
+ {
+ // valid IPv6 address
+ this->s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+
+ dest_IPv6.sin6_family = AF_INET6;
+ dest_IPv6.sin6_port = htons(dest_port);
+ local_IPv6.sin6_addr = IN6ADDR_ANY_INIT;
+ local_IPv6.sin6_family = AF_INET6;
+ local_IPv6.sin6_port = htons(0);
+
+ //local_IPv6.sin6_addr = IN6ADDR_ANY_INIT;
+ bind(s, (sockaddr*)&local_IPv6, sizeof(local_IPv6));
+ }
+ else if (inet_pton(AF_INET, dest_ip, &dest.sin_addr) == 1)
+ {
+ // valid IPv4 address
+ this->s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+ dest.sin_family = AF_INET;
+ dest.sin_port = htons(dest_port);
+
+ local.sin_family = AF_INET;
+ local.sin_port = htons(0);
+ //local.sin_addr.S_un.S_addr = INADDR_ANY;
+ bind(s, (sockaddr*)&local, sizeof(local));
+ }
+ else
+ {
+ // In case of invalid address better mark this sender as invalid
+ // and not use loopback. User of this class hould know whether he/she
+ // has made a mistake.
+ this->valid = false;
+ std::cout << "Invalid IP Address" << std::endl;
+ }
- s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- bind(s, (sockaddr*)&local, sizeof(local));
}
UDPSender::~UDPSender()
diff --git a/Client/src/model/UDPSender.h b/Client/src/model/UDPSender.h
index d46b4aa..bb68e92 100644
--- a/Client/src/model/UDPSender.h
+++ b/Client/src/model/UDPSender.h
@@ -2,9 +2,11 @@
#include
#include
+#include
#include
+
/**
Data sender to Opentrack using UDP
*/
@@ -14,8 +16,16 @@ class UDPSender
const int BUFFER_SIZE = sizeof(double) * 6;
double position_data[6];
- sockaddr_in dest;
- sockaddr_in local;
+ union
+ {
+ sockaddr_in dest;
+ sockaddr_in6 dest_IPv6;
+ };
+ union
+ {
+ sockaddr_in local;
+ sockaddr_in6 local_IPv6;
+ };
WSAData data;
SOCKET s;
@@ -23,6 +33,7 @@ class UDPSender
public:
std::string ip;
int port;
+ bool valid = true;
UDPSender(const char* dest_ip, int dest_port);
~UDPSender();
diff --git a/Client/src/presenter/presenter.cpp b/Client/src/presenter/presenter.cpp
index d91bf12..9b780fe 100644
--- a/Client/src/presenter/presenter.cpp
+++ b/Client/src/presenter/presenter.cpp
@@ -3,7 +3,7 @@
#include
#include "presenter.h"
-#include "opencv.hpp"
+#include "opencv2/opencv.hpp"
#include "../camera/CameraFactory.h"
@@ -209,7 +209,7 @@ void Presenter::run_loop()
}
cv::Point p1(d.face_coords[0], d.face_coords[1]);
cv::Point p2(d.face_coords[2], d.face_coords[3]);
- cv::rectangle(mat, p1, p2, color_blue, 1);
+ cv::rectangle(mat, p1, p2, color_blue, 2);
}
update_tracking_data(d);
diff --git a/Client/src/version.h b/Client/src/version.h
index 6ef866d..acf28c9 100644
--- a/Client/src/version.h
+++ b/Client/src/version.h
@@ -1,3 +1,3 @@
#pragma once
-#define AITRACK_VERSION "v0.6.5-alpha"
\ No newline at end of file
+#define AITRACK_VERSION "v0.6.6-alpha"
\ No newline at end of file
diff --git a/Client/src/view/ConfigWindow.cpp b/Client/src/view/ConfigWindow.cpp
index d06240a..4b84da6 100644
--- a/Client/src/view/ConfigWindow.cpp
+++ b/Client/src/view/ConfigWindow.cpp
@@ -1,4 +1,5 @@
#include "ConfigWindow.h"
+#include
ConfigWindow::ConfigWindow(IRootView *prev_window, QWidget *parent)
: QWidget(parent)
@@ -77,6 +78,11 @@ ConfigData ConfigWindow::get_inputs()
conf.autocheck_updates = check_auto_update->isChecked();
conf.tracking_shortcut_enabled = check_enable_tracking_shortcut->isChecked();
+ if (conf.ip.length() == 0)
+ conf.ip = std::string("127.0.0.1"); /* default to loopback IPv4 on same computer */
+ if (conf.port == 0)
+ conf.port = 4242; /* default to opentrack port */
+
return conf;
}
diff --git a/Client/src/view/WindowMain.h b/Client/src/view/WindowMain.h
index 6b9d3f3..2fb692c 100644
--- a/Client/src/view/WindowMain.h
+++ b/Client/src/view/WindowMain.h
@@ -6,7 +6,7 @@
#include
-#include "opencv.hpp"
+#include "opencv2/opencv.hpp"
#include "../presenter/i_presenter.h"
#include "ui_MainWindow.h"
diff --git a/Client/src/view/i_view.h b/Client/src/view/i_view.h
index 4f4d29f..d9a2429 100644
--- a/Client/src/view/i_view.h
+++ b/Client/src/view/i_view.h
@@ -1,7 +1,7 @@
#pragma once
-#include "opencv.hpp"
+#include "opencv2/opencv.hpp"
#include "../model/Config.h"
#include "../presenter/i_presenter.h"
diff --git a/PS3Driver/src/ps3eye.cpp b/PS3Driver/src/ps3eye.cpp
index f661c92..e039b13 100644
--- a/PS3Driver/src/ps3eye.cpp
+++ b/PS3Driver/src/ps3eye.cpp
@@ -189,7 +189,7 @@ static const uint8_t ov772x_reg_initdata[][2] = {
{ 0x11, 0x00 },
{ 0x0D, 0x41 },
- { 0x8E, 0x00 }, // De-noise threshold - jfrancois 0x00 - orig 0x04
+ { 0x8E, 0x00 } // De-noise threshold - jfrancois 0x00 - orig 0x04
};
static const uint8_t bridge_start_vga[][2] = {
@@ -201,7 +201,7 @@ static const uint8_t bridge_start_vga[][2] = {
{0x1d, 0x2C}, /* frame size */
{0x1d, 0x00}, /* frame size */
{0xc0, 0x50},
- {0xc1, 0x3c},
+ {0xc1, 0x3c}
};
static const uint8_t sensor_start_vga[][2] = {
{0x12, 0x01},
@@ -211,7 +211,7 @@ static const uint8_t sensor_start_vga[][2] = {
{0x1a, 0xf0},
{0x29, 0xa0},
{0x2c, 0xf0},
- {0x65, 0x20},
+ {0x65, 0x20}
};
static const uint8_t bridge_start_qvga[][2] = {
{0x1c, 0x00},
@@ -222,7 +222,7 @@ static const uint8_t bridge_start_qvga[][2] = {
{0x1d, 0x4b}, /* frame size */
{0x1d, 0x00}, /* frame size */
{0xc0, 0x28},
- {0xc1, 0x1e},
+ {0xc1, 0x1e}
};
static const uint8_t sensor_start_qvga[][2] = {
{0x12, 0x41},
@@ -232,7 +232,7 @@ static const uint8_t sensor_start_qvga[][2] = {
{0x1a, 0x78},
{0x29, 0x50},
{0x2c, 0x78},
- {0x65, 0x2f},
+ {0x65, 0x2f}
};
/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
@@ -812,10 +812,12 @@ class URBDesc
USBMgr::instance()->cameraStopped();
- free(transfer_buffer);
+ if (transfer_buffer)
+ free(transfer_buffer);
transfer_buffer = NULL;
- delete frame_queue;
+ if (frame_queue)
+ delete frame_queue;
frame_queue = NULL;
}
@@ -826,7 +828,7 @@ class URBDesc
num_active_transfers_condition.notify_one();
}
- void frame_add(enum gspca_packet_type packet_type, const uint8_t *data, int len)
+ void inline frame_add(enum gspca_packet_type packet_type, const uint8_t *data, int len)
{
if (packet_type == FIRST_PACKET)
{
@@ -1312,7 +1314,7 @@ uint16_t PS3EYECam::ov534_set_frame_rate(uint16_t frame_rate, bool dry_run)
{8, 0x02, 0x01, 0x02},
{5, 0x04, 0x01, 0x02},
{3, 0x06, 0x01, 0x02},
- {2, 0x09, 0x01, 0x02},
+ {2, 0x09, 0x01, 0x02}
};
static const struct rate_s rate_1[] = { /* 320x240 */
{290, 0x00, 0xc1, 0x04},
@@ -1336,7 +1338,7 @@ uint16_t PS3EYECam::ov534_set_frame_rate(uint16_t frame_rate, bool dry_run)
{7, 0x04, 0x01, 0x04},
{5, 0x06, 0x01, 0x04},
{3, 0x09, 0x01, 0x04},
- {2, 0x18, 0x01, 0x02},
+ {2, 0x18, 0x01, 0x02}
};
if (frame_width == 640) {
@@ -1362,24 +1364,25 @@ uint16_t PS3EYECam::ov534_set_frame_rate(uint16_t frame_rate, bool dry_run)
return r->fps;
}
-void PS3EYECam::ov534_reg_write(uint16_t reg, uint8_t val)
+void inline PS3EYECam::ov534_reg_write(uint16_t reg, uint8_t val)
{
int ret;
//debug("reg=0x%04x, val=0%02x", reg, val);
- usb_buf[0] = val;
+ // usb_buf[0] = val;
+
+ ret = libusb_control_transfer(handle_,
+ LIBUSB_ENDPOINT_OUT |
+ LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
+ 0x01, 0x00, reg,
+ &val, 1, 500);
- ret = libusb_control_transfer(handle_,
- LIBUSB_ENDPOINT_OUT |
- LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
- 0x01, 0x00, reg,
- usb_buf, 1, 500);
if (ret < 0) {
debug("write failed\n");
}
}
-uint8_t PS3EYECam::ov534_reg_read(uint16_t reg)
+uint8_t inline PS3EYECam::ov534_reg_read(uint16_t reg)
{
int ret;
@@ -1396,7 +1399,7 @@ uint8_t PS3EYECam::ov534_reg_read(uint16_t reg)
return usb_buf[0];
}
-int PS3EYECam::sccb_check_status()
+int inline PS3EYECam::sccb_check_status()
{
uint8_t data;
int i;
@@ -1419,7 +1422,7 @@ int PS3EYECam::sccb_check_status()
return 0;
}
-void PS3EYECam::sccb_reg_write(uint8_t reg, uint8_t val)
+void inline PS3EYECam::sccb_reg_write(uint8_t reg, uint8_t val)
{
//debug("reg: 0x%02x, val: 0x%02x", reg, val);
ov534_reg_write(OV534_REG_SUBADDR, reg);
@@ -1432,7 +1435,7 @@ void PS3EYECam::sccb_reg_write(uint8_t reg, uint8_t val)
}
-uint8_t PS3EYECam::sccb_reg_read(uint16_t reg)
+uint8_t inline PS3EYECam::sccb_reg_read(uint16_t reg)
{
ov534_reg_write(OV534_REG_SUBADDR, (uint8_t)reg);
ov534_reg_write(OV534_REG_OPERATION, OV534_OP_WRITE_2);
diff --git a/README.md b/README.md
index 7fe2214..cf1fbb1 100644
--- a/README.md
+++ b/README.md
@@ -63,4 +63,4 @@ Thank you!
## Acknowledgements
- [inspirit](https://github.com/inspirit), for the PS3 C++ camera library which I used during development.
-- [emilianavt](https://github.com/emilianavt/), for porting the original Pytorch pretrained models to ONNX.
+- [emilianavt](https://github.com/emilianavt/), for porting the original Pytorch pretrained landmark model to ONNX format.
diff --git a/models/detection.onnx b/models/detection.onnx
index 60bbf7a..f223594 100644
Binary files a/models/detection.onnx and b/models/detection.onnx differ