mirror of
https://gitcode.com/gh_mirrors/ope/OpenFace.git
synced 2025-12-30 13:02:30 +00:00
Removing code duplication and getting rid of some C++ warnings due to float/double and signed/unsigned mixing.
This commit is contained in:
@@ -7,7 +7,7 @@ branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- feature/no-ui-fix
|
||||
- feature/code_cleanup
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
|
||||
@@ -3,10 +3,11 @@ branches:
|
||||
only:
|
||||
- develop
|
||||
- master
|
||||
- /^feature/-.*$/
|
||||
- feature/code_cleanup
|
||||
max_jobs: 4
|
||||
configuration:
|
||||
- Release
|
||||
- Debug
|
||||
platform:
|
||||
- x64
|
||||
- Win32
|
||||
|
||||
@@ -147,7 +147,7 @@ namespace GazeAnalyser_Interop {
|
||||
|
||||
// Perform manual projection of points
|
||||
vector<cv::Point2f> imagePoints_left;
|
||||
for (int i = 0; i < points_left.size(); ++i)
|
||||
for (size_t i = 0; i < points_left.size(); ++i)
|
||||
{
|
||||
float x = points_left[i].x * fx / points_left[i].z + cx;
|
||||
float y = points_left[i].y * fy / points_left[i].z + cy;
|
||||
@@ -156,7 +156,7 @@ namespace GazeAnalyser_Interop {
|
||||
}
|
||||
|
||||
vector<cv::Point2f> imagePoints_right;
|
||||
for (int i = 0; i < points_right.size(); ++i)
|
||||
for (size_t i = 0; i < points_right.size(); ++i)
|
||||
{
|
||||
float x = points_right[i].x * fx / points_right[i].z + cx;
|
||||
float y = points_right[i].y * fy / points_right[i].z + cy;
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace UtilitiesOF {
|
||||
|
||||
std::vector<std::string> image_files_std;
|
||||
|
||||
for (size_t i = 0; i < image_files->Count; ++i)
|
||||
for (int i = 0; i < image_files->Count; ++i)
|
||||
{
|
||||
std::string image_file = msclr::interop::marshal_as<std::string>(image_files[i]);
|
||||
image_files_std.push_back(image_file);
|
||||
|
||||
@@ -55,17 +55,6 @@ namespace FaceAnalysis
|
||||
// The following two methods go hand in hand
|
||||
void ExtractSummaryStatistics(const cv::Mat_<double>& descriptors, cv::Mat_<double>& sum_stats, bool mean, bool stdev, bool max_min);
|
||||
void AddDescriptor(cv::Mat_<double>& descriptors, cv::Mat_<double> new_descriptor, int curr_frame, int num_frames_to_keep = 120);
|
||||
|
||||
//===========================================================================
|
||||
// Point set and landmark manipulation functions
|
||||
//===========================================================================
|
||||
// Using Kabsch's algorithm for aligning shapes
|
||||
//This assumes that align_from and align_to are already mean normalised
|
||||
cv::Matx22f AlignShapesKabsch2D(const cv::Mat_<float>& align_from, const cv::Mat_<float>& align_to);
|
||||
|
||||
//=============================================================================
|
||||
// Basically Kabsch's algorithm but also allows the collection of points to be different in scale from each other
|
||||
cv::Matx22f AlignShapesWithScale(cv::Mat_<float>& src, cv::Mat_<float> dst);
|
||||
|
||||
//============================================================================
|
||||
// Matrix reading functionality
|
||||
|
||||
@@ -703,7 +703,7 @@ void FaceAnalyser::ExtractAllPredictionsOfflineClass(vector<std::pair<std::strin
|
||||
// Perform a moving average of 7 frames on classifications
|
||||
int window_size = 7;
|
||||
vector<double> au_vals_tmp = au_vals;
|
||||
if(au_vals.size() > (window_size - 1) / 2)
|
||||
if((int)au_vals.size() > (window_size - 1) / 2)
|
||||
{
|
||||
for (size_t i = (window_size - 1)/2; i < au_vals.size() - (window_size - 1) / 2; ++i)
|
||||
{
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
#include <Face_utils.h>
|
||||
|
||||
#include <RotationHelpers.h>
|
||||
|
||||
// OpenCV includes
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
@@ -131,7 +133,7 @@ namespace FaceAnalysis
|
||||
extract_rigid_points(source_landmarks, destination_landmarks);
|
||||
}
|
||||
|
||||
cv::Matx22f scale_rot_matrix = AlignShapesWithScale(source_landmarks, destination_landmarks);
|
||||
cv::Matx22f scale_rot_matrix = Utilities::AlignShapesWithScale(source_landmarks, destination_landmarks);
|
||||
cv::Matx23f warp_matrix;
|
||||
|
||||
warp_matrix(0,0) = scale_rot_matrix(0,0);
|
||||
@@ -170,7 +172,7 @@ namespace FaceAnalysis
|
||||
extract_rigid_points(source_landmarks, destination_landmarks);
|
||||
}
|
||||
|
||||
cv::Matx22f scale_rot_matrix = AlignShapesWithScale(source_landmarks, destination_landmarks);
|
||||
cv::Matx22f scale_rot_matrix = Utilities::AlignShapesWithScale(source_landmarks, destination_landmarks);
|
||||
cv::Matx23f warp_matrix;
|
||||
|
||||
warp_matrix(0,0) = scale_rot_matrix(0,0);
|
||||
@@ -333,88 +335,6 @@ namespace FaceAnalysis
|
||||
new_descriptor.copyTo(descriptors.row(row_to_change));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Point set and landmark manipulation functions
|
||||
//===========================================================================
|
||||
// Using Kabsch's algorithm for aligning shapes
|
||||
//This assumes that align_from and align_to are already mean normalised
|
||||
cv::Matx22f AlignShapesKabsch2D(const cv::Mat_<float>& align_from, const cv::Mat_<float>& align_to)
|
||||
{
|
||||
|
||||
cv::SVD svd(align_from.t() * align_to);
|
||||
|
||||
// make sure no reflection is there
|
||||
// corr ensures that we do only rotaitons and not reflections
|
||||
float d = cv::determinant(svd.vt.t() * svd.u.t());
|
||||
|
||||
cv::Matx22f corr = cv::Matx22f::eye();
|
||||
if (d > 0)
|
||||
{
|
||||
corr(1, 1) = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
corr(1, 1) = -1;
|
||||
}
|
||||
|
||||
cv::Matx22f R;
|
||||
cv::Mat(svd.vt.t()*cv::Mat(corr)*svd.u.t()).copyTo(R);
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Basically Kabsch's algorithm but also allows the collection of points to be different in scale from each other
|
||||
cv::Matx22f AlignShapesWithScale(cv::Mat_<float>& src, cv::Mat_<float> dst)
|
||||
{
|
||||
int n = src.rows;
|
||||
|
||||
// First we mean normalise both src and dst
|
||||
float mean_src_x = cv::mean(src.col(0))[0];
|
||||
float mean_src_y = cv::mean(src.col(1))[0];
|
||||
|
||||
float mean_dst_x = cv::mean(dst.col(0))[0];
|
||||
float mean_dst_y = cv::mean(dst.col(1))[0];
|
||||
|
||||
cv::Mat_<float> src_mean_normed = src.clone();
|
||||
src_mean_normed.col(0) = src_mean_normed.col(0) - mean_src_x;
|
||||
src_mean_normed.col(1) = src_mean_normed.col(1) - mean_src_y;
|
||||
|
||||
cv::Mat_<float> dst_mean_normed = dst.clone();
|
||||
dst_mean_normed.col(0) = dst_mean_normed.col(0) - mean_dst_x;
|
||||
dst_mean_normed.col(1) = dst_mean_normed.col(1) - mean_dst_y;
|
||||
|
||||
// Find the scaling factor of each
|
||||
cv::Mat src_sq;
|
||||
cv::pow(src_mean_normed, 2, src_sq);
|
||||
|
||||
cv::Mat dst_sq;
|
||||
cv::pow(dst_mean_normed, 2, dst_sq);
|
||||
|
||||
float s_src = sqrt(cv::sum(src_sq)[0] / n);
|
||||
float s_dst = sqrt(cv::sum(dst_sq)[0] / n);
|
||||
|
||||
src_mean_normed = src_mean_normed / s_src;
|
||||
dst_mean_normed = dst_mean_normed / s_dst;
|
||||
|
||||
float s = s_dst / s_src;
|
||||
|
||||
// Get the rotation
|
||||
cv::Matx22f R = AlignShapesKabsch2D(src_mean_normed, dst_mean_normed);
|
||||
|
||||
cv::Matx22f A;
|
||||
cv::Mat(s * R).copyTo(A);
|
||||
|
||||
cv::Mat_<float> aligned = (cv::Mat(cv::Mat(A) * src.t())).t();
|
||||
cv::Mat_<float> offset = dst - aligned;
|
||||
|
||||
float t_x = cv::mean(offset.col(0))[0];
|
||||
float t_y = cv::mean(offset.col(1))[0];
|
||||
|
||||
return A;
|
||||
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// Matrix reading functionality
|
||||
//============================================================================
|
||||
|
||||
@@ -58,19 +58,6 @@ namespace LandmarkDetector
|
||||
// templ is the template we are convolving with, templ_dfts it's dfts at varying windows sizes (optional), _result - the output, method the type of convolution
|
||||
void matchTemplate_m(const cv::Mat_<float>& input_img, cv::Mat_<double>& img_dft, cv::Mat& _integral_img, cv::Mat& _integral_img_sq, const cv::Mat_<float>& templ, map<int, cv::Mat_<double> >& templ_dfts, cv::Mat_<float>& result, int method);
|
||||
|
||||
//===========================================================================
|
||||
// Point set and landmark manipulation functions
|
||||
//===========================================================================
|
||||
// Using Kabsch's algorithm for aligning shapes
|
||||
//This assumes that align_from and align_to are already mean normalised
|
||||
cv::Matx22d AlignShapesKabsch2D(const cv::Mat_<double>& align_from, const cv::Mat_<double>& align_to);
|
||||
cv::Matx22f AlignShapesKabsch2D_f(const cv::Mat_<float>& align_from, const cv::Mat_<float>& align_to);
|
||||
|
||||
//=============================================================================
|
||||
// Basically Kabsch's algorithm but also allows the collection of points to be different in scale from each other
|
||||
cv::Matx22d AlignShapesWithScale(cv::Mat_<double>& src, cv::Mat_<double> dst);
|
||||
cv::Matx22f AlignShapesWithScale_f(cv::Mat_<float>& src, cv::Mat_<float> dst);
|
||||
|
||||
// Useful utility for grabing a bounding box around a set of 2D landmarks (as a 1D 2n x 1 vector of xs followed by doubles or as an n x 2 vector)
|
||||
void ExtractBoundingBox(const cv::Mat_<float>& landmarks, float &min_x, float &max_x, float &min_y, float &max_y);
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace LandmarkDetector
|
||||
auto iter = input_output_maps[0].row(k).begin();
|
||||
float neg_mult = prelu_weights.at<float>(k);
|
||||
|
||||
for (size_t i = 0; i < w; ++i)
|
||||
for (int i = 0; i < w; ++i)
|
||||
{
|
||||
float in_val = *iter;
|
||||
// Apply the PReLU
|
||||
@@ -105,7 +105,7 @@ namespace LandmarkDetector
|
||||
cv::Size orig_size = input_maps[0].size();
|
||||
cv::Mat_<float> input_concat((int)input_maps.size(), input_maps[0].cols * input_maps[0].rows);
|
||||
|
||||
for (int in = 0; in < input_maps.size(); ++in)
|
||||
for (int in = 0; in < (int)input_maps.size(); ++in)
|
||||
{
|
||||
cv::Mat_<float> add = input_maps[in];
|
||||
|
||||
|
||||
@@ -354,9 +354,9 @@ void CNN::Read(const string& location)
|
||||
|
||||
// Rearrange the flattened kernels into weight matrices for direct convolution computation
|
||||
cv::Mat_<float> weight_matrix(num_in_maps * kernels_rearr[0][0].rows * kernels_rearr[0][0].cols, num_kernels);
|
||||
for (size_t k = 0; k < num_kernels; ++k)
|
||||
for (int k = 0; k < num_kernels; ++k)
|
||||
{
|
||||
for (size_t i = 0; i < num_in_maps; ++i)
|
||||
for (int i = 0; i < num_in_maps; ++i)
|
||||
{
|
||||
// Flatten the kernel
|
||||
cv::Mat_<float> k_flat = kernels_rearr[k][i].t();
|
||||
@@ -370,7 +370,7 @@ void CNN::Read(const string& location)
|
||||
|
||||
// Add a bias term to the weight matrix for efficiency
|
||||
cv::Mat_<float> W(weight_matrix.rows, weight_matrix.cols + 1, 1.0);
|
||||
for (size_t k = 0; k < weight_matrix.rows; ++k)
|
||||
for (int k = 0; k < weight_matrix.rows; ++k)
|
||||
{
|
||||
W.at<float>(k, weight_matrix.cols) = biases[k];
|
||||
}
|
||||
|
||||
@@ -263,9 +263,9 @@ void DetectionValidator::Read(string location)
|
||||
|
||||
// Rearrange the flattened kernels into weight matrices for direct convolution computation
|
||||
cv::Mat_<float> weight_matrix(num_in_maps * kernels_rearr[0][0].rows * kernels_rearr[0][0].cols, num_kernels);
|
||||
for (size_t k = 0; k < num_kernels; ++k)
|
||||
for (int k = 0; k < num_kernels; ++k)
|
||||
{
|
||||
for (size_t i = 0; i < num_in_maps; ++i)
|
||||
for (int i = 0; i < num_in_maps; ++i)
|
||||
{
|
||||
// Flatten the kernel
|
||||
cv::Mat_<float> k_flat = kernels_rearr[k][i].t();
|
||||
@@ -279,7 +279,7 @@ void DetectionValidator::Read(string location)
|
||||
|
||||
// Add a bias term to the weight matrix for efficiency
|
||||
cv::Mat_<float> W(weight_matrix.rows, weight_matrix.cols + 1, 1.0);
|
||||
for (size_t k = 0; k < weight_matrix.rows; ++k)
|
||||
for (int k = 0; k < weight_matrix.rows; ++k)
|
||||
{
|
||||
W.at<float>(k, weight_matrix.cols) = biases[k];
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ bool DetectLandmarksInImageMultiHypEarlyTerm(const cv::Mat_<uchar> &grayscale_im
|
||||
|
||||
// Setup the parameters accordingly
|
||||
// Only do the first iteration
|
||||
for (int i = 1; i < params.window_sizes_current.size(); ++i)
|
||||
for (size_t i = 1; i < params.window_sizes_current.size(); ++i)
|
||||
{
|
||||
params.window_sizes_current[i] = 0;
|
||||
}
|
||||
|
||||
@@ -284,163 +284,6 @@ namespace LandmarkDetector
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
// Point set and landmark manipulation functions
|
||||
//===========================================================================
|
||||
// Using Kabsch's algorithm for aligning shapes
|
||||
//This assumes that align_from and align_to are already mean normalised
|
||||
cv::Matx22d AlignShapesKabsch2D(const cv::Mat_<double>& align_from, const cv::Mat_<double>& align_to)
|
||||
{
|
||||
|
||||
cv::SVD svd(align_from.t() * align_to);
|
||||
|
||||
// make sure no reflection is there
|
||||
// corr ensures that we do only rotaitons and not reflections
|
||||
double d = cv::determinant(svd.vt.t() * svd.u.t());
|
||||
|
||||
cv::Matx22d corr = cv::Matx22d::eye();
|
||||
if (d > 0)
|
||||
{
|
||||
corr(1, 1) = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
corr(1, 1) = -1;
|
||||
}
|
||||
|
||||
cv::Matx22d R;
|
||||
cv::Mat(svd.vt.t()*cv::Mat(corr)*svd.u.t()).copyTo(R);
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
cv::Matx22f AlignShapesKabsch2D_f(const cv::Mat_<float>& align_from, const cv::Mat_<float>& align_to)
|
||||
{
|
||||
|
||||
cv::SVD svd(align_from.t() * align_to);
|
||||
|
||||
// make sure no reflection is there
|
||||
// corr ensures that we do only rotaitons and not reflections
|
||||
float d = cv::determinant(svd.vt.t() * svd.u.t());
|
||||
|
||||
cv::Matx22f corr = cv::Matx22f::eye();
|
||||
if (d > 0)
|
||||
{
|
||||
corr(1, 1) = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
corr(1, 1) = -1;
|
||||
}
|
||||
|
||||
cv::Matx22f R;
|
||||
cv::Mat(svd.vt.t()*cv::Mat(corr)*svd.u.t()).copyTo(R);
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Basically Kabsch's algorithm but also allows the collection of points to be different in scale from each other
|
||||
cv::Matx22d AlignShapesWithScale(cv::Mat_<double>& src, cv::Mat_<double> dst)
|
||||
{
|
||||
int n = src.rows;
|
||||
|
||||
// First we mean normalise both src and dst
|
||||
double mean_src_x = cv::mean(src.col(0))[0];
|
||||
double mean_src_y = cv::mean(src.col(1))[0];
|
||||
|
||||
double mean_dst_x = cv::mean(dst.col(0))[0];
|
||||
double mean_dst_y = cv::mean(dst.col(1))[0];
|
||||
|
||||
cv::Mat_<double> src_mean_normed = src.clone();
|
||||
src_mean_normed.col(0) = src_mean_normed.col(0) - mean_src_x;
|
||||
src_mean_normed.col(1) = src_mean_normed.col(1) - mean_src_y;
|
||||
|
||||
cv::Mat_<double> dst_mean_normed = dst.clone();
|
||||
dst_mean_normed.col(0) = dst_mean_normed.col(0) - mean_dst_x;
|
||||
dst_mean_normed.col(1) = dst_mean_normed.col(1) - mean_dst_y;
|
||||
|
||||
// Find the scaling factor of each
|
||||
cv::Mat src_sq;
|
||||
cv::pow(src_mean_normed, 2, src_sq);
|
||||
|
||||
cv::Mat dst_sq;
|
||||
cv::pow(dst_mean_normed, 2, dst_sq);
|
||||
|
||||
double s_src = sqrt(cv::sum(src_sq)[0] / n);
|
||||
double s_dst = sqrt(cv::sum(dst_sq)[0] / n);
|
||||
|
||||
src_mean_normed = src_mean_normed / s_src;
|
||||
dst_mean_normed = dst_mean_normed / s_dst;
|
||||
|
||||
double s = s_dst / s_src;
|
||||
|
||||
// Get the rotation
|
||||
cv::Matx22d R = AlignShapesKabsch2D(src_mean_normed, dst_mean_normed);
|
||||
|
||||
cv::Matx22d A;
|
||||
cv::Mat(s * R).copyTo(A);
|
||||
|
||||
cv::Mat_<double> aligned = (cv::Mat(cv::Mat(A) * src.t())).t();
|
||||
cv::Mat_<double> offset = dst - aligned;
|
||||
|
||||
double t_x = cv::mean(offset.col(0))[0];
|
||||
double t_y = cv::mean(offset.col(1))[0];
|
||||
|
||||
return A;
|
||||
|
||||
}
|
||||
|
||||
cv::Matx22f AlignShapesWithScale_f(cv::Mat_<float>& src, cv::Mat_<float> dst)
|
||||
{
|
||||
int n = src.rows;
|
||||
|
||||
// First we mean normalise both src and dst
|
||||
float mean_src_x = cv::mean(src.col(0))[0];
|
||||
float mean_src_y = cv::mean(src.col(1))[0];
|
||||
|
||||
float mean_dst_x = cv::mean(dst.col(0))[0];
|
||||
float mean_dst_y = cv::mean(dst.col(1))[0];
|
||||
|
||||
cv::Mat_<float> src_mean_normed = src.clone();
|
||||
src_mean_normed.col(0) = src_mean_normed.col(0) - mean_src_x;
|
||||
src_mean_normed.col(1) = src_mean_normed.col(1) - mean_src_y;
|
||||
|
||||
cv::Mat_<float> dst_mean_normed = dst.clone();
|
||||
dst_mean_normed.col(0) = dst_mean_normed.col(0) - mean_dst_x;
|
||||
dst_mean_normed.col(1) = dst_mean_normed.col(1) - mean_dst_y;
|
||||
|
||||
// Find the scaling factor of each
|
||||
cv::Mat src_sq;
|
||||
cv::pow(src_mean_normed, 2, src_sq);
|
||||
|
||||
cv::Mat dst_sq;
|
||||
cv::pow(dst_mean_normed, 2, dst_sq);
|
||||
|
||||
float s_src = sqrt(cv::sum(src_sq)[0] / n);
|
||||
float s_dst = sqrt(cv::sum(dst_sq)[0] / n);
|
||||
|
||||
src_mean_normed = src_mean_normed / s_src;
|
||||
dst_mean_normed = dst_mean_normed / s_dst;
|
||||
|
||||
float s = s_dst / s_src;
|
||||
|
||||
// Get the rotation
|
||||
cv::Matx22f R = AlignShapesKabsch2D_f(src_mean_normed, dst_mean_normed);
|
||||
|
||||
cv::Matx22f A = s * R;
|
||||
|
||||
cv::Mat_<float> aligned = (cv::Mat(cv::Mat(A) * src.t())).t();
|
||||
cv::Mat_<float> offset = dst - aligned;
|
||||
|
||||
float t_x = cv::mean(offset.col(0))[0];
|
||||
float t_y = cv::mean(offset.col(1))[0];
|
||||
|
||||
return A;
|
||||
|
||||
}
|
||||
|
||||
// Useful utility for grabing a bounding box around a set of 2D landmarks (as a 1D 2n x 1 vector of xs followed by doubles or as an n x 2 vector)
|
||||
void ExtractBoundingBox(const cv::Mat_<float>& landmarks, float &min_x, float &max_x, float &min_y, float &max_y)
|
||||
{
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
#include "Patch_experts.h"
|
||||
|
||||
#include "RotationHelpers.h"
|
||||
|
||||
// TBB includes
|
||||
#include <tbb/tbb.h>
|
||||
|
||||
@@ -156,7 +158,7 @@ void Patch_experts::Response(vector<cv::Mat_<float> >& patch_expert_responses, c
|
||||
cv::Mat_<float> reference_shape_2D = (reference_shape.reshape(1, 2).t());
|
||||
cv::Mat_<float> image_shape_2D = landmark_locations.reshape(1, 2).t();
|
||||
|
||||
sim_img_to_ref = AlignShapesWithScale_f(image_shape_2D, reference_shape_2D);
|
||||
sim_img_to_ref = Utilities::AlignShapesWithScale(image_shape_2D, reference_shape_2D);
|
||||
sim_ref_to_img = sim_img_to_ref.inv(cv::DECOMP_LU);
|
||||
|
||||
float a1 = sim_ref_to_img(0, 0);
|
||||
@@ -461,21 +463,21 @@ bool Patch_experts::Read(vector<string> intensity_svr_expert_locations, vector<s
|
||||
}
|
||||
|
||||
// Reading in weights/biases/cutoffs
|
||||
for (int i = 0; i < centers[0].size(); ++i)
|
||||
for (size_t i = 0; i < centers[0].size(); ++i)
|
||||
{
|
||||
double weight;
|
||||
earlyTermFile >> weight;
|
||||
early_term_weights.push_back(weight);
|
||||
}
|
||||
|
||||
for (int i = 0; i < centers[0].size(); ++i)
|
||||
for (size_t i = 0; i < centers[0].size(); ++i)
|
||||
{
|
||||
double bias;
|
||||
earlyTermFile >> bias;
|
||||
early_term_biases.push_back(bias);
|
||||
}
|
||||
|
||||
for (int i = 0; i < centers[0].size(); ++i)
|
||||
for (size_t i = 0; i < centers[0].size(); ++i)
|
||||
{
|
||||
double cutoff;
|
||||
earlyTermFile >> cutoff;
|
||||
|
||||
@@ -160,5 +160,87 @@ namespace Utilities
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Point set and landmark manipulation functions
|
||||
//===========================================================================
|
||||
// Using Kabsch's algorithm for aligning shapes
|
||||
//This assumes that align_from and align_to are already mean normalised
|
||||
static cv::Matx22f AlignShapesKabsch2D(const cv::Mat_<float>& align_from, const cv::Mat_<float>& align_to)
|
||||
{
|
||||
|
||||
cv::SVD svd(align_from.t() * align_to);
|
||||
|
||||
// make sure no reflection is there
|
||||
// corr ensures that we do only rotaitons and not reflections
|
||||
double d = cv::determinant(svd.vt.t() * svd.u.t());
|
||||
|
||||
cv::Matx22f corr = cv::Matx22f::eye();
|
||||
if (d > 0)
|
||||
{
|
||||
corr(1, 1) = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
corr(1, 1) = -1;
|
||||
}
|
||||
|
||||
cv::Matx22f R;
|
||||
cv::Mat(svd.vt.t()*cv::Mat(corr)*svd.u.t()).copyTo(R);
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Basically Kabsch's algorithm but also allows the collection of points to be different in scale from each other
|
||||
static cv::Matx22f AlignShapesWithScale(cv::Mat_<float>& src, cv::Mat_<float> dst)
|
||||
{
|
||||
int n = src.rows;
|
||||
|
||||
// First we mean normalise both src and dst
|
||||
float mean_src_x = (float)cv::mean(src.col(0))[0];
|
||||
float mean_src_y = (float)cv::mean(src.col(1))[0];
|
||||
|
||||
float mean_dst_x = (float)cv::mean(dst.col(0))[0];
|
||||
float mean_dst_y = (float)cv::mean(dst.col(1))[0];
|
||||
|
||||
cv::Mat_<float> src_mean_normed = src.clone();
|
||||
src_mean_normed.col(0) = src_mean_normed.col(0) - mean_src_x;
|
||||
src_mean_normed.col(1) = src_mean_normed.col(1) - mean_src_y;
|
||||
|
||||
cv::Mat_<float> dst_mean_normed = dst.clone();
|
||||
dst_mean_normed.col(0) = dst_mean_normed.col(0) - mean_dst_x;
|
||||
dst_mean_normed.col(1) = dst_mean_normed.col(1) - mean_dst_y;
|
||||
|
||||
// Find the scaling factor of each
|
||||
cv::Mat src_sq;
|
||||
cv::pow(src_mean_normed, 2, src_sq);
|
||||
|
||||
cv::Mat dst_sq;
|
||||
cv::pow(dst_mean_normed, 2, dst_sq);
|
||||
|
||||
float s_src = (float)sqrt(cv::sum(src_sq)[0] / n);
|
||||
float s_dst = (float)sqrt(cv::sum(dst_sq)[0] / n);
|
||||
|
||||
src_mean_normed = src_mean_normed / s_src;
|
||||
dst_mean_normed = dst_mean_normed / s_dst;
|
||||
|
||||
float s = s_dst / s_src;
|
||||
|
||||
// Get the rotation
|
||||
cv::Matx22f R = AlignShapesKabsch2D(src_mean_normed, dst_mean_normed);
|
||||
|
||||
cv::Matx22f A;
|
||||
cv::Mat(s * R).copyTo(A);
|
||||
|
||||
//cv::Mat_<float> aligned = (cv::Mat(cv::Mat(A) * src.t())).t();
|
||||
//cv::Mat_<float> offset = dst - aligned;
|
||||
|
||||
//float t_x = cv::mean(offset.col(0))[0];
|
||||
//float t_y = cv::mean(offset.col(1))[0];
|
||||
|
||||
return A;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -468,7 +468,7 @@ void SequenceCapture::CaptureThread()
|
||||
}
|
||||
else if (is_image_seq)
|
||||
{
|
||||
if (image_files.empty() || frame_num_int >= image_files.size())
|
||||
if (image_files.empty() || frame_num_int >= (int)image_files.size())
|
||||
{
|
||||
// Indicate lack of success by returning an empty image
|
||||
tmp_frame = cv::Mat();
|
||||
|
||||
Reference in New Issue
Block a user