|
26 | 26 | #include "eos/core/LandmarkMapper.hpp" |
27 | 27 | #include "eos/morphablemodel/MorphableModel.hpp" |
28 | 28 | #include "eos/morphablemodel/Blendshape.hpp" |
| 29 | +#include "eos/render/detail/render_detail.hpp" |
29 | 30 | #include "rcr/landmark.hpp" |
30 | 31 |
|
| 32 | +#include "glm/mat4x4.hpp" |
| 33 | +#include "glm/gtc/matrix_transform.hpp" |
| 34 | + |
31 | 35 | #include "opencv2/core/core.hpp" |
32 | 36 |
|
33 | 37 | #include <vector> |
@@ -110,64 +114,31 @@ cv::Rect make_bbox_square(cv::Rect bounding_box) |
110 | 114 | }; |
111 | 115 |
|
112 | 116 | /** |
113 | | - * @brief Takes LandmarkCollection of 2D landmarks and, using the landmark_mapper, find the |
114 | | - * corresponding 3D vertex indices and returns them, along with the coordinates of the 3D point. |
| 117 | + * Draws the given mesh as wireframe into the image. |
115 | 118 | * |
116 | | - * The function only returns points which the landmark mapper was able to convert, and skips all |
117 | | - * points for which there is no mapping. Thus, the number of returned points might be smaller than |
118 | | - * the number of input points. |
119 | | - * All three output vectors have the same size and contain the points in the same order. |
120 | | - * landmarks can be an eos::core::LandmarkCollection<cv::Vec2f> or an rcr::LandmarkCollection<cv::Vec2f>. |
| 119 | + * It does backface culling, i.e. draws only vertices in CCW order. |
121 | 120 | * |
122 | | - * @param[in] landmarks A LandmarkCollection of 2D landmarks. |
123 | | - * @param[in] landmark_mapper A mapper which maps the 2D landmark identifiers to 3D model vertex indices. |
124 | | - * @param[in] morphable_model Model to get the 3D point coordinates from. |
125 | | - * @return A tuple of <image_points, model_points, vertex_indices>. |
| 121 | + * @param[in] image An image to draw into. |
| 122 | + * @param[in] mesh The mesh to draw. |
| 123 | + * @param[in] modelview Model-view matrix to draw the mesh. |
| 124 | + * @param[in] projection Projection matrix to draw the mesh. |
| 125 | + * @param[in] viewport Viewport to draw the mesh. |
| 126 | + * @param[in] colour Colour of the mesh to be drawn. |
126 | 127 | */ |
127 | | -template<class T> |
128 | | -auto get_corresponding_pointset(const T& landmarks, const eos::core::LandmarkMapper& landmark_mapper, const eos::morphablemodel::MorphableModel& morphable_model) |
| 128 | +void draw_wireframe(cv::Mat image, const eos::render::Mesh& mesh, glm::mat4x4 modelview, glm::mat4x4 projection, glm::vec4 viewport, cv::Scalar colour = cv::Scalar(0, 255, 0, 255)) |
129 | 129 | { |
130 | | - using cv::Mat; |
131 | | - using std::vector; |
132 | | - using cv::Vec2f; |
133 | | - using cv::Vec4f; |
134 | | - |
135 | | - // These will be the final 2D and 3D points used for the fitting: |
136 | | - vector<Vec4f> model_points; // the points in the 3D shape model |
137 | | - vector<int> vertex_indices; // their vertex indices |
138 | | - vector<Vec2f> image_points; // the corresponding 2D landmark points |
139 | | - |
140 | | - // Sub-select all the landmarks which we have a mapping for (i.e. that are defined in the 3DMM): |
141 | | - for (int i = 0; i < landmarks.size(); ++i) { |
142 | | - auto converted_name = landmark_mapper.convert(landmarks[i].name); |
143 | | - if (!converted_name) { // no mapping defined for the current landmark |
144 | | - continue; |
| 130 | + for (const auto& triangle : mesh.tvi) |
| 131 | + { |
| 132 | + const auto p1 = glm::project({ mesh.vertices[triangle[0]][0], mesh.vertices[triangle[0]][1], mesh.vertices[triangle[0]][2] }, modelview, projection, viewport); |
| 133 | + const auto p2 = glm::project({ mesh.vertices[triangle[1]][0], mesh.vertices[triangle[1]][1], mesh.vertices[triangle[1]][2] }, modelview, projection, viewport); |
| 134 | + const auto p3 = glm::project({ mesh.vertices[triangle[2]][0], mesh.vertices[triangle[2]][1], mesh.vertices[triangle[2]][2] }, modelview, projection, viewport); |
| 135 | + if (eos::render::detail::are_vertices_ccw_in_screen_space(glm::vec2(p1), glm::vec2(p2), glm::vec2(p3))) |
| 136 | + { |
| 137 | + cv::line(image, cv::Point(p1.x, p1.y), cv::Point(p2.x, p2.y), colour); |
| 138 | + cv::line(image, cv::Point(p2.x, p2.y), cv::Point(p3.x, p3.y), colour); |
| 139 | + cv::line(image, cv::Point(p3.x, p3.y), cv::Point(p1.x, p1.y), colour); |
145 | 140 | } |
146 | | - int vertex_idx = std::stoi(converted_name.get()); |
147 | | - Vec4f vertex = morphable_model.get_shape_model().get_mean_at_point(vertex_idx); |
148 | | - model_points.emplace_back(vertex); |
149 | | - vertex_indices.emplace_back(vertex_idx); |
150 | | - image_points.emplace_back(landmarks[i].coordinates); |
151 | 141 | } |
152 | | - return std::make_tuple(image_points, model_points, vertex_indices); |
153 | | -}; |
154 | | - |
155 | | -/** |
156 | | - * @brief Concatenates two std::vector's of the same type and returns the concatenated |
157 | | - * vector. The elements of the second vector are appended after the first one. |
158 | | - * |
159 | | - * @param[in] vec_a First vector. |
160 | | - * @param[in] vec_b Second vector. |
161 | | - * @return The concatenated vector. |
162 | | - */ |
163 | | -template <class T> |
164 | | -auto concat(const std::vector<T>& vec_a, const std::vector<T>& vec_b) |
165 | | -{ |
166 | | - std::vector<T> concatenated_vec; |
167 | | - concatenated_vec.reserve(vec_a.size() + vec_b.size()); |
168 | | - concatenated_vec.insert(std::end(concatenated_vec), std::begin(vec_a), std::end(vec_a)); |
169 | | - concatenated_vec.insert(std::end(concatenated_vec), std::begin(vec_b), std::end(vec_b)); |
170 | | - return concatenated_vec; |
171 | 142 | }; |
172 | 143 |
|
173 | 144 | /** |
|
0 commit comments