blob: c18abc53e0499aa45a9e7f7761866dddb58b906e [file] [log] [blame]
Brian Silverman2ccf8c52016-03-15 00:22:26 -04001#ifndef Y2016_VISION_STEREO_GEOMETRY_H_
2#define Y2016_VISION_STEREO_GEOMETRY_H_
3
4#include <string>
5
John Park33858a32018-09-28 23:05:48 -07006#include "aos/logging/logging.h"
Parker Schuh2cd173d2017-01-28 00:12:01 -08007#include "aos/vision/math/vector.h"
Brian Silverman2ccf8c52016-03-15 00:22:26 -04008#include "y2016/vision/calibration.pb.h"
9
10namespace y2016 {
11namespace vision {
12
13// Returns the contents of the calibration file which are embedded into the
14// code.
15CalibrationFile EmbeddedCalibrationFile();
16
17// Returns the embedded Calibration for the given robot_name or LOG(FATAL)s.
18Calibration FindCalibrationForRobotOrDie(
19 const ::std::string &robot_name, const CalibrationFile &calibration_file);
20
21class StereoGeometry {
22 public:
23 StereoGeometry(const ::std::string &robot_name)
24 : calibration_(FindCalibrationForRobotOrDie(robot_name,
25 EmbeddedCalibrationFile())) {}
26
27 // Returns the forward world distance in meters corresponding to the given
28 // distance in pixels between the two cameras.
29 double PixelToWorldDistance(double pixel_distance) {
30 return (calibration_.center_center_dist() *
31 calibration_.camera_image_width() * calibration_.focal_length() /
32 (pixel_distance + calibration_.center_center_skew())) +
33 calibration_.measure_camera_offset();
34 }
35
36 // Converts locations on both cameras to the distance between the locations
37 // and both angles.
38 // Returns (via pointers) the distance to the target in meters, the horizontal
39 // angle to the target in radians, and the vertical angle to the target in
40 // radians.
41 // TODO(Brian): Figure out which way is positive on the angles.
42 void Process(const ::aos::vision::Vector<2> &center0,
43 const ::aos::vision::Vector<2> &center1, double *distance,
44 double *horizontal_angle, double *vertical_angle) {
45 *distance = PixelToWorldDistance(center1.x() - center0.x());
46 const double average_x = (center0.x() + center1.x()) / 2.0 -
47 calibration_.camera_image_width() / 2.0;
48 const double average_y = (center0.y() + center1.y()) / 2.0 -
49 calibration_.camera_image_height() / 2.0;
50
51 *horizontal_angle =
52 std::atan2(average_x, calibration_.camera_image_width() *
53 calibration_.focal_length());
54 *vertical_angle = std::atan2(average_y, calibration_.camera_image_width() *
55 calibration_.focal_length());
56 }
57
58 const Calibration &calibration() const { return calibration_; }
59
60 private:
61 Calibration calibration_;
62};
63
64} // namespace vision
65} // namespace y2016
66
67#endif // Y2016_VISION_STEREO_GEOMETRY_H_