Commit 80d6c0cd authored by Patrik Huber's avatar Patrik Huber

Added the actual C++ fitting wrapper

Calling it works great!
No result is returned yet from C++ to Matlab.
parent a07f1c28
...@@ -17,17 +17,29 @@ ...@@ -17,17 +17,29 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#include "eos/core/LandmarkMapper.hpp"
#include "eos/morphablemodel/MorphableModel.hpp"
#include "eos/morphablemodel/Blendshape.hpp"
#include "eos/morphablemodel/EdgeTopology.hpp"
#include "eos/fitting/contour_correspondence.hpp"
#include "eos/fitting/fitting.hpp"
#include "eos/fitting/RenderingParameters.hpp"
#include "eos/render/Mesh.hpp"
#include "mexplus_eigen.hpp" #include "mexplus_eigen.hpp"
#include "mexplus.h" #include "mexplus.h"
#include "Eigen/Core" #include "Eigen/Core"
#include "opencv2/core/core.hpp"
#include "mex.h" #include "mex.h"
//#include "matrix.h" //#include "matrix.h"
#include <string> #include <string>
using namespace eos;
using namespace mexplus; using namespace mexplus;
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
...@@ -36,46 +48,54 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) ...@@ -36,46 +48,54 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// Check for proper number of input and output arguments: // Check for proper number of input and output arguments:
mexPrintf("nlhs: %d, nrhs: %d\n", nlhs, nrhs); mexPrintf("nlhs: %d, nrhs: %d\n", nlhs, nrhs);
if (nrhs != 12) { if (nrhs != 12) {
mexErrMsgIdAndTxt("eos:example:nargin", "fit_shape_and_pose requires 12 input arguments."); mexErrMsgIdAndTxt("eos:fitting:nargin", "fit_shape_and_pose requires 12 input arguments.");
} }
if (nlhs != 2) { // 'nlhs >= 1' means no output argument apparently? if (nlhs != 2) {
mexErrMsgIdAndTxt("eos:example:nargout", "fit_shape_and_pose returns two output arguments."); mexErrMsgIdAndTxt("eos:fitting:nargout", "fit_shape_and_pose returns two output arguments.");
} }
InputArguments input(nrhs, prhs, 12); InputArguments input(nrhs, prhs, 12);
auto morphablemodel_file = input.get<string>(0); auto morphablemodel_file = input.get<string>(0);
auto blendshapes_file = input.get<string>(1); auto blendshapes_file = input.get<string>(1);
auto landmarks = input.get<Eigen::MatrixXd>(2); auto landmarks_in = input.get<Eigen::MatrixXd>(2);
// auto mm = input.get<string>(0); auto mapper_file = input.get<string>(3);
// double vin1 = input.get<double>(0); auto image_width = input.get<int>(4);
// Matlab stores col-wise in memory - hence the entry of the second row comes first auto image_height = input.get<int>(5);
//auto vin2 = input.get<vector<double>>(1); auto edgetopo_file = input.get<string>(6);
/* auto test = input[1]; auto contour_lms_file = input.get<string>(7);
MxArray mxa(test); auto model_cnt_file = input.get<string>(8);
auto ndim = mxa.dimensionSize(); auto num_iterations = input.get<int>(9);
auto nrows = mxa.dimensions()[0]; auto num_shape_coeffs = input.get<int>(10);
auto ncols = mxa.dimensions()[1]; auto lambda = input.get<double>(11);
Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>> em(vin2.data(), 2, 3);
// ==> Yes, now I can put exactly this in the MxArray namespace!
std::stringstream ss;
ss << em;
std::string msg = ss.str();
*/
//auto x = MxArray::Numeric<double>(2, 2);
/* auto asdf = input.get<Eigen::MatrixXd>(1);
std::stringstream ss2;
ss2 << asdf;
std::string msg2 = ss2.str();*/
OutputArguments output(nlhs, plhs, 2); if (landmarks_in.rows() != 68) {
output.set(0, landmarks); mexErrMsgIdAndTxt("eos:fitting:argin", "Given landmarks must be a 68 x 2 vector with ibug landmarks, in the order from 1 to 68.");
output.set(1, landmarks); }
// Convert the landmarks (given as matrix in Matlab) to a LandmarkCollection:
core::LandmarkCollection<cv::Vec2f> landmarks;
for (int i = 0; i < 68; ++i)
{
landmarks.push_back(core::Landmark<cv::Vec2f>{ std::to_string(i + 1), cv::Vec2f(landmarks_in(i, 0), landmarks_in(i, 1)) });
}
// Load everything:
const auto morphable_model = morphablemodel::load_model(morphablemodel_file);
auto blendshapes = morphablemodel::load_blendshapes(blendshapes_file);
core::LandmarkMapper landmark_mapper(mapper_file);
auto edge_topology = morphablemodel::load_edge_topology(edgetopo_file);
auto contour_landmarks = fitting::ContourLandmarks::load(contour_lms_file);
auto model_contour = fitting::ModelContour::load(model_cnt_file);
boost::optional<int> num_shape_coefficients_to_fit = num_shape_coeffs == -1 ? boost::none : boost::optional<int>(num_shape_coeffs);
//double *vin1, *vin2; // Now do the actual fitting:
//vin1 = (double*)mxGetPr(prhs[0]); render::Mesh mesh;
//vin2 = (double*)mxGetPr(prhs[1]); fitting::RenderingParameters rendering_parameters;
//mexPrintf("%f, %f\n", vin1, vin2[0]); std::tie(mesh, rendering_parameters) = fitting::fit_shape_and_pose(morphable_model, blendshapes, landmarks, landmark_mapper, image_width, image_height, edge_topology, contour_landmarks, model_contour, num_iterations, num_shape_coefficients_to_fit, lambda);
// Return the mesh and the rendering_parameters:
OutputArguments output(nlhs, plhs, 2);
output.set(0, landmarks_in); // the Mesh
output.set(1, landmarks_in); // RenderingParameters
}; };
void func() void func()
......
...@@ -4,6 +4,16 @@ cmake_minimum_required(VERSION 3.7.0) ...@@ -4,6 +4,16 @@ cmake_minimum_required(VERSION 3.7.0)
# If Matlab_ROOT_DIR is set, the Matlab at that location is used. # If Matlab_ROOT_DIR is set, the Matlab at that location is used.
find_package(Matlab COMPONENTS MX_LIBRARY REQUIRED) find_package(Matlab COMPONENTS MX_LIBRARY REQUIRED)
# Dependencies of the modules:
find_package(OpenCV 2.4.3 REQUIRED core)
set_target_properties(${OpenCV_LIBS} PROPERTIES MAP_IMPORTED_CONFIG_RELWITHDEBINFO RELEASE)
if(MSVC)
# The standard find_package for boost on Win finds the dynamic libs, so for dynamic linking to boost we need to #define:
add_definitions(-DBOOST_ALL_NO_LIB) # Don't use the automatic library linking by boost with VS (#pragma ...). Instead, we specify everything here in cmake.
add_definitions(-DBOOST_ALL_DYN_LINK) # Link against the dynamic boost lib - needs to match with the version that find_package finds.
endif()
find_package(Boost 1.50.0 COMPONENTS system filesystem REQUIRED) # Why do we need boost for MorphableModel.hpp?
# See: https://cmake.org/cmake/help/v3.7/module/FindMatlab.html?highlight=findmatlab#command:matlab_add_mex # See: https://cmake.org/cmake/help/v3.7/module/FindMatlab.html?highlight=findmatlab#command:matlab_add_mex
matlab_add_mex( matlab_add_mex(
NAME eos_fitting NAME eos_fitting
...@@ -11,7 +21,7 @@ matlab_add_mex( ...@@ -11,7 +21,7 @@ matlab_add_mex(
SRC +eos/+fitting/private/fitting.cpp SRC +eos/+fitting/private/fitting.cpp
OUTPUT_NAME fitting #[OUTPUT_NAME output_name] OUTPUT_NAME fitting #[OUTPUT_NAME output_name]
# DOCUMENTATION +eos/+fitting/fit_shape_and_pose.m # doesn't work - wrong path probably. But it renames the file to fitting.m, so not what we want anyway. # DOCUMENTATION +eos/+fitting/fit_shape_and_pose.m # doesn't work - wrong path probably. But it renames the file to fitting.m, so not what we want anyway.
#[LINK_TO target1 target2 ...] # OpenCV etc? LINK_TO ${OpenCV_LIBS} ${Boost_LIBRARIES} #[LINK_TO target1 target2 ...]
#[...] #[...]
) )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment