Skip to content
Snippets Groups Projects
Commit 2b65ade7 authored by Sebastian Hahta's avatar Sebastian Hahta
Browse files

improved cursor

parent 098a19c6
No related branches found
No related tags found
No related merge requests found
Pipeline #29308 passed
...@@ -541,6 +541,20 @@ Eigen::Vector3f Camera::worldAt(int x, int y) { ...@@ -541,6 +541,20 @@ Eigen::Vector3f Camera::worldAt(int x, int y) {
return res; return res;
} }
Eigen::Vector3f fitPlane(const std::vector<float3>& pts) {
// PCA: calculate covariance matrix and its eigenvectors. Last eigenvector
// is the plane normal.
Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, 3, Eigen::RowMajor>>
mat((float*)(pts.data()), pts.size(), 3);
Eigen::MatrixXf centered = mat.rowwise() - mat.colwise().mean();
Eigen::MatrixXf cov = (centered.adjoint() * centered) / double(mat.rows() - 1);
Eigen::EigenSolver<Eigen::MatrixXf> es(cov);
Eigen::Vector3cf n(es.eigenvectors().col(2)); // already normalized
return n.real();
}
void Camera::setCursor(int x, int y) { void Camera::setCursor(int x, int y) {
auto ptr = std::atomic_load(&latest_); auto ptr = std::atomic_load(&latest_);
...@@ -554,35 +568,50 @@ void Camera::setCursor(int x, int y) { ...@@ -554,35 +568,50 @@ void Camera::setCursor(int x, int y) {
const auto &intrins = frame.getLeft(); const auto &intrins = frame.getLeft();
Eigen::Matrix4f posef = frame.getPose().cast<float>(); Eigen::Matrix4f posef = frame.getPose().cast<float>();
float3 CC = getWorldPoint(depth, x, y, intrins, posef); float3 CC = getWorldPoint(depth, x, y, intrins, posef);
cursor_pos_[0] = CC.x; cursor_pos_[0] = CC.x;
cursor_pos_[1] = CC.y; cursor_pos_[1] = CC.y;
cursor_pos_[2] = CC.z; cursor_pos_[2] = CC.z;
// Now find normal // some valid value as initial value
float3 PC = getWorldPoint(depth, x, y+4, intrins, posef); const float3 CP = getWorldPoint(depth, x+4, y, intrins, posef);
float3 CP = getWorldPoint(depth, x+4, y, intrins, posef);
float3 MC = getWorldPoint(depth, x, y-4, intrins, posef);
float3 CM = getWorldPoint(depth, x-4, y, intrins, posef);
const float3 n = cross(PC-MC, CP-CM);
const float l = length(n);
if (l > 0.0f) {
cursor_normal_[0] = n.x / -l;
cursor_normal_[1] = n.y / -l;
cursor_normal_[2] = n.z / -l;
}
cursor_target_[0] = CP.x; cursor_target_[0] = CP.x;
cursor_target_[1] = CP.y; cursor_target_[1] = CP.y;
cursor_target_[2] = CP.z; cursor_target_[2] = CP.z;
// get points around the selected point. candidates are selected in
// from square [-range, range] around (x, y) and points which are
// closer than max_distance are used. TODO: check bounds (depth map
// size)
const int range = 30;
const float max_distance = 0.50;
std::vector<float3> pts;
for (int xi = -range; xi <= range; xi++) {
for (int yi = -range; yi <= range; yi++) {
auto p = getWorldPoint(depth, x + xi, y + yi, intrins, posef);
if (p.x == 0 && p.y == 0 && p.z == 0.0) {
continue;
}
const float3 d = p - CC;
if (sqrtf(d.x*d.x + d.y*d.y + d.z*d.z) < max_distance) {
pts.push_back(p);
}
}}
if (pts.size() == 0) { return; }
cursor_normal_ = fitPlane(pts);
} }
} }
cursor_ = _cursor(); cursor_ = _cursor();
} }
void Camera::setCursorTarget(const Eigen::Vector3f &p) {
cursor_target_ =
p - cursor_normal_.dot(p - cursor_pos_) * cursor_normal_;
cursor_ = _cursor();
}
void Camera::setOriginToCursor() { void Camera::setOriginToCursor() {
using ftl::calibration::transform::inverse; using ftl::calibration::transform::inverse;
......
...@@ -75,7 +75,7 @@ public: ...@@ -75,7 +75,7 @@ public:
void setCursorPosition(const Eigen::Vector3f &pos) { cursor_pos_ = pos; cursor_ = _cursor(); } void setCursorPosition(const Eigen::Vector3f &pos) { cursor_pos_ = pos; cursor_ = _cursor(); }
void setCursorNormal(const Eigen::Vector3f &norm) { cursor_normal_ = norm; cursor_ = _cursor(); } void setCursorNormal(const Eigen::Vector3f &norm) { cursor_normal_ = norm; cursor_ = _cursor(); }
void setCursorTarget(const Eigen::Vector3f &targ) { cursor_target_ = targ; cursor_ = _cursor(); } void setCursorTarget(const Eigen::Vector3f &targ);
void setCursor(int x, int y); void setCursor(int x, int y);
const Eigen::Vector3f getCursorPosition() const { return cursor_pos_; } const Eigen::Vector3f getCursorPosition() const { return cursor_pos_; }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment