Use a solver for hub estimation
Uses ceres to estimate the rotation and distance
from the hub to the camera.
Ready for reviewing
Signed-off-by: Milind Upadhyay <milind.upadhyay@gmail.com>
Change-Id: Idd4fb3334146a0587c713887626cb0abe43cdd4e
diff --git a/y2022/vision/camera_reader.cc b/y2022/vision/camera_reader.cc
index 000d7f2..1d1f13e 100644
--- a/y2022/vision/camera_reader.cc
+++ b/y2022/vision/camera_reader.cc
@@ -13,7 +13,6 @@
#include "opencv2/imgproc.hpp"
#include "y2022/vision/blob_detector.h"
#include "y2022/vision/calibration_generated.h"
-#include "y2022/vision/target_estimator.h"
DEFINE_string(image_png, "", "A set of PNG images");
@@ -41,32 +40,38 @@
}
namespace {
+flatbuffers::Offset<flatbuffers::Vector<const Point *>> CvPointsToFbs(
+ const std::vector<cv::Point> &points,
+ aos::Sender<TargetEstimate>::Builder *builder) {
+ std::vector<Point> points_fbs;
+ for (auto p : points) {
+ points_fbs.push_back(Point{p.x, p.y});
+ }
+ return builder->fbb()->CreateVectorOfStructs(points_fbs);
+}
+
// Converts a vector of cv::Point to PointT for the flatbuffer
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Blob>>>
CvBlobsToFbs(const std::vector<std::vector<cv::Point>> &blobs,
- aos::Sender<TargetEstimate>::Builder &builder) {
+ aos::Sender<TargetEstimate>::Builder *builder) {
std::vector<flatbuffers::Offset<Blob>> blobs_fbs;
for (auto &blob : blobs) {
- std::vector<Point> points_fbs;
- for (auto p : blob) {
- points_fbs.push_back(Point{p.x, p.y});
- }
- auto points_offset = builder.fbb()->CreateVectorOfStructs(points_fbs);
- auto blob_builder = builder.MakeBuilder<Blob>();
+ const auto points_offset = CvPointsToFbs(blob, builder);
+ auto blob_builder = builder->MakeBuilder<Blob>();
blob_builder.add_points(points_offset);
blobs_fbs.emplace_back(blob_builder.Finish());
}
- return builder.fbb()->CreateVector(blobs_fbs.data(), blobs_fbs.size());
+ return builder->fbb()->CreateVector(blobs_fbs.data(), blobs_fbs.size());
}
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<BlobStatsFbs>>>
BlobStatsToFbs(const std::vector<BlobDetector::BlobStats> blob_stats,
- aos::Sender<TargetEstimate>::Builder &builder) {
+ aos::Sender<TargetEstimate>::Builder *builder) {
std::vector<flatbuffers::Offset<BlobStatsFbs>> stats_fbs;
for (auto &stats : blob_stats) {
// Make BlobStatsFbs builder then fill each field using the BlobStats
// struct, then you finish it and add it to stats_fbs.
- auto stats_builder = builder.MakeBuilder<BlobStatsFbs>();
+ auto stats_builder = builder->MakeBuilder<BlobStatsFbs>();
Point centroid_fbs = Point{stats.centroid.x, stats.centroid.y};
stats_builder.add_centroid(¢roid_fbs);
stats_builder.add_aspect_ratio(stats.aspect_ratio);
@@ -76,7 +81,7 @@
auto current_stats = stats_builder.Finish();
stats_fbs.emplace_back(current_stats);
}
- return builder.fbb()->CreateVector(stats_fbs.data(), stats_fbs.size());
+ return builder->fbb()->CreateVector(stats_fbs.data(), stats_fbs.size());
}
} // namespace
@@ -88,11 +93,13 @@
flatbuffers::Offset<BlobResultFbs> blob_result_offset;
{
const auto filtered_blobs_offset =
- CvBlobsToFbs(blob_result.filtered_blobs, builder);
+ CvBlobsToFbs(blob_result.filtered_blobs, &builder);
const auto unfiltered_blobs_offset =
- CvBlobsToFbs(blob_result.unfiltered_blobs, builder);
+ CvBlobsToFbs(blob_result.unfiltered_blobs, &builder);
const auto blob_stats_offset =
- BlobStatsToFbs(blob_result.blob_stats, builder);
+ BlobStatsToFbs(blob_result.blob_stats, &builder);
+ const auto filtered_centroids_offset =
+ CvPointsToFbs(blob_result.filtered_centroids, &builder);
const Point centroid_fbs =
Point{blob_result.centroid.x, blob_result.centroid.y};
@@ -100,17 +107,28 @@
blob_result_builder.add_filtered_blobs(filtered_blobs_offset);
blob_result_builder.add_unfiltered_blobs(unfiltered_blobs_offset);
blob_result_builder.add_blob_stats(blob_stats_offset);
+ blob_result_builder.add_filtered_centroids(filtered_centroids_offset);
blob_result_builder.add_centroid(¢roid_fbs);
blob_result_offset = blob_result_builder.Finish();
}
+ target_estimator_.Solve(blob_result.filtered_centroids, std::nullopt);
+
const auto camera_calibration_offset =
aos::RecursiveCopyFlatBuffer(camera_calibration_, builder.fbb());
+ const auto rotation =
+ Rotation{target_estimator_.roll(), target_estimator_.pitch(),
+ target_estimator_.yaw()};
+
auto target_estimate_builder = builder.MakeBuilder<TargetEstimate>();
- TargetEstimator::EstimateTargetLocation(
- blob_result.centroid, CameraIntrinsics(), CameraExtrinsics(),
- &target_estimate_builder);
+
+ target_estimate_builder.add_distance(target_estimator_.distance());
+ target_estimate_builder.add_angle_to_target(
+ target_estimator_.angle_to_target());
+ target_estimate_builder.add_angle_to_camera(
+ target_estimator_.angle_to_camera());
+ target_estimate_builder.add_rotation_camera_hub(&rotation);
target_estimate_builder.add_blob_result(blob_result_offset);
target_estimate_builder.add_camera_calibration(camera_calibration_offset);
target_estimate_builder.add_image_monotonic_timestamp_ns(