Commit 30ff5944 authored by Patrik Huber's avatar Patrik Huber

Added viewport flipping to linear SOP estimation

Adjusted RenderingParameters constructor accordingly.

This is useful to get correct angle estimates when, as in OpenCV, the viewport is upside-down.
It could maybe also be solved by negating the 2nd and 3rd row of the rotation matrix in RenderingParameters, but I couldn't get the projection right. This is probably nicer.
parent b47358f0
...@@ -106,16 +106,20 @@ struct RenderingParameters ...@@ -106,16 +106,20 @@ struct RenderingParameters
// This assumes estimate_sop was run on points with OpenCV viewport! I.e. y flipped. // This assumes estimate_sop was run on points with OpenCV viewport! I.e. y flipped.
RenderingParameters(ScaledOrthoProjectionParameters ortho_params, int image_width, int image_height) { RenderingParameters(ScaledOrthoProjectionParameters ortho_params, int image_width, int image_height) {
camera_type = CameraType::Orthographic; camera_type = CameraType::Orthographic;
rotation = ortho_params.R; rotation = ortho_params.R; // convert the rotation matrix to a quaternion
t_x = ortho_params.tx; t_x = ortho_params.tx;
t_y = ortho_params.ty; t_y = ortho_params.ty;
const auto l = 0.0; const auto l = 0.0;
const auto r = image_width / ortho_params.s; const auto r = image_width / ortho_params.s;
const auto b = image_height / ortho_params.s; const auto b = 0.0; // The b and t values are not tested for what happens if the SOP parameters
const auto t = 0.0; const auto t = image_height / ortho_params.s; // were estimated on a non-flipped viewport.
frustum = Frustum(l, r, b, t); frustum = Frustum(l, r, b, t);
}; };
glm::quat get_rotation() const {
return rotation;
};
glm::mat4x4 get_modelview() const { glm::mat4x4 get_modelview() const {
// rot from quat, add transl., return 4x4. // rot from quat, add transl., return 4x4.
glm::mat4x4 modelview = glm::mat4_cast(rotation); glm::mat4x4 modelview = glm::mat4_cast(rotation);
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "opencv2/core/core.hpp" #include "opencv2/core/core.hpp"
#include "boost/optional.hpp"
#include <vector> #include <vector>
#include <cassert> #include <cassert>
...@@ -61,16 +63,29 @@ struct ScaledOrthoProjectionParameters { ...@@ -61,16 +63,29 @@ struct ScaledOrthoProjectionParameters {
* *
* @param[in] image_points A list of 2D image points. * @param[in] image_points A list of 2D image points.
* @param[in] model_points Corresponding points of a 3D model. * @param[in] model_points Corresponding points of a 3D model.
* @param[in] is_viewport_upsidedown Flag to set whether the viewport of the image points is upside-down (e.g. as in OpenCV).
* @param[in] viewport_height Height of the viewport of the image points (needs to be given if is_viewport_upsidedown == true).
* @return Rotation, translation and scaling of the estimated scaled orthographic projection. * @return Rotation, translation and scaling of the estimated scaled orthographic projection.
*/ */
ScaledOrthoProjectionParameters estimate_orthographic_projection_linear(std::vector<cv::Vec2f> image_points, std::vector<cv::Vec4f> model_points) ScaledOrthoProjectionParameters estimate_orthographic_projection_linear(std::vector<cv::Vec2f> image_points, std::vector<cv::Vec4f> model_points, bool is_viewport_upsidedown, boost::optional<int> viewport_height = boost::none)
{ {
using cv::Mat; using cv::Mat;
assert(image_points.size() == model_points.size()); assert(image_points.size() == model_points.size());
assert(image_points.size() >= 4); // Number of correspondence points given needs to be equal to or larger than 4 assert(image_points.size() >= 4); // Number of correspondence points given needs to be equal to or larger than 4
const int num_correspondences = static_cast<int>(image_points.size()); const int num_correspondences = static_cast<int>(image_points.size());
auto npts = num_correspondences;
if (is_viewport_upsidedown)
{
if (viewport_height == boost::none)
{
throw std::runtime_error("Error: If is_viewport_upsidedown is set to true, viewport_height needs to be given.");
}
for (auto&& ip : image_points)
{
ip[1] = viewport_height.get() - ip[1];
}
}
Mat A = Mat::zeros(2 * num_correspondences, 8, CV_32FC1); Mat A = Mat::zeros(2 * num_correspondences, 8, CV_32FC1);
int row_index = 0; int row_index = 0;
......
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