mirror of
https://gitcode.com/gh_mirrors/ope/OpenFace.git
synced 2026-05-15 03:37:49 +00:00
Another slight performance increase.
This commit is contained in:
@@ -79,8 +79,12 @@ namespace LandmarkDetector
|
||||
void Response(const cv::Mat_<float> &area_of_interest, cv::Mat_<float> &response);
|
||||
|
||||
// Faster version of the response that only considers a subset of the area_of_interest
|
||||
void ResponseSparse(const cv::Mat_<float> &area_of_interest, cv::Mat_<float> &response);
|
||||
void ResponseSparse(const cv::Mat_<float> &area_of_interest, cv::Mat_<float> &response, cv::Mat_<float>& mapMatrix);
|
||||
|
||||
|
||||
};
|
||||
|
||||
void interpolationMatrix(cv::Mat_<float>& mapMatrix, int response_height, int response_width, int input_width, int input_height);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -305,8 +305,6 @@ void im2colBiasSparseContrastNorm(const cv::Mat_<float>& input, int width, int h
|
||||
{
|
||||
for (int i = 0; i< yB; i++)
|
||||
{
|
||||
float* Mo = output.ptr<float>(rowIdx);
|
||||
|
||||
// Skip every second row
|
||||
skipCounter++;
|
||||
if ((skipCounter + 1) % 2 == 0)
|
||||
@@ -314,6 +312,8 @@ void im2colBiasSparseContrastNorm(const cv::Mat_<float>& input, int width, int h
|
||||
continue;
|
||||
}
|
||||
|
||||
float* Mo = output.ptr<float>(rowIdx);
|
||||
|
||||
float sum = 0;
|
||||
|
||||
for (unsigned int yy = 0; yy < height; ++yy)
|
||||
@@ -526,8 +526,83 @@ void im2colBiasSparse(const cv::Mat_<float>& input, int width, int height, cv::M
|
||||
// response = response.t();
|
||||
//}
|
||||
|
||||
// As the sparse patch expert output with interpolation, this function creates an interpolation matrix
|
||||
void LandmarkDetector::interpolationMatrix(cv::Mat_<float>& mapMatrix, int response_height, int response_width, int input_width, int input_height)
|
||||
{
|
||||
int m = input_height;
|
||||
int n = input_width;
|
||||
|
||||
// determine how many blocks there will be with a sliding window of width x height in the input
|
||||
int yB = m - 11 + 1;
|
||||
int xB = n - 11 + 1;
|
||||
|
||||
// As we will be skipping half of the outputs
|
||||
int out_size = (yB*xB - 1) / 2;
|
||||
|
||||
mapMatrix.create(out_size, response_height * response_width);
|
||||
mapMatrix.setTo(0.0f);
|
||||
|
||||
// Find a mapping from indices in the computed sparse response and the original full response
|
||||
cv::Mat_<int> value_id_matrix(response_width, response_height, 0);
|
||||
|
||||
int ind = 0;
|
||||
for (int k = 0; k < value_id_matrix.rows * value_id_matrix.cols; ++k)
|
||||
{
|
||||
if (k % 2 != 0)
|
||||
{
|
||||
value_id_matrix.at<int>(k) = ind;
|
||||
ind++;
|
||||
}
|
||||
}
|
||||
value_id_matrix = value_id_matrix.t();
|
||||
|
||||
int skip_counter = 0;
|
||||
for (int x = 0; x < response_width; ++x)
|
||||
{
|
||||
for (int y = 0; y < response_height; ++y)
|
||||
{
|
||||
int mapping_col = x * response_height + y;
|
||||
skip_counter++;
|
||||
if (skip_counter % 2 == 0)
|
||||
{
|
||||
int val_id = value_id_matrix.at<int>(y, x);
|
||||
mapMatrix.at<float>(val_id, mapping_col) = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
double num_neigh = 0.0;
|
||||
vector<int> val_ids;
|
||||
if (x - 1 >= 0)
|
||||
{
|
||||
num_neigh++;
|
||||
val_ids.push_back(value_id_matrix.at<int>(y, x - 1));
|
||||
}
|
||||
if (y - 1 >= 0)
|
||||
{
|
||||
num_neigh++;
|
||||
val_ids.push_back(value_id_matrix.at<int>(y - 1, x));
|
||||
}
|
||||
if (x + 1 < response_width)
|
||||
{
|
||||
num_neigh++;
|
||||
val_ids.push_back(value_id_matrix.at<int>(y, x + 1));
|
||||
}
|
||||
if (y + 1 < response_height)
|
||||
{
|
||||
num_neigh++;
|
||||
val_ids.push_back(value_id_matrix.at<int>(y + 1, x));
|
||||
}
|
||||
|
||||
for (size_t k = 0; k < val_ids.size(); ++k)
|
||||
{
|
||||
mapMatrix.at<float>(val_ids[k], mapping_col) = 1.0 / num_neigh;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CEN_patch_expert::ResponseSparse(const cv::Mat_<float> &area_of_interest, cv::Mat_<float> &response)
|
||||
void CEN_patch_expert::ResponseSparse(const cv::Mat_<float> &area_of_interest, cv::Mat_<float> &response, cv::Mat_<float>& mapMatrix)
|
||||
{
|
||||
|
||||
int response_height = area_of_interest.rows - height + 1;
|
||||
@@ -593,69 +668,9 @@ void CEN_patch_expert::ResponseSparse(const cv::Mat_<float> &area_of_interest, c
|
||||
|
||||
}
|
||||
|
||||
// Restructure the output with interpolation
|
||||
cv::Mat_<float> mapMatrix(response.rows, response_height * response_width, 0.0f); //TODO move this out
|
||||
|
||||
// Find a mapping from indices in the computed sparse response and the original full response
|
||||
cv::Mat_<int> value_id_matrix(response_width, response_height, 0);
|
||||
|
||||
int ind = 0;
|
||||
for (int k = 0; k < value_id_matrix.rows * value_id_matrix.cols; ++k)
|
||||
{
|
||||
if(k % 2 != 0)
|
||||
{
|
||||
value_id_matrix.at<int>(k) = ind;
|
||||
ind++;
|
||||
}
|
||||
}
|
||||
value_id_matrix = value_id_matrix.t();
|
||||
|
||||
int skip_counter = 0;
|
||||
for (int x = 0; x < response_width; ++x)
|
||||
{
|
||||
for (int y = 0; y < response_height; ++y)
|
||||
{
|
||||
int mapping_col = x * response_height + y;
|
||||
skip_counter++;
|
||||
if (skip_counter % 2 == 0)
|
||||
{
|
||||
int val_id = value_id_matrix.at<int>(y, x);
|
||||
mapMatrix.at<float>(val_id, mapping_col) = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
double num_neigh = 0.0;
|
||||
vector<int> val_ids;
|
||||
if (x - 1 >= 0)
|
||||
{
|
||||
num_neigh++;
|
||||
val_ids.push_back(value_id_matrix.at<int>(y, x - 1));
|
||||
}
|
||||
if (y - 1 >= 0)
|
||||
{
|
||||
num_neigh++;
|
||||
val_ids.push_back(value_id_matrix.at<int>(y - 1, x));
|
||||
}
|
||||
if (x + 1 < response_width)
|
||||
{
|
||||
num_neigh++;
|
||||
val_ids.push_back(value_id_matrix.at<int>(y, x + 1));
|
||||
}
|
||||
if (y + 1 < response_height)
|
||||
{
|
||||
num_neigh++;
|
||||
val_ids.push_back(value_id_matrix.at<int>(y+1, x));
|
||||
}
|
||||
|
||||
for (size_t k = 0; k < val_ids.size(); ++k)
|
||||
{
|
||||
mapMatrix.at<float>(val_ids[k], mapping_col) = 1.0 / num_neigh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response = response.t() * mapMatrix;
|
||||
response = response.t();
|
||||
//response = response.t() * mapMatrix;
|
||||
//response = response.t();
|
||||
response = mapMatrix * response;
|
||||
response = response.reshape(1, response_height);
|
||||
response = response.t();
|
||||
}
|
||||
|
||||
@@ -162,6 +162,19 @@ void Patch_experts::Response(vector<cv::Mat_<float> >& patch_expert_responses, c
|
||||
|
||||
}
|
||||
|
||||
// If using CEN precalculate interpolation matrix
|
||||
cv::Mat_<float> interp_mat;
|
||||
if (use_cen)
|
||||
{
|
||||
// Assuming the same size for all experts
|
||||
int support_region = 11;
|
||||
int area_of_interest_width = window_size + support_region - 1;
|
||||
int area_of_interest_height = window_size + support_region - 1;
|
||||
int resp_size = area_of_interest_height - support_region + 1;
|
||||
interpolationMatrix(interp_mat, resp_size, resp_size, area_of_interest_width, area_of_interest_height);
|
||||
interp_mat = interp_mat.t();
|
||||
}
|
||||
|
||||
// calculate the patch responses for every landmark, Actual work happens here. If openMP is turned on it is possible to do this in parallel,
|
||||
// this might work well on some machines, while potentially have an adverse effect on others
|
||||
#ifdef _OPENMP
|
||||
@@ -214,7 +227,7 @@ void Patch_experts::Response(vector<cv::Mat_<float> >& patch_expert_responses, c
|
||||
// Get intensity response either from the SVR, CCNF, or CEN patch experts (prefer CEN as they are the most accurate so far)
|
||||
if (!cen_expert_intensity.empty())
|
||||
{
|
||||
cen_expert_intensity[scale][view_id][i].ResponseSparse(area_of_interest, patch_expert_responses[i]);
|
||||
cen_expert_intensity[scale][view_id][i].ResponseSparse(area_of_interest, patch_expert_responses[i], interp_mat);
|
||||
}
|
||||
else if (!ccnf_expert_intensity.empty())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user